linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes
@ 2012-03-06 15:11 Tero Kristo
  2012-03-06 15:11 ` [PATCHv5 1/6] ARM: OMAP3 PM: correct enable/disable of daisy io chain Tero Kristo
                   ` (7 more replies)
  0 siblings, 8 replies; 30+ messages in thread
From: Tero Kristo @ 2012-03-06 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Changes compared to previous version:

- patch2:
  * fixed the timeout for waiting for ST_IO_CHAIN == 1
  * added clear for ST_IO_CHAIN bit (as per spec + implementation in patch 1)
  * replaced the timeout at the end of function with a simple register
    readback (timing out on a register value that we are clearing does
    not make that much sense, the bit is cleared the very first time CPU
    manages to read it)
- patch5:
  * added spinlock for protecting io_chain_trigger operation

Tested on omap3 beagle + omap4 blaze. Also did measurements for the
cost of IO chain trigger operation with ARM performance counters:

- omap3 approx 7...8us
- omap4 approx 2...4us

-Tero

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

* [PATCHv5 1/6] ARM: OMAP3 PM: correct enable/disable of daisy io chain
  2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
@ 2012-03-06 15:11 ` Tero Kristo
  2012-03-10  3:48   ` Paul Walmsley
  2012-03-06 15:11 ` [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file Tero Kristo
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Tero Kristo @ 2012-03-06 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mohan V <mohanv@ti.com>

Currently the enabling and disabling of IO Daisy chain is not
according to the TRM. The below steps are followed to enable/
disable the IO chain according to the "Sec 3.5.7.2.2
I/O Wake-Up Mechanism" in OMAP3630 Public TRM[1].

Steps to enable IO chain:
[a] Set PM_WKEN_WKUP.EN_IO bit
[b] Set the PM_WKEN_WKUP.EN_IO_CHAIN bit
[c] Poll for PM_WKST_WKUP.ST_IO_CHAIN.
[d] When ST_IO_CHAIN bit set to 1, clear PM_WKEN_WKUP.EN_IO_CHAIN
[e] Clear ST_IO_CHAIN bit.

Steps to disable IO chain:
[a] Clear PM_WKEN_WKUP.EN_IO_CHAIN bit
[b] Clear PM_WKEN_WKUP.EN_IO bit
[c] Clear PM_WKST_WKUP.ST_IO bit by writing 1 to it.

Step [e] & [c] in each case can be skipped, as these are handled
by the PRCM interrupt handler later.

[1] http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vV.zip

Signed-off-by: Mohan V <mohanv@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Reviewed-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fc69875..b0821a8 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -94,16 +94,17 @@ static void omap3_enable_io_chain(void)
 	/* Do a readback to assure write has been done */
 	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
 
-	while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
+	while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
 		 OMAP3430_ST_IO_CHAIN_MASK)) {
 		timeout++;
 		if (timeout > 1000) {
 			pr_err("Wake up daisy chain activation failed.\n");
 			return;
 		}
-		omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
-					   WKUP_MOD, PM_WKEN);
 	}
+	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+			PM_WKEN);
+
 }
 
 static void omap3_disable_io_chain(void)
-- 
1.7.4.1

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

* [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
  2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
  2012-03-06 15:11 ` [PATCHv5 1/6] ARM: OMAP3 PM: correct enable/disable of daisy io chain Tero Kristo
@ 2012-03-06 15:11 ` Tero Kristo
  2012-03-06 15:57   ` Nishanth Menon
                     ` (2 more replies)
  2012-03-06 15:11 ` [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support Tero Kristo
                   ` (5 subsequent siblings)
  7 siblings, 3 replies; 30+ messages in thread
From: Tero Kristo @ 2012-03-06 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vishwanath BS <vishwanath.bs@ti.com>

Since IO Daisychain modifies only PRM registers, it makes sense to move
it to PRM File. Also changed the timeout value for IO chain enable to
100us and added a wait for status disable at the end.

Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c       |   30 +----------------------------
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   37 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.h |   14 +++++++++++++
 3 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b0821a8..e97ec3f 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -85,34 +85,6 @@ static inline void omap3_per_restore_context(void)
 	omap_gpio_restore_context();
 }
 
-static void omap3_enable_io_chain(void)
-{
-	int timeout = 0;
-
-	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-				   PM_WKEN);
-	/* Do a readback to assure write has been done */
-	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
-
-	while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
-		 OMAP3430_ST_IO_CHAIN_MASK)) {
-		timeout++;
-		if (timeout > 1000) {
-			pr_err("Wake up daisy chain activation failed.\n");
-			return;
-		}
-	}
-	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-			PM_WKEN);
-
-}
-
-static void omap3_disable_io_chain(void)
-{
-	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-				     PM_WKEN);
-}
-
 static void omap3_core_save_context(void)
 {
 	omap3_ctrl_save_padconf();
@@ -324,7 +296,7 @@ void omap_sram_idle(void)
 	     core_next_state < PWRDM_POWER_ON)) {
 		omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
 		if (omap3_has_io_chain_ctrl())
-			omap3_enable_io_chain();
+			omap3_trigger_io_chain();
 	}
 
 	pwrdm_pre_transition();
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 9ce7654..2f45b96 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -301,6 +301,43 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)
 				OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 }
 
+/*
+ * Maximum time(us) it takes to output the signal WUCLKOUT of the last pad of
+ * the I/O ring after asserting WUCLKIN high
+ */
+#define MAX_IOPAD_LATCH_TIME 100
+
+/* OMAP3 Daisychain enable sequence */
+void omap3_trigger_io_chain(void)
+{
+	int i = 0;
+
+	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+				   PM_WKEN);
+	/* Do a readback to assure write has been done */
+	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+
+	omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
+			  OMAP3430_ST_IO_CHAIN_MASK,
+			  MAX_IOPAD_LATCH_TIME, i);
+
+	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+				     PM_WKEN);
+
+	omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
+				     PM_WKST);
+
+	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
+}
+
+/* OMAP3 Daisychain disable sequence */
+void omap3_disable_io_chain(void)
+{
+	if (omap_rev() >= OMAP3430_REV_ES3_1)
+		omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK,
+					     WKUP_MOD, PM_WKEN);
+}
+
 static int __init omap3xxx_prcm_init(void)
 {
 	if (cpu_is_omap34xx())
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index 70ac2a1..15973aa 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -289,6 +289,18 @@ static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
 		"not suppose to be used on omap4\n");
 	return 0;
 }
+static inline void omap3_trigger_io_chain(void)
+{
+	WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+		"not suppose to be used on omap4\n");
+	return 0;
+}
+static inline void omap3_disable_io_chain(void)
+{
+	WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+		"not suppose to be used on omap4\n");
+	return 0;
+}
 #else
 /* Power/reset management domain register get/set */
 extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
@@ -302,6 +314,8 @@ extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
 extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
 extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
 extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
+extern void omap3_trigger_io_chain(void);
+extern void omap3_disable_io_chain(void);
 
 /* OMAP3-specific VP functions */
 u32 omap3_prm_vp_check_txdone(u8 vp_id);
-- 
1.7.4.1

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

* [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support
  2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
  2012-03-06 15:11 ` [PATCHv5 1/6] ARM: OMAP3 PM: correct enable/disable of daisy io chain Tero Kristo
  2012-03-06 15:11 ` [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file Tero Kristo
@ 2012-03-06 15:11 ` Tero Kristo
  2012-03-10  3:59   ` Paul Walmsley
  2012-03-06 15:11 ` [PATCHv5 4/6] ARM: OMAP3+: PRM: Enable IO wake up Tero Kristo
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Tero Kristo @ 2012-03-06 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rajendra Nayak <rnayak@ti.com>

IO daisychain is a mechanism that allows individual IO pads to generate
wakeup events on their own based on a switch of an input signal level.
This allows the hardware module behind the pad to be powered down, but
still have device level capability to detect IO events, and once this
happens the module can be powered back up to resume IO. See section
3.9.4 in OMAP4430 Public TRM for details.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/prm44xx.c |   41 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/prm44xx.h |    1 +
 2 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index a37bfd4..caa5e0f 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -231,6 +231,47 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask)
 				 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
 }
 
+/*
+ * Maximum time(us) it takes to output the signal WUCLKOUT of the last pad of
+ * the I/O ring after asserting WUCLKIN high
+ */
+#define MAX_IOPAD_LATCH_TIME 100
+
+/* OMAP4 IO Daisychain trigger sequence */
+void omap4_trigger_io_chain(void)
+{
+	int i = 0;
+
+	/* Enable GLOBAL_WUEN */
+	if (!(omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+		OMAP4_PRM_IO_PMCTRL_OFFSET) & OMAP4430_GLOBAL_WUEN_MASK))
+		omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
+			OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET);
+
+	/* Trigger WUCLKIN enable */
+	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
+			OMAP4430_WUCLK_CTRL_MASK, OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET);
+	omap_test_timeout(
+		(((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET) &
+			OMAP4430_WUCLK_STATUS_MASK) >>
+			OMAP4430_WUCLK_STATUS_SHIFT) == 1),
+		MAX_IOPAD_LATCH_TIME, i);
+
+	/* Trigger WUCLKIN disable */
+	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
+			OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
+	omap_test_timeout(
+		(((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET) &
+			OMAP4430_WUCLK_STATUS_MASK) >>
+			OMAP4430_WUCLK_STATUS_SHIFT) == 0),
+		MAX_IOPAD_LATCH_TIME, i);
+	return;
+}
+
 static int __init omap4xxx_prcm_init(void)
 {
 	if (cpu_is_omap44xx())
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 7978092..54a057e 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -762,6 +762,7 @@ void omap4_prm_vp_clear_txdone(u8 vp_id);
 extern u32 omap4_prm_vcvp_read(u8 offset);
 extern void omap4_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
+extern void omap4_trigger_io_chain(void);
 
 /* PRM interrupt-related functions */
 extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
-- 
1.7.4.1

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

* [PATCHv5 4/6] ARM: OMAP3+: PRM: Enable IO wake up
  2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
                   ` (2 preceding siblings ...)
  2012-03-06 15:11 ` [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support Tero Kristo
@ 2012-03-06 15:11 ` Tero Kristo
  2012-03-10  4:00   ` Paul Walmsley
  2012-03-06 15:11 ` [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux Tero Kristo
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 30+ messages in thread
From: Tero Kristo @ 2012-03-06 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

Enable IO Wake up for OMAP3/4 as part of PRM Init. Currently this has been
managed in cpuidle path which is not the right place. Subsequent patch
will remove IO Daisy chain handling in cpuidle path once daisy chain is
handled as part of hwmod mux. This patch also moves the OMAP4 IO wakeup
enable code from the trigger function to init time setup.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Reviewed-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   11 ++++++++++-
 arch/arm/mach-omap2/prm44xx.c      |   18 ++++++++++--------
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 2f45b96..f0179f6 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -338,10 +338,19 @@ void omap3_disable_io_chain(void)
 					     WKUP_MOD, PM_WKEN);
 }
 
+static void __init omap3_enable_io_wakeup(void)
+{
+	if (omap3_has_io_wakeup())
+		omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
+					   PM_WKEN);
+}
+
 static int __init omap3xxx_prcm_init(void)
 {
-	if (cpu_is_omap34xx())
+	if (cpu_is_omap34xx()) {
+		omap3_enable_io_wakeup();
 		return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
+	}
 	return 0;
 }
 subsys_initcall(omap3xxx_prcm_init);
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index caa5e0f..4ce6f08 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -242,13 +242,6 @@ void omap4_trigger_io_chain(void)
 {
 	int i = 0;
 
-	/* Enable GLOBAL_WUEN */
-	if (!(omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
-		OMAP4_PRM_IO_PMCTRL_OFFSET) & OMAP4430_GLOBAL_WUEN_MASK))
-		omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
-			OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_DEVICE_INST,
-			OMAP4_PRM_IO_PMCTRL_OFFSET);
-
 	/* Trigger WUCLKIN enable */
 	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
 			OMAP4430_WUCLK_CTRL_MASK, OMAP4430_PRM_DEVICE_INST,
@@ -272,10 +265,19 @@ void omap4_trigger_io_chain(void)
 	return;
 }
 
+static void __init omap4_enable_io_wakeup(void)
+{
+	omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
+			OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET);
+}
+
 static int __init omap4xxx_prcm_init(void)
 {
-	if (cpu_is_omap44xx())
+	if (cpu_is_omap44xx()) {
+		omap4_enable_io_wakeup();
 		return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+	}
 	return 0;
 }
 subsys_initcall(omap4xxx_prcm_init);
-- 
1.7.4.1

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

* [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
  2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
                   ` (3 preceding siblings ...)
  2012-03-06 15:11 ` [PATCHv5 4/6] ARM: OMAP3+: PRM: Enable IO wake up Tero Kristo
@ 2012-03-06 15:11 ` Tero Kristo
  2012-03-10  4:01   ` Paul Walmsley
  2012-06-22 11:45   ` Rajendra Nayak
  2012-03-06 15:11 ` [PATCHv5 6/6] ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle Tero Kristo
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 30+ messages in thread
From: Tero Kristo @ 2012-03-06 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vishwanath BS <vishwanath.bs@ti.com>

IO Daisychain feature has to be triggered whenever there is a change in
device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP).

Now devices can idle independent of the powerdomain, there can be a
window where device is idled and corresponding powerdomain can be
ON/INACTIVE state. In such situations, since both module wake up is
enabled at padlevel as well as io daisychain sequence is triggered,
there will be 2 PRCM interrupts (Module async wake up via swakeup and
IO Pad interrupt). But as PRCM Interrupt handler clears the Module
Padlevel WKST bit in the first interrupt, module specific interrupt
handler will not triggered for the second time

Also look at detailed explanation given by Rajendra at
http://www.spinics.net/lists/linux-serial/msg04480.html

Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |    9 +++++++--
 arch/arm/mach-omap2/pm.c         |   21 +++++++++++++++++++++
 arch/arm/mach-omap2/pm.h         |    1 +
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 5192cab..56adbfb 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -152,6 +152,7 @@
 #include "prm44xx.h"
 #include "prminst44xx.h"
 #include "mux.h"
+#include "pm.h"
 
 /* Maximum microseconds to wait for OMAP module to softreset */
 #define MAX_MODULE_SOFTRESET_WAIT	10000
@@ -1535,8 +1536,10 @@ static int _enable(struct omap_hwmod *oh)
 	/* Mux pins for device runtime if populated */
 	if (oh->mux && (!oh->mux->enabled ||
 			((oh->_state == _HWMOD_STATE_IDLE) &&
-			 oh->mux->pads_dynamic)))
+			 oh->mux->pads_dynamic))) {
 		omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
+		omap_trigger_io_chain();
+	}
 
 	_add_initiator_dep(oh, mpu_oh);
 
@@ -1622,8 +1625,10 @@ static int _idle(struct omap_hwmod *oh)
 		clkdm_hwmod_disable(oh->clkdm, oh);
 
 	/* Mux pins for device idle if populated */
-	if (oh->mux && oh->mux->pads_dynamic)
+	if (oh->mux && oh->mux->pads_dynamic) {
 		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+		omap_trigger_io_chain();
+	}
 
 	oh->_state = _HWMOD_STATE_IDLE;
 
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 1881fe9..b7ac0f4 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -25,8 +25,12 @@
 #include "clockdomain.h"
 #include "pm.h"
 #include "twl-common.h"
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
 
 static struct omap_device_pm_latency *pm_lats;
+static void (*io_chain_trigger_func) (void);
+static DEFINE_SPINLOCK(io_chain_lock);
 
 static int _init_omap_device(char *name)
 {
@@ -64,6 +68,17 @@ static void omap2_init_processor_devices(void)
 	}
 }
 
+void omap_trigger_io_chain(void)
+{
+	unsigned long flags;
+
+	if (io_chain_trigger_func) {
+		spin_lock_irqsave(&io_chain_lock, flags);
+		io_chain_trigger_func();
+		spin_unlock_irqrestore(&io_chain_lock, flags);
+	}
+}
+
 /* Types of sleep_switch used in omap_set_pwrdm_state */
 #define FORCEWAKEUP_SWITCH	0
 #define LOWPOWERSTATE_SWITCH	1
@@ -221,6 +236,12 @@ static int __init omap2_common_pm_init(void)
 		omap2_init_processor_devices();
 	omap_pm_if_init();
 
+	if (cpu_is_omap34xx() && omap3_has_io_chain_ctrl())
+		io_chain_trigger_func = omap3_trigger_io_chain;
+
+	if (cpu_is_omap44xx())
+		io_chain_trigger_func = omap4_trigger_io_chain;
+
 	return 0;
 }
 postcore_initcall(omap2_common_pm_init);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index b737b11..f9dac40 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -22,6 +22,7 @@ extern int omap3_can_sleep(void);
 extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 extern int omap3_idle_init(void);
 extern int omap4_idle_init(void);
+extern void omap_trigger_io_chain(void);
 
 #if defined(CONFIG_PM_OPP)
 extern int omap3_opp_init(void);
-- 
1.7.4.1

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

* [PATCHv5 6/6] ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle
  2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
                   ` (4 preceding siblings ...)
  2012-03-06 15:11 ` [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux Tero Kristo
@ 2012-03-06 15:11 ` Tero Kristo
  2012-03-10  4:02   ` Paul Walmsley
  2012-03-10  4:05 ` [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Paul Walmsley
  2012-03-10 21:29 ` Paul Walmsley
  7 siblings, 1 reply; 30+ messages in thread
From: Tero Kristo @ 2012-03-06 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vishwanath BS <vishwanath.bs@ti.com>

As IO Daisy chain sequence is triggered via hwmod mux, there is no need to
control it from cpuidle path for OMAP3.

Also as omap3_disable_io_chain is no longer being used, just remove the
function.

Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Reviewed-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c       |   17 -----------------
 arch/arm/mach-omap2/prm2xxx_3xxx.c |    8 --------
 arch/arm/mach-omap2/prm2xxx_3xxx.h |    7 -------
 3 files changed, 0 insertions(+), 32 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index e97ec3f..ed12bb4 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -291,13 +291,6 @@ void omap_sram_idle(void)
 	/* Enable IO-PAD and IO-CHAIN wakeups */
 	per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
 	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
-	if (omap3_has_io_wakeup() &&
-	    (per_next_state < PWRDM_POWER_ON ||
-	     core_next_state < PWRDM_POWER_ON)) {
-		omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
-		if (omap3_has_io_chain_ctrl())
-			omap3_trigger_io_chain();
-	}
 
 	pwrdm_pre_transition();
 
@@ -376,16 +369,6 @@ void omap_sram_idle(void)
 			omap3_per_restore_context();
 	}
 
-	/* Disable IO-PAD and IO-CHAIN wakeup */
-	if (omap3_has_io_wakeup() &&
-	    (per_next_state < PWRDM_POWER_ON ||
-	     core_next_state < PWRDM_POWER_ON)) {
-		omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
-					     PM_WKEN);
-		if (omap3_has_io_chain_ctrl())
-			omap3_disable_io_chain();
-	}
-
 	clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
 }
 
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index f0179f6..b8962fe 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -330,14 +330,6 @@ void omap3_trigger_io_chain(void)
 	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
 }
 
-/* OMAP3 Daisychain disable sequence */
-void omap3_disable_io_chain(void)
-{
-	if (omap_rev() >= OMAP3430_REV_ES3_1)
-		omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK,
-					     WKUP_MOD, PM_WKEN);
-}
-
 static void __init omap3_enable_io_wakeup(void)
 {
 	if (omap3_has_io_wakeup())
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index 15973aa..391b844 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -295,12 +295,6 @@ static inline void omap3_trigger_io_chain(void)
 		"not suppose to be used on omap4\n");
 	return 0;
 }
-static inline void omap3_disable_io_chain(void)
-{
-	WARN(1, "prm: omap2xxx/omap3xxx specific function and "
-		"not suppose to be used on omap4\n");
-	return 0;
-}
 #else
 /* Power/reset management domain register get/set */
 extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
@@ -315,7 +309,6 @@ extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
 extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
 extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
 extern void omap3_trigger_io_chain(void);
-extern void omap3_disable_io_chain(void);
 
 /* OMAP3-specific VP functions */
 u32 omap3_prm_vp_check_txdone(u8 vp_id);
-- 
1.7.4.1

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

* [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
  2012-03-06 15:11 ` [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file Tero Kristo
@ 2012-03-06 15:57   ` Nishanth Menon
  2012-03-06 16:05     ` Tero Kristo
  2012-03-10  0:40   ` Paul Walmsley
  2012-03-10  3:50   ` Paul Walmsley
  2 siblings, 1 reply; 30+ messages in thread
From: Nishanth Menon @ 2012-03-06 15:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:11-20120306, Tero Kristo wrote:
> From: Vishwanath BS <vishwanath.bs@ti.com>
> 
> Since IO Daisychain modifies only PRM registers, it makes sense to move
> it to PRM File. Also changed the timeout value for IO chain enable to
> 100us and added a wait for status disable at the end.
[...]
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> index 9ce7654..2f45b96 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> @@ -301,6 +301,43 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)
>  				OMAP3_PRM_IRQENABLE_MPU_OFFSET);
>  }
>  
> +/*
> + * Maximum time(us) it takes to output the signal WUCLKOUT of the last pad of
> + * the I/O ring after asserting WUCLKIN high
> + */
> +#define MAX_IOPAD_LATCH_TIME 100
> +
> +/* OMAP3 Daisychain enable sequence */
> +void omap3_trigger_io_chain(void)
> +{
> +	int i = 0;
> +
> +	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
> +				   PM_WKEN);
> +	/* Do a readback to assure write has been done */
> +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
> +
> +	omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
> +			  OMAP3430_ST_IO_CHAIN_MASK,
> +			  MAX_IOPAD_LATCH_TIME, i);
probably a nitpick, but would'nt you like to keep the OMAP3 and OMAP4
style consistent?
> +
> +	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
> +				     PM_WKEN);
> +
> +	omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
> +				     PM_WKST);
> +
> +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
in the previous iteration it had:
omap_test_timeout(((omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
OMAP3430_ST_IO_CHAIN_MASK) == 0),
MAX_IOPAD_LATCH_TIME,
i);
gone now?
-- 
Regards,
Nishanth Menon

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

* [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
  2012-03-06 15:57   ` Nishanth Menon
@ 2012-03-06 16:05     ` Tero Kristo
  0 siblings, 0 replies; 30+ messages in thread
From: Tero Kristo @ 2012-03-06 16:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2012-03-06 at 09:57 -0600, Nishanth Menon wrote:
> On 17:11-20120306, Tero Kristo wrote:
> > From: Vishwanath BS <vishwanath.bs@ti.com>
> > 
> > Since IO Daisychain modifies only PRM registers, it makes sense to move
> > it to PRM File. Also changed the timeout value for IO chain enable to
> > 100us and added a wait for status disable at the end.
> [...]
> > diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> > index 9ce7654..2f45b96 100644
> > --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
> > +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> > @@ -301,6 +301,43 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)
> >  				OMAP3_PRM_IRQENABLE_MPU_OFFSET);
> >  }
> >  
> > +/*
> > + * Maximum time(us) it takes to output the signal WUCLKOUT of the last pad of
> > + * the I/O ring after asserting WUCLKIN high
> > + */
> > +#define MAX_IOPAD_LATCH_TIME 100
> > +
> > +/* OMAP3 Daisychain enable sequence */
> > +void omap3_trigger_io_chain(void)
> > +{
> > +	int i = 0;
> > +
> > +	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
> > +				   PM_WKEN);
> > +	/* Do a readback to assure write has been done */
> > +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
> > +
> > +	omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
> > +			  OMAP3430_ST_IO_CHAIN_MASK,
> > +			  MAX_IOPAD_LATCH_TIME, i);
> probably a nitpick, but would'nt you like to keep the OMAP3 and OMAP4
> style consistent?
> > +
> > +	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
> > +				     PM_WKEN);
> > +
> > +	omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
> > +				     PM_WKST);
> > +
> > +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
> in the previous iteration it had:
> omap_test_timeout(((omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
> OMAP3430_ST_IO_CHAIN_MASK) == 0),
> MAX_IOPAD_LATCH_TIME,
> i);
> gone now?

Yea, according to TRM this is not what should be done on omap3,
apparently one of the comments I received was in error for one of the
previous versions. Also, the implementation in patch 1 is closer to what
is here now.

-Tero

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

* [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
  2012-03-06 15:11 ` [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file Tero Kristo
  2012-03-06 15:57   ` Nishanth Menon
@ 2012-03-10  0:40   ` Paul Walmsley
  2012-03-12  5:50     ` Rajendra Nayak
  2012-03-10  3:50   ` Paul Walmsley
  2 siblings, 1 reply; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10  0:40 UTC (permalink / raw)
  To: linux-arm-kernel

cc Rajendra

Hi Tero,

a few comments:

On Tue, 6 Mar 2012, Tero Kristo wrote:

...

> +/* OMAP3 Daisychain enable sequence */
> +void omap3_trigger_io_chain(void)
> +{
> +	int i = 0;
> +
> +	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
> +				   PM_WKEN);
> +	/* Do a readback to assure write has been done */
> +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);

Looks like this barrier shouldn't be needed?  The write is immediately 
followed by another read from the same IP block.

> +
> +	omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
> +			  OMAP3430_ST_IO_CHAIN_MASK,
> +			  MAX_IOPAD_LATCH_TIME, i);
> +
> +	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
> +				     PM_WKEN);
> +
> +	omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
> +				     PM_WKST);
> +
> +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
> +}

I see that you removed the second timeout test from this code, but not 
from the OMAP4 version.  Any reason why?  Seems like if the second timeout 
can be removed from one, then it can also be removed from the other?


- Paul

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

* [PATCHv5 1/6] ARM: OMAP3 PM: correct enable/disable of daisy io chain
  2012-03-06 15:11 ` [PATCHv5 1/6] ARM: OMAP3 PM: correct enable/disable of daisy io chain Tero Kristo
@ 2012-03-10  3:48   ` Paul Walmsley
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10  3:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Tue, 6 Mar 2012, Tero Kristo wrote:

> From: Mohan V <mohanv@ti.com>
> 
> Currently the enabling and disabling of IO Daisy chain is not
> according to the TRM. The below steps are followed to enable/
> disable the IO chain according to the "Sec 3.5.7.2.2
> I/O Wake-Up Mechanism" in OMAP3630 Public TRM[1].
> 
> Steps to enable IO chain:
> [a] Set PM_WKEN_WKUP.EN_IO bit
> [b] Set the PM_WKEN_WKUP.EN_IO_CHAIN bit
> [c] Poll for PM_WKST_WKUP.ST_IO_CHAIN.
> [d] When ST_IO_CHAIN bit set to 1, clear PM_WKEN_WKUP.EN_IO_CHAIN
> [e] Clear ST_IO_CHAIN bit.
> 
> Steps to disable IO chain:
> [a] Clear PM_WKEN_WKUP.EN_IO_CHAIN bit
> [b] Clear PM_WKEN_WKUP.EN_IO bit
> [c] Clear PM_WKST_WKUP.ST_IO bit by writing 1 to it.
> 
> Step [e] & [c] in each case can be skipped, as these are handled
> by the PRCM interrupt handler later.
> 
> [1] http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vV.zip
> 
> Signed-off-by: Mohan V <mohanv@ti.com>
> Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
> Reviewed-by: Rajendra Nayak <rnayak@ti.com>

I modified the commit message to better reflect the reality of what's in 
the TRM.  Updated version is below.


- Paul

From: Mohan V <mohanv@ti.com>
Date: Fri, 2 Mar 2012 17:17:50 +0200
Subject: [PATCH 1/6] ARM: OMAP3: PM: correct enable/disable of daisy io chain

Currently the enabling and disabling of IO Daisy chain is not
according to the TRM. The below steps are followed to enable/
disable the IO chain, based loosely on the "Sec 3.5.7.2.2
I/O Wake-Up Mechanism" section in OMAP3630 Public TRM[1].

Steps to enable IO chain:
[a] Set PM_WKEN_WKUP.EN_IO bit
[b] Set the PM_WKEN_WKUP.EN_IO_CHAIN bit
[c] Poll for PM_WKST_WKUP.ST_IO_CHAIN.
[d] When ST_IO_CHAIN bit set to 1, clear PM_WKEN_WKUP.EN_IO_CHAIN
[e] Clear ST_IO_CHAIN bit.

Steps to disable IO chain:
[a] Clear PM_WKEN_WKUP.EN_IO_CHAIN bit
[b] Clear PM_WKEN_WKUP.EN_IO bit
[c] Clear PM_WKST_WKUP.ST_IO bit by writing 1 to it.

Step [e] & [c] in each case can be skipped, as these are handled
by the PRCM interrupt handler later.

[1] http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vV.zip

Signed-off-by: Mohan V <mohanv@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
[paul at pwsan.com: modified commit message to clarify that these steps are
 based loosely on the TRM section, rather than documented exactly]
Reviewed-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/pm34xx.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fc69875..b0821a8 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -94,16 +94,17 @@ static void omap3_enable_io_chain(void)
 	/* Do a readback to assure write has been done */
 	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
 
-	while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
+	while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
 		 OMAP3430_ST_IO_CHAIN_MASK)) {
 		timeout++;
 		if (timeout > 1000) {
 			pr_err("Wake up daisy chain activation failed.\n");
 			return;
 		}
-		omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
-					   WKUP_MOD, PM_WKEN);
 	}
+	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+			PM_WKEN);
+
 }
 
 static void omap3_disable_io_chain(void)
-- 
1.7.9.1

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

* [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
  2012-03-06 15:11 ` [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file Tero Kristo
  2012-03-06 15:57   ` Nishanth Menon
  2012-03-10  0:40   ` Paul Walmsley
@ 2012-03-10  3:50   ` Paul Walmsley
  2 siblings, 0 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Tue, 6 Mar 2012, Tero Kristo wrote:

> From: Vishwanath BS <vishwanath.bs@ti.com>
> 
> Since IO Daisychain modifies only PRM registers, it makes sense to move
> it to PRM File. Also changed the timeout value for IO chain enable to
> 100us and added a wait for status disable at the end.
> 
> Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

This patch has been updated in a few different ways, described below.  
Please let me know if you're okay with it.


- Paul

From: Vishwanath BS <vishwanath.bs@ti.com>
Date: Fri, 2 Mar 2012 17:17:51 +0200
Subject: [PATCH 2/6] ARM: OMAP3: PM: Move IO Daisychain function to omap3 prm
 file

Since IO Daisychain modifies only PRM registers, it makes sense to move
it to PRM File. Also changed the timeout value for IO chain enable to
100us and added a wait for status disable at the end.

Thanks to Nishanth Menon <nm@ti.com> for contributing a fix to the
timeout code waiting for WUCLKOUT to go high.

Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Cc: Nishanth Menon <nm@ti.com>
[paul at pwsan.com: renamed omap3_trigger_io_chain() to better describe the
 end result and to match other PRM functions; removed
 omap3_disable_io_chain(); moved MAX_IOPAD_LATCH_TIME to prcm-common as it
 will also be used by the OMAP4 code; removed unnecessary barrier;
 added kerneldoc; added credit for fix from Nishanth]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/pm34xx.c       |   35 ++---------------------------------
 arch/arm/mach-omap2/prcm-common.h  |    8 ++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   31 +++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/prm2xxx_3xxx.h |    2 ++
 4 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b0821a8..378a0de 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -85,34 +85,6 @@ static inline void omap3_per_restore_context(void)
 	omap_gpio_restore_context();
 }
 
-static void omap3_enable_io_chain(void)
-{
-	int timeout = 0;
-
-	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-				   PM_WKEN);
-	/* Do a readback to assure write has been done */
-	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
-
-	while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
-		 OMAP3430_ST_IO_CHAIN_MASK)) {
-		timeout++;
-		if (timeout > 1000) {
-			pr_err("Wake up daisy chain activation failed.\n");
-			return;
-		}
-	}
-	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-			PM_WKEN);
-
-}
-
-static void omap3_disable_io_chain(void)
-{
-	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
-				     PM_WKEN);
-}
-
 static void omap3_core_save_context(void)
 {
 	omap3_ctrl_save_padconf();
@@ -324,7 +296,7 @@ void omap_sram_idle(void)
 	     core_next_state < PWRDM_POWER_ON)) {
 		omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
 		if (omap3_has_io_chain_ctrl())
-			omap3_enable_io_chain();
+			omap3_reconfigure_io_chain();
 	}
 
 	pwrdm_pre_transition();
@@ -407,12 +379,9 @@ void omap_sram_idle(void)
 	/* Disable IO-PAD and IO-CHAIN wakeup */
 	if (omap3_has_io_wakeup() &&
 	    (per_next_state < PWRDM_POWER_ON ||
-	     core_next_state < PWRDM_POWER_ON)) {
+	     core_next_state < PWRDM_POWER_ON))
 		omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
 					     PM_WKEN);
-		if (omap3_has_io_chain_ctrl())
-			omap3_disable_io_chain();
-	}
 
 	clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
 }
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 5aa5435..f057c15 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -406,6 +406,14 @@
  */
 #define MAX_MODULE_HARDRESET_WAIT		10000
 
+/*
+ * Maximum time(us) it takes to output the signal WUCLKOUT of the last
+ * pad of the I/O ring after asserting WUCLKIN high.  Tero measured
+ * the actual time at 7 to 8 microseconds on OMAP3 and 2 to 4
+ * microseconds on OMAP4, so this timeout may be too high.
+ */
+#define MAX_IOPAD_LATCH_TIME			100
+
 # ifndef __ASSEMBLER__
 extern void __iomem *prm_base;
 extern void __iomem *cm_base;
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 9ce7654..7d62bd6 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -301,6 +301,37 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)
 				OMAP3_PRM_IRQENABLE_MPU_OFFSET);
 }
 
+/**
+ * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
+ *
+ * Clear any previously-latched I/O wakeup events and ensure that the
+ * I/O wakeup gates are aligned with the current mux settings.  Works
+ * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
+ * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit.  No
+ * return value.
+ */
+void omap3xxx_prm_reconfigure_io_chain(void)
+{
+	int i = 0;
+
+	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+				   PM_WKEN);
+
+	omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
+			  OMAP3430_ST_IO_CHAIN_MASK,
+			  MAX_IOPAD_LATCH_TIME, i);
+	if (i == MAX_IOPAD_LATCH_TIME)
+		pr_warn("PRM: I/O chain clock line assertion timed out\n");
+
+	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+				     PM_WKEN);
+
+	omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
+				   PM_WKST);
+
+	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
+}
+
 static int __init omap3xxx_prcm_init(void)
 {
 	if (cpu_is_omap34xx())
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index 70ac2a1..1ba3d65 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -315,6 +315,8 @@ extern u32 omap3_prm_vcvp_read(u8 offset);
 extern void omap3_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
+extern void omap3xxx_prm_reconfigure_io_chain(void);
+
 /* PRM interrupt-related functions */
 extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
 extern void omap3xxx_prm_ocp_barrier(void);
-- 
1.7.9.1

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

* [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support
  2012-03-06 15:11 ` [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support Tero Kristo
@ 2012-03-10  3:59   ` Paul Walmsley
  2012-03-12  5:52     ` Rajendra Nayak
  0 siblings, 1 reply; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10  3:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Tue, 6 Mar 2012, Tero Kristo wrote:

> From: Rajendra Nayak <rnayak@ti.com>
> 
> IO daisychain is a mechanism that allows individual IO pads to generate
> wakeup events on their own based on a switch of an input signal level.
> This allows the hardware module behind the pad to be powered down, but
> still have device level capability to detect IO events, and once this
> happens the module can be powered back up to resume IO. See section
> 3.9.4 in OMAP4430 Public TRM for details.
> 
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

Here's an updated version of this patch.  Please let me know if you think 
we should remove the poll on the WUCLKOUT line to conform with the change 
that Tero made to the OMAP3 version.


- Paul

From: Rajendra Nayak <rnayak@ti.com>
Date: Fri, 2 Mar 2012 17:17:52 +0200
Subject: [PATCH 3/6] ARM: OMAP4: PRM: Add IO Daisychain support

IO daisychain is a mechanism that allows individual IO pads to generate
wakeup events on their own based on a switch of an input signal level.
This allows the hardware module behind the pad to be powered down, but
still have device level capability to detect IO events, and once this
happens the module can be powered back up to resume IO. See section
3.9.4 in OMAP4430 Public TRM for details.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
[paul at pwsan.com: removed MAX_IOPAD_LATCH_TIME declaration; renamed
 omap4_trigger_io_chain() to conform to other PRM function names;
 added kerneldoc]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/prm44xx.c |   48 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/prm44xx.h |    2 +
 2 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index a1d6154..5868a12 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -231,6 +231,54 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask)
 				 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
 }
 
+/**
+ * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
+ *
+ * Clear any previously-latched I/O wakeup events and ensure that the
+ * I/O wakeup gates are aligned with the current mux settings.  Works
+ * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
+ * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted.
+ * No return value. XXX Are the final two steps necessary?
+ */
+void omap44xx_prm_reconfigure_io_chain(void)
+{
+	int i = 0;
+
+	/* Enable GLOBAL_WUEN */
+	if (!(omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+		OMAP4_PRM_IO_PMCTRL_OFFSET) & OMAP4430_GLOBAL_WUEN_MASK))
+		omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
+			OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET);
+
+	/* Trigger WUCLKIN enable */
+	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
+			OMAP4430_WUCLK_CTRL_MASK, OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET);
+	omap_test_timeout(
+		(((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET) &
+			OMAP4430_WUCLK_STATUS_MASK) >>
+			OMAP4430_WUCLK_STATUS_SHIFT) == 1),
+		MAX_IOPAD_LATCH_TIME, i);
+	if (i == MAX_IOPAD_LATCH_TIME)
+		pr_warn("PRM: I/O chain clock line assertion timed out\n");
+
+	/* Trigger WUCLKIN disable */
+	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
+			OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
+	omap_test_timeout(
+		(((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET) &
+			OMAP4430_WUCLK_STATUS_MASK) >>
+			OMAP4430_WUCLK_STATUS_SHIFT) == 0),
+		MAX_IOPAD_LATCH_TIME, i);
+	if (i == MAX_IOPAD_LATCH_TIME)
+		pr_warn("PRM: I/O chain clock line deassertion timed out\n");
+
+	return;
+}
+
 static int __init omap4xxx_prcm_init(void)
 {
 	if (cpu_is_omap44xx())
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 7978092..ee72ae6 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -763,6 +763,8 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
 extern void omap4_prm_vcvp_write(u32 val, u8 offset);
 extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
 
+extern void omap44xx_prm_reconfigure_io_chain(void);
+
 /* PRM interrupt-related functions */
 extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
 extern void omap44xx_prm_ocp_barrier(void);
-- 
1.7.9.1

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

* [PATCHv5 4/6] ARM: OMAP3+: PRM: Enable IO wake up
  2012-03-06 15:11 ` [PATCHv5 4/6] ARM: OMAP3+: PRM: Enable IO wake up Tero Kristo
@ 2012-03-10  4:00   ` Paul Walmsley
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10  4:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 6 Mar 2012, Tero Kristo wrote:

> Enable IO Wake up for OMAP3/4 as part of PRM Init. Currently this has been
> managed in cpuidle path which is not the right place. Subsequent patch
> will remove IO Daisy chain handling in cpuidle path once daisy chain is
> handled as part of hwmod mux. This patch also moves the OMAP4 IO wakeup
> enable code from the trigger function to init time setup.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> Reviewed-by: Rajendra Nayak <rnayak@ti.com>

Here's an updated version of this patch.  Please let me know if you have 
any comments.

- Paul

From: Tero Kristo <t-kristo@ti.com>
Date: Fri, 2 Mar 2012 17:17:53 +0200
Subject: [PATCH 4/6] ARM: OMAP3+: PRM: Enable IO wake up

Enable IO Wake up for OMAP3/4 as part of PRM Init. Currently this has been
managed in cpuidle path which is not the right place. Subsequent patch
will remove IO Daisy chain handling in cpuidle path once daisy chain is
handled as part of hwmod mux. This patch also moves the OMAP4 IO wakeup
enable code from the trigger function to init time setup.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
[paul at pwsan.com: harmonize function names with other PRM functions; add
 kerneldoc]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/prm2xxx_3xxx.c |   20 +++++++++++++++++++-
 arch/arm/mach-omap2/prm44xx.c      |   26 ++++++++++++++++++--------
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 7d62bd6..1471a33 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -332,10 +332,28 @@ void omap3xxx_prm_reconfigure_io_chain(void)
 	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
 }
 
+/**
+ * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
+ *
+ * Activates the I/O wakeup event latches and allows events logged by
+ * those latches to signal a wakeup event to the PRCM.  For I/O
+ * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
+ * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
+ * No return value.
+ */
+static void __init omap3xxx_prm_enable_io_wakeup(void)
+{
+	if (omap3_has_io_wakeup())
+		omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
+					   PM_WKEN);
+}
+
 static int __init omap3xxx_prcm_init(void)
 {
-	if (cpu_is_omap34xx())
+	if (cpu_is_omap34xx()) {
+		omap3xxx_prm_enable_io_wakeup();
 		return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
+	}
 	return 0;
 }
 subsys_initcall(omap3xxx_prcm_init);
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 5868a12..af251c7 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -244,13 +244,6 @@ void omap44xx_prm_reconfigure_io_chain(void)
 {
 	int i = 0;
 
-	/* Enable GLOBAL_WUEN */
-	if (!(omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
-		OMAP4_PRM_IO_PMCTRL_OFFSET) & OMAP4430_GLOBAL_WUEN_MASK))
-		omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
-			OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_DEVICE_INST,
-			OMAP4_PRM_IO_PMCTRL_OFFSET);
-
 	/* Trigger WUCLKIN enable */
 	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
 			OMAP4430_WUCLK_CTRL_MASK, OMAP4430_PRM_DEVICE_INST,
@@ -279,10 +272,27 @@ void omap44xx_prm_reconfigure_io_chain(void)
 	return;
 }
 
+/**
+ * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
+ *
+ * Activates the I/O wakeup event latches and allows events logged by
+ * those latches to signal a wakeup event to the PRCM.  For I/O wakeups
+ * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
+ * omap44xx_prm_reconfigure_io_chain() must be called.  No return value.
+ */
+static void __init omap44xx_prm_enable_io_wakeup(void)
+{
+	omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
+			OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_DEVICE_INST,
+			OMAP4_PRM_IO_PMCTRL_OFFSET);
+}
+
 static int __init omap4xxx_prcm_init(void)
 {
-	if (cpu_is_omap44xx())
+	if (cpu_is_omap44xx()) {
+		omap44xx_prm_enable_io_wakeup();
 		return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+	}
 	return 0;
 }
 subsys_initcall(omap4xxx_prcm_init);
-- 
1.7.9.1

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

* [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
  2012-03-06 15:11 ` [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux Tero Kristo
@ 2012-03-10  4:01   ` Paul Walmsley
  2012-06-22 11:45   ` Rajendra Nayak
  1 sibling, 0 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10  4:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Tue, 6 Mar 2012, Tero Kristo wrote:

> From: Vishwanath BS <vishwanath.bs@ti.com>
> 
> IO Daisychain feature has to be triggered whenever there is a change in
> device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP).
> 
> Now devices can idle independent of the powerdomain, there can be a
> window where device is idled and corresponding powerdomain can be
> ON/INACTIVE state. In such situations, since both module wake up is
> enabled at padlevel as well as io daisychain sequence is triggered,
> there will be 2 PRCM interrupts (Module async wake up via swakeup and
> IO Pad interrupt). But as PRCM Interrupt handler clears the Module
> Padlevel WKST bit in the first interrupt, module specific interrupt
> handler will not triggered for the second time
> 
> Also look at detailed explanation given by Rajendra at
> http://www.spinics.net/lists/linux-serial/msg04480.html
> 
> Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>

Here's an updated version of this patch that removes the dependency on 
mach-omap2/pm.*.


- Paul

From: Vishwanath BS <vishwanath.bs@ti.com>
Date: Fri, 2 Mar 2012 17:17:54 +0200
Subject: [PATCH 5/6] ARM: OMAP3PLUS: hwmod: reconfigure IO Daisychain during
 hwmod mux

IO Daisychain feature has to be triggered whenever there is a change in
device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP).

Now devices can idle independent of the powerdomain, there can be a
window where device is idled and corresponding powerdomain can be
ON/INACTIVE state. In such situations, since both module wake up is
enabled at padlevel as well as io daisychain sequence is triggered,
there will be 2 PRCM interrupts (Module async wake up via swakeup and
IO Pad interrupt). But as PRCM Interrupt handler clears the Module
Padlevel WKST bit in the first interrupt, module specific interrupt
handler will not triggered for the second time

Also look at detailed explanation given by Rajendra at
http://www.spinics.net/lists/linux-serial/msg04480.html

Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
[paul at pwsan.com: remove dependency on pm.c & pm.h; add kerneldoc]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/omap_hwmod.c |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index eba6cd3..58a5920 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -152,6 +152,7 @@
 #include "prm44xx.h"
 #include "prminst44xx.h"
 #include "mux.h"
+#include "pm.h"
 
 /* Maximum microseconds to wait for OMAP module to softreset */
 #define MAX_MODULE_SOFTRESET_WAIT	10000
@@ -165,6 +166,8 @@ static LIST_HEAD(omap_hwmod_list);
 /* mpu_oh: used to add/remove MPU initiator from sleepdep list */
 static struct omap_hwmod *mpu_oh;
 
+/* io_chain_lock: used to serialize reconfigurations of the I/O chain */
+static DEFINE_SPINLOCK(io_chain_lock);
 
 /* Private functions */
 
@@ -1481,6 +1484,32 @@ static int _reset(struct omap_hwmod *oh)
 }
 
 /**
+ * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain
+ *
+ * Call the appropriate PRM function to clear any logged I/O chain
+ * wakeups and to reconfigure the chain.  This apparently needs to be
+ * done upon every mux change.  Since hwmods can be concurrently
+ * enabled and idled, hold a spinlock around the I/O chain
+ * reconfiguration sequence.  No return value.
+ *
+ * XXX When the PRM code is moved to drivers, this function can be removed,
+ * as the PRM infrastructure should abstract this.
+ */
+static void _reconfigure_io_chain(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&io_chain_lock, flags);
+
+	if (cpu_is_omap34xx() && omap3_has_io_chain_ctrl())
+		omap3xxx_prm_reconfigure_io_chain();
+	else if (cpu_is_omap44xx())
+		omap44xx_prm_reconfigure_io_chain();
+
+	spin_unlock_irqrestore(&io_chain_lock, flags);
+}
+
+/**
  * _enable - enable an omap_hwmod
  * @oh: struct omap_hwmod *
  *
@@ -1535,8 +1564,10 @@ static int _enable(struct omap_hwmod *oh)
 	/* Mux pins for device runtime if populated */
 	if (oh->mux && (!oh->mux->enabled ||
 			((oh->_state == _HWMOD_STATE_IDLE) &&
-			 oh->mux->pads_dynamic)))
+			 oh->mux->pads_dynamic))) {
 		omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
+		_reconfigure_io_chain();
+	}
 
 	_add_initiator_dep(oh, mpu_oh);
 
@@ -1622,8 +1653,10 @@ static int _idle(struct omap_hwmod *oh)
 		clkdm_hwmod_disable(oh->clkdm, oh);
 
 	/* Mux pins for device idle if populated */
-	if (oh->mux && oh->mux->pads_dynamic)
+	if (oh->mux && oh->mux->pads_dynamic) {
 		omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+		_reconfigure_io_chain();
+	}
 
 	oh->_state = _HWMOD_STATE_IDLE;
 
-- 
1.7.9.1

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

* [PATCHv5 6/6] ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle
  2012-03-06 15:11 ` [PATCHv5 6/6] ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle Tero Kristo
@ 2012-03-10  4:02   ` Paul Walmsley
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10  4:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 6 Mar 2012, Tero Kristo wrote:

> From: Vishwanath BS <vishwanath.bs@ti.com>
> 
> As IO Daisy chain sequence is triggered via hwmod mux, there is no need to
> control it from cpuidle path for OMAP3.
> 
> Also as omap3_disable_io_chain is no longer being used, just remove the
> function.
> 
> Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> Reviewed-by: Rajendra Nayak <rnayak@ti.com>

And here's a modified version of this one that takes into account the 
earlier changes.


- Paul

>From ad04159c4ec89eef4026fa2e2aeefc3795d98b89 Mon Sep 17 00:00:00 2001
From: Vishwanath BS <vishwanath.bs@ti.com>
Date: Fri, 2 Mar 2012 17:17:55 +0200
Subject: [PATCH 6/6] ARM: OMAP3: PM: Remove IO Daisychain control from
 cpuidle

As IO Daisy chain sequence is triggered via hwmod mux, there is no need to
control it from cpuidle path for OMAP3.

Also as omap3_disable_io_chain is no longer being used, just remove the
function.

Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Reviewed-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/pm34xx.c |   14 --------------
 1 files changed, 0 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 378a0de..ed12bb4 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -291,13 +291,6 @@ void omap_sram_idle(void)
 	/* Enable IO-PAD and IO-CHAIN wakeups */
 	per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
 	core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
-	if (omap3_has_io_wakeup() &&
-	    (per_next_state < PWRDM_POWER_ON ||
-	     core_next_state < PWRDM_POWER_ON)) {
-		omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
-		if (omap3_has_io_chain_ctrl())
-			omap3_reconfigure_io_chain();
-	}
 
 	pwrdm_pre_transition();
 
@@ -376,13 +369,6 @@ void omap_sram_idle(void)
 			omap3_per_restore_context();
 	}
 
-	/* Disable IO-PAD and IO-CHAIN wakeup */
-	if (omap3_has_io_wakeup() &&
-	    (per_next_state < PWRDM_POWER_ON ||
-	     core_next_state < PWRDM_POWER_ON))
-		omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
-					     PM_WKEN);
-
 	clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
 }
 
-- 
1.7.9.1

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

* [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes
  2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
                   ` (5 preceding siblings ...)
  2012-03-06 15:11 ` [PATCHv5 6/6] ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle Tero Kristo
@ 2012-03-10  4:05 ` Paul Walmsley
  2012-03-12  5:53   ` Rajendra Nayak
  2012-03-12 10:00   ` Tero Kristo
  2012-03-10 21:29 ` Paul Walmsley
  7 siblings, 2 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10  4:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Tue, 6 Mar 2012, Tero Kristo wrote:

> Changes compared to previous version:
> 
> - patch2:
>   * fixed the timeout for waiting for ST_IO_CHAIN == 1
>   * added clear for ST_IO_CHAIN bit (as per spec + implementation in patch 1)
>   * replaced the timeout at the end of function with a simple register
>     readback (timing out on a register value that we are clearing does
>     not make that much sense, the bit is cleared the very first time CPU
>     manages to read it)
> - patch5:
>   * added spinlock for protecting io_chain_trigger operation
> 
> Tested on omap3 beagle + omap4 blaze. Also did measurements for the
> cost of IO chain trigger operation with ARM performance counters:
> 
> - omap3 approx 7...8us
> - omap4 approx 2...4us

Thanks for the changes.  So as you probably already saw, a few changes 
have been made.  The updated series is in the branch 
'io_chain_devel_3.4' on git://git.pwsan.com/linux-2.6.

The main outstanding question is whether the OMAP4 WUCLKOUT poll should be 
removed to match the v5 changes to the OMAP3 function.  Please let me 
know.   Any other testing or comments are of course welcome.


- Paul

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

* [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes
  2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
                   ` (6 preceding siblings ...)
  2012-03-10  4:05 ` [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Paul Walmsley
@ 2012-03-10 21:29 ` Paul Walmsley
  2012-03-12  5:55   ` Rajendra Nayak
  7 siblings, 1 reply; 30+ messages in thread
From: Paul Walmsley @ 2012-03-10 21:29 UTC (permalink / raw)
  To: linux-arm-kernel


Hi

By the way, one other thing I forgot to mention.  It would be really great 
if kerneldoc comments can be created for any new functions added to hwmod, 
PRCM, clock, or omap_device code.  The intention is to help not only 
people unfamiliar with the code, but even ourselves in the future.  I've 
been adding these by hand on Tero's last few patch series, but at some 
point I'll probably stop accepting patches without kerneldoc.


thanks,

- Paul

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

* [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
  2012-03-10  0:40   ` Paul Walmsley
@ 2012-03-12  5:50     ` Rajendra Nayak
  2012-03-12  9:19       ` Tero Kristo
  0 siblings, 1 reply; 30+ messages in thread
From: Rajendra Nayak @ 2012-03-12  5:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 10 March 2012 06:10 AM, Paul Walmsley wrote:
> cc Rajendra
>
> Hi Tero,
>
> a few comments:
>
> On Tue, 6 Mar 2012, Tero Kristo wrote:
>
> ...
>
>> +/* OMAP3 Daisychain enable sequence */
>> +void omap3_trigger_io_chain(void)
>> +{
>> +	int i = 0;
>> +
>> +	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
>> +				   PM_WKEN);
>> +	/* Do a readback to assure write has been done */
>> +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
>
> Looks like this barrier shouldn't be needed?  The write is immediately
> followed by another read from the same IP block.
>
>> +
>> +	omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST)&
>> +			  OMAP3430_ST_IO_CHAIN_MASK,
>> +			  MAX_IOPAD_LATCH_TIME, i);
>> +
>> +	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
>> +				     PM_WKEN);
>> +
>> +	omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
>> +				     PM_WKST);
>> +
>> +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
>> +}
>
> I see that you removed the second timeout test from this code, but not
> from the OMAP4 version.  Any reason why?  Seems like if the second timeout
> can be removed from one, then it can also be removed from the other?

Actually FWIK, its nteeded in both OMAP3 and OMAP4. The OMAP3
documentation does no mention about it. but that is just bad
documentation.

>
>
> - Paul

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

* [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support
  2012-03-10  3:59   ` Paul Walmsley
@ 2012-03-12  5:52     ` Rajendra Nayak
  2012-03-12  6:10       ` Rajendra Nayak
  2012-03-12  6:51       ` Paul Walmsley
  0 siblings, 2 replies; 30+ messages in thread
From: Rajendra Nayak @ 2012-03-12  5:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 10 March 2012 09:29 AM, Paul Walmsley wrote:
> Hi
>
> On Tue, 6 Mar 2012, Tero Kristo wrote:
>
>> From: Rajendra Nayak<rnayak@ti.com>
>>
>> IO daisychain is a mechanism that allows individual IO pads to generate
>> wakeup events on their own based on a switch of an input signal level.
>> This allows the hardware module behind the pad to be powered down, but
>> still have device level capability to detect IO events, and once this
>> happens the module can be powered back up to resume IO. See section
>> 3.9.4 in OMAP4430 Public TRM for details.
>>
>> Signed-off-by: Rajendra Nayak<rnayak@ti.com>
>> Signed-off-by: Vishwanath BS<vishwanath.bs@ti.com>
>> Signed-off-by: Tero Kristo<t-kristo@ti.com>
>
> Here's an updated version of this patch.  Please let me know if you think
> we should remove the poll on the WUCLKOUT line to conform with the change
> that Tero made to the OMAP3 version.

Thanks Paul, for the updates patch. Just one comment below..

>
>
> - Paul
>
> From: Rajendra Nayak<rnayak@ti.com>
> Date: Fri, 2 Mar 2012 17:17:52 +0200
> Subject: [PATCH 3/6] ARM: OMAP4: PRM: Add IO Daisychain support
>
> IO daisychain is a mechanism that allows individual IO pads to generate
> wakeup events on their own based on a switch of an input signal level.
> This allows the hardware module behind the pad to be powered down, but
> still have device level capability to detect IO events, and once this
> happens the module can be powered back up to resume IO. See section
> 3.9.4 in OMAP4430 Public TRM for details.
>
> Signed-off-by: Rajendra Nayak<rnayak@ti.com>
> Signed-off-by: Vishwanath BS<vishwanath.bs@ti.com> is just bad
documentation.

> Signed-off-by: Tero Kristo<t-kristo@ti.com>
> [paul at pwsan.com: removed MAX_IOPAD_LATCH_TIME declaration; renamed

But the code below still seems to use it. Is it now defined in some
common header so the same value is used in omap3 and omap4?

regards,
Rajendra

>   omap4_trigger_io_chain() to conform to other PRM function names;
>   added kerneldoc]
> Signed-off-by: Paul Walmsley<paul@pwsan.com>
> ---
>   arch/arm/mach-omap2/prm44xx.c |   48 +++++++++++++++++++++++++++++++++++++++++
>   arch/arm/mach-omap2/prm44xx.h |    2 +
>   2 files changed, 50 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
> index a1d6154..5868a12 100644
> --- a/arch/arm/mach-omap2/prm44xx.c
> +++ b/arch/arm/mach-omap2/prm44xx.c
> @@ -231,6 +231,54 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask)
>   				 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
>   }
>
> +/**
> + * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
> + *
> + * Clear any previously-latched I/O wakeup events and ensure that the
> + * I/O wakeup gates are aligned with the current mux settings.  Works
> + * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
> + * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted.
> + * No return value. XXX Are the final two steps necessary?
> + */
> +void omap44xx_prm_reconfigure_io_chain(void)
> +{
> +	int i = 0;
> +
> +	/* Enable GLOBAL_WUEN */
> +	if (!(omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
> +		OMAP4_PRM_IO_PMCTRL_OFFSET)&  OMAP4430_GLOBAL_WUEN_MASK))
> +		omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
> +			OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_PRM_DEVICE_INST,
> +			OMAP4_PRM_IO_PMCTRL_OFFSET);
> +
> +	/* Trigger WUCLKIN enable */
> +	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
> +			OMAP4430_WUCLK_CTRL_MASK, OMAP4430_PRM_DEVICE_INST,
> +			OMAP4_PRM_IO_PMCTRL_OFFSET);
> +	omap_test_timeout(
> +		(((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
> +			OMAP4_PRM_IO_PMCTRL_OFFSET)&
> +			OMAP4430_WUCLK_STATUS_MASK)>>
> +			OMAP4430_WUCLK_STATUS_SHIFT) == 1),
> +		MAX_IOPAD_LATCH_TIME, i);
> +	if (i == MAX_IOPAD_LATCH_TIME)
> +		pr_warn("PRM: I/O chain clock line assertion timed out\n");
> +
> +	/* Trigger WUCLKIN disable */
> +	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
> +			OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET);
> +	omap_test_timeout(
> +		(((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
> +			OMAP4_PRM_IO_PMCTRL_OFFSET)&
> +			OMAP4430_WUCLK_STATUS_MASK)>>
> +			OMAP4430_WUCLK_STATUS_SHIFT) == 0),
> +		MAX_IOPAD_LATCH_TIME, i);
> +	if (i == MAX_IOPAD_LATCH_TIME)
> +		pr_warn("PRM: I/O chain clock line deassertion timed out\n");
> +
> +	return;
> +}
> +
>   static int __init omap4xxx_prcm_init(void)
>   {
>   	if (cpu_is_omap44xx())
> diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
> index 7978092..ee72ae6 100644
> --- a/arch/arm/mach-omap2/prm44xx.h
> +++ b/arch/arm/mach-omap2/prm44xx.h
> @@ -763,6 +763,8 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
>   extern void omap4_prm_vcvp_write(u32 val, u8 offset);
>   extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
>
> +extern void omap44xx_prm_reconfigure_io_chain(void);
> +
>   /* PRM interrupt-related functions */
>   extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
>   extern void omap44xx_prm_ocp_barrier(void);

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

* [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes
  2012-03-10  4:05 ` [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Paul Walmsley
@ 2012-03-12  5:53   ` Rajendra Nayak
  2012-03-12 10:00   ` Tero Kristo
  1 sibling, 0 replies; 30+ messages in thread
From: Rajendra Nayak @ 2012-03-12  5:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 10 March 2012 09:35 AM, Paul Walmsley wrote:
> The main outstanding question is whether the OMAP4 WUCLKOUT poll should be
> removed to match the v5 changes to the OMAP3 function.  Please let me
> know.   Any other testing or comments are of course welcome.

I think we should instead add it back in omap3 and keep the omap4 as is.

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

* [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes
  2012-03-10 21:29 ` Paul Walmsley
@ 2012-03-12  5:55   ` Rajendra Nayak
  0 siblings, 0 replies; 30+ messages in thread
From: Rajendra Nayak @ 2012-03-12  5:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 11 March 2012 02:59 AM, Paul Walmsley wrote:
>
> Hi

Hi Paul,

>
> By the way, one other thing I forgot to mention.  It would be really great
> if kerneldoc comments can be created for any new functions added to hwmod,
> PRCM, clock, or omap_device code.  The intention is to help not only
> people unfamiliar with the code, but even ourselves in the future.  I've
> been adding these by hand on Tero's last few patch series, but at some
> point I'll probably stop accepting patches without kerneldoc.

Thanks for updating the kerneldoc comments this time around. Will make
sure patches hence forth come with adequate documentation added.

thanks,
Rajendra
>
>
> thanks,
>
> - Paul

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

* [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support
  2012-03-12  5:52     ` Rajendra Nayak
@ 2012-03-12  6:10       ` Rajendra Nayak
  2012-03-12  6:51       ` Paul Walmsley
  1 sibling, 0 replies; 30+ messages in thread
From: Rajendra Nayak @ 2012-03-12  6:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 12 March 2012 11:22 AM, Rajendra Nayak wrote:
>>
>> From: Rajendra Nayak<rnayak@ti.com>
>> Date: Fri, 2 Mar 2012 17:17:52 +0200
>> Subject: [PATCH 3/6] ARM: OMAP4: PRM: Add IO Daisychain support
>>
>> IO daisychain is a mechanism that allows individual IO pads to generate
>> wakeup events on their own based on a switch of an input signal level.
>> This allows the hardware module behind the pad to be powered down, but
>> still have device level capability to detect IO events, and once this
>> happens the module can be powered back up to resume IO. See section
>> 3.9.4 in OMAP4430 Public TRM for details.
>>
>> Signed-off-by: Rajendra Nayak<rnayak@ti.com>
>> Signed-off-by: Vishwanath BS<vishwanath.bs@ti.com> is just bad
> documentation.
>
>> Signed-off-by: Tero Kristo<t-kristo@ti.com>
>> [paul at pwsan.com: removed MAX_IOPAD_LATCH_TIME declaration; renamed
>
> But the code below still seems to use it. Is it now defined in some
> common header so the same value is used in omap3 and omap4?

never mind, just saw the other updates from you. The patches look good
to me, except for the comment I add to add the second timeout back in
omap3.

Tero, was there a specific reason you got rid of it for omap3 in your
latest patch-set?

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

* [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support
  2012-03-12  5:52     ` Rajendra Nayak
  2012-03-12  6:10       ` Rajendra Nayak
@ 2012-03-12  6:51       ` Paul Walmsley
  1 sibling, 0 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-03-12  6:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 12 Mar 2012, Rajendra Nayak wrote:

> > Signed-off-by: Tero Kristo<t-kristo@ti.com>
> > [paul at pwsan.com: removed MAX_IOPAD_LATCH_TIME declaration; renamed
> 
> But the code below still seems to use it. Is it now defined in some
> common header so the same value is used in omap3 and omap4?

Yes, I put it into prcm-common.h in the previous patch that added it for 
OMAP3.  I'll update that comment to clarify.


- Paul

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

* [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
  2012-03-12  5:50     ` Rajendra Nayak
@ 2012-03-12  9:19       ` Tero Kristo
  2012-03-12 10:15         ` Rajendra Nayak
  0 siblings, 1 reply; 30+ messages in thread
From: Tero Kristo @ 2012-03-12  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2012-03-12 at 11:20 +0530, Rajendra Nayak wrote:
> On Saturday 10 March 2012 06:10 AM, Paul Walmsley wrote:
> > cc Rajendra
> >
> > Hi Tero,
> >
> > a few comments:
> >
> > On Tue, 6 Mar 2012, Tero Kristo wrote:
> >
> > ...
> >
> >> +/* OMAP3 Daisychain enable sequence */
> >> +void omap3_trigger_io_chain(void)
> >> +{
> >> +	int i = 0;
> >> +
> >> +	omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
> >> +				   PM_WKEN);
> >> +	/* Do a readback to assure write has been done */
> >> +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
> >
> > Looks like this barrier shouldn't be needed?  The write is immediately
> > followed by another read from the same IP block.

I think you are right here, this can be dropped.

> >
> >> +
> >> +	omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST)&
> >> +			  OMAP3430_ST_IO_CHAIN_MASK,
> >> +			  MAX_IOPAD_LATCH_TIME, i);
> >> +
> >> +	omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
> >> +				     PM_WKEN);
> >> +
> >> +	omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
> >> +				     PM_WKST);
> >> +
> >> +	omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
> >> +}
> >
> > I see that you removed the second timeout test from this code, but not
> > from the OMAP4 version.  Any reason why?  Seems like if the second timeout
> > can be removed from one, then it can also be removed from the other?
> 
> Actually FWIK, its nteeded in both OMAP3 and OMAP4. The OMAP3
> documentation does no mention about it. but that is just bad
> documentation.

Both documentation and actual functionality appears to be different for
OMAP3 / OMAP4. The status bit on OMAP3 is read / write, and writing 1 to
it clears it. On OMAP4, it is read only and both values 0 / 1 indicate
something has happened. On OMAP3 the bit must be cleared by writing 1 to
it, otherwise it remains high indefinitely and will break all the
subsequent trigger calls. Also, clearing EN_IO_CHAIN on OMAP3 does not
appear to trigger any activity that would change the status of
ST_IO_CHAIN, so there is nothing to poll at the end.

Here is a sample trace I just generated for the trigger on OMAP3:

[    7.707824] omap3_trigger_io_chain(1): PM_WKST=00000000
[    7.707855] omap3_trigger_io_chain(2): PM_WKST=00000000
[    7.707855] omap3_trigger_io_chain(3): PM_WKST=00010000
[    7.707885] omap3_trigger_io_chain(4): PM_WKST=00000000
[    7.707977] omap3_trigger_io_chain(5): PM_WKST=00000000

1 = enter trigger function
2 = just after enabling io chain
3 = just after first poll loop
4 = just after clear of io status and disabling of io chain
5 = after udelay(100) from last event (you can see the status bit never
raises)

So, you can see that there is no change in the status bit between 4...5,
so there is no point for polling anything there. I even tried changing
the clear of IO status and disabling of IO chain to see if it had any
impact on this result but no. The main point is that we must clear the
status bit at #4, and thus polling for it to change at #5 makes no
sense. We just need to force the register writes to PRCM by doing some
access to the IP block.


Looking at similar trace on omap4:

[    8.097503] omap4_trigger_io_chain(1): IO=00010020
[    8.097503] omap4_trigger_io_chain(2): IO=00010320
[    8.097534] omap4_trigger_io_chain(3): IO=00010320
[    8.097534] omap4_trigger_io_chain(4): IO=00010020
[    8.097534] omap4_trigger_io_chain(5): IO=00010020

1 = enter function
2 = just after enabling WUCLK_CTRL
3 = just after poll
4 = just after disabling WUCLK_CTRL
5 = just after poll

Well, the status bit follows the state of the WUCLK_CTRL, but there is
no time to actually poll the registers it seems, their state has already
changed when the value from first read arrives back as the register
access itself is so slow. But... we are not manually clearing the status
bit, thus polling kind of makes sense (and it might make more sense if
some future version of PRCM would allow faster register access.)

I also did both of these tests by caching the register values to memory
(no immediate printks to avoid delays) but the results are still the
same.

-Tero

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

* [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes
  2012-03-10  4:05 ` [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Paul Walmsley
  2012-03-12  5:53   ` Rajendra Nayak
@ 2012-03-12 10:00   ` Tero Kristo
  2012-03-12 10:13     ` Paul Walmsley
  1 sibling, 1 reply; 30+ messages in thread
From: Tero Kristo @ 2012-03-12 10:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2012-03-09 at 21:05 -0700, Paul Walmsley wrote:
> Hi
> 
> On Tue, 6 Mar 2012, Tero Kristo wrote:
> 
> > Changes compared to previous version:
> > 
> > - patch2:
> >   * fixed the timeout for waiting for ST_IO_CHAIN == 1
> >   * added clear for ST_IO_CHAIN bit (as per spec + implementation in patch 1)
> >   * replaced the timeout at the end of function with a simple register
> >     readback (timing out on a register value that we are clearing does
> >     not make that much sense, the bit is cleared the very first time CPU
> >     manages to read it)
> > - patch5:
> >   * added spinlock for protecting io_chain_trigger operation
> > 
> > Tested on omap3 beagle + omap4 blaze. Also did measurements for the
> > cost of IO chain trigger operation with ARM performance counters:
> > 
> > - omap3 approx 7...8us
> > - omap4 approx 2...4us
> 
> Thanks for the changes.  So as you probably already saw, a few changes 
> have been made.  The updated series is in the branch 
> 'io_chain_devel_3.4' on git://git.pwsan.com/linux-2.6.
> 
> The main outstanding question is whether the OMAP4 WUCLKOUT poll should be 
> removed to match the v5 changes to the OMAP3 function.  Please let me 
> know.   Any other testing or comments are of course welcome.

Just tested your branch with omap3 beagle + omap4 blaze (with my omap4
cswr set on top), and it works on both.

For the WUCLK poll bit I added detailed comments on patch 2 thread, but
my current understanding is that the implementation now on omap3 / omap4
is what they should be due to IP differences (except maybe the small
optimization for omap3 part you commented about.)

-Tero

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

* [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes
  2012-03-12 10:00   ` Tero Kristo
@ 2012-03-12 10:13     ` Paul Walmsley
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-03-12 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero, Rajendra,

On Mon, 12 Mar 2012, Tero Kristo wrote:

> Just tested your branch with omap3 beagle + omap4 blaze (with my omap4
> cswr set on top), and it works on both.
> 
> For the WUCLK poll bit I added detailed comments on patch 2 thread, but
> my current understanding is that the implementation now on omap3 / omap4
> is what they should be due to IP differences (except maybe the small
> optimization for omap3 part you commented about.)

Thank you both for the detailed comments and explanation on this series, 
and the testing... sounds like this set is okay to go.


- Paul

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

* [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file
  2012-03-12  9:19       ` Tero Kristo
@ 2012-03-12 10:15         ` Rajendra Nayak
  0 siblings, 0 replies; 30+ messages in thread
From: Rajendra Nayak @ 2012-03-12 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tero,

On Monday 12 March 2012 02:49 PM, Tero Kristo wrote:
>>> I see that you removed the second timeout test from this code, but not
>>> >  >  from the OMAP4 version.  Any reason why?  Seems like if the second timeout
>>> >  >  can be removed from one, then it can also be removed from the other?
>> >
>> >  Actually FWIK, its nteeded in both OMAP3 and OMAP4. The OMAP3
>> >  documentation does no mention about it. but that is just bad
>> >  documentation.
> Both documentation and actual functionality appears to be different for
> OMAP3 / OMAP4. The status bit on OMAP3 is read / write, and writing 1 to
> it clears it. On OMAP4, it is read only and both values 0 / 1 indicate
> something has happened. On OMAP3 the bit must be cleared by writing 1 to
> it, otherwise it remains high indefinitely and will break all the
> subsequent trigger calls. Also, clearing EN_IO_CHAIN on OMAP3 does not
> appear to trigger any activity that would change the status of
> ST_IO_CHAIN, so there is nothing to poll at the end.
>
> Here is a sample trace I just generated for the trigger on OMAP3:
>
> [    7.707824] omap3_trigger_io_chain(1): PM_WKST=00000000
> [    7.707855] omap3_trigger_io_chain(2): PM_WKST=00000000
> [    7.707855] omap3_trigger_io_chain(3): PM_WKST=00010000
> [    7.707885] omap3_trigger_io_chain(4): PM_WKST=00000000
> [    7.707977] omap3_trigger_io_chain(5): PM_WKST=00000000
>
> 1 = enter trigger function
> 2 = just after enabling io chain
> 3 = just after first poll loop
> 4 = just after clear of io status and disabling of io chain
> 5 = after udelay(100) from last event (you can see the status bit never
> raises)

Ok, I guess then the omap3 and omap4 implementations are indeed
different and should be handled differently. Thanks for the explanation.

regards,
Rajendra

>
> So, you can see that there is no change in the status bit between 4...5,
> so there is no point for polling anything there. I even tried changing
> the clear of IO status and disabling of IO chain to see if it had any
> impact on this result but no. The main point is that we must clear the
> status bit at #4, and thus polling for it to change at #5 makes no
> sense. We just need to force the register writes to PRCM by doing some
> access to the IP block.
>
>
> Looking at similar trace on omap4:
>
> [    8.097503] omap4_trigger_io_chain(1): IO=00010020
> [    8.097503] omap4_trigger_io_chain(2): IO=00010320
> [    8.097534] omap4_trigger_io_chain(3): IO=00010320
> [    8.097534] omap4_trigger_io_chain(4): IO=00010020
> [    8.097534] omap4_trigger_io_chain(5): IO=00010020
>
> 1 = enter function
> 2 = just after enabling WUCLK_CTRL
> 3 = just after poll
> 4 = just after disabling WUCLK_CTRL
> 5 = just after poll
>
> Well, the status bit follows the state of the WUCLK_CTRL, but there is
> no time to actually poll the registers it seems, their state has already
> changed when the value from first read arrives back as the register
> access itself is so slow. But... we are not manually clearing the status
> bit, thus polling kind of makes sense (and it might make more sense if
> some future version of PRCM would allow faster register access.)
>
> I also did both of these tests by caching the register values to memory
> (no immediate printks to avoid delays) but the results are still the
> same.
>

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

* [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
  2012-03-06 15:11 ` [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux Tero Kristo
  2012-03-10  4:01   ` Paul Walmsley
@ 2012-06-22 11:45   ` Rajendra Nayak
  2012-06-22 18:39     ` Paul Walmsley
  1 sibling, 1 reply; 30+ messages in thread
From: Rajendra Nayak @ 2012-06-22 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tuesday 06 March 2012 08:41 PM, Tero Kristo wrote:
> From: Vishwanath BS<vishwanath.bs@ti.com>
>
> IO Daisychain feature has to be triggered whenever there is a change in
> device's mux configuration (See section 3.9.4 in OMAP4 Public TRM vP).
>
> Now devices can idle independent of the powerdomain, there can be a
> window where device is idled and corresponding powerdomain can be
> ON/INACTIVE state. In such situations, since both module wake up is
> enabled at padlevel as well as io daisychain sequence is triggered,
> there will be 2 PRCM interrupts (Module async wake up via swakeup and
> IO Pad interrupt). But as PRCM Interrupt handler clears the Module
> Padlevel WKST bit in the first interrupt, module specific interrupt
> handler will not triggered for the second time
>
> Also look at detailed explanation given by Rajendra at
> http://www.spinics.net/lists/linux-serial/msg04480.html
>
> Signed-off-by: Vishwanath BS<vishwanath.bs@ti.com>
> Signed-off-by: Tero Kristo<t-kristo@ti.com>
> ---
>   arch/arm/mach-omap2/omap_hwmod.c |    9 +++++++--
>   arch/arm/mach-omap2/pm.c         |   21 +++++++++++++++++++++
>   arch/arm/mach-omap2/pm.h         |    1 +
>   3 files changed, 29 insertions(+), 2 deletions(-)
>

>   /* Types of sleep_switch used in omap_set_pwrdm_state */
>   #define FORCEWAKEUP_SWITCH	0
>   #define LOWPOWERSTATE_SWITCH	1
> @@ -221,6 +236,12 @@ static int __init omap2_common_pm_init(void)
>   		omap2_init_processor_devices();
>   	omap_pm_if_init();
>
> +	if (cpu_is_omap34xx()&&  omap3_has_io_chain_ctrl())
> +		io_chain_trigger_func = omap3_trigger_io_chain;

While testing with one of Tero's OMAP4 OFF mode support branches (which
also include these patches) I found a OMAP4 standalone build fails
here..

CC      arch/arm/mach-omap2/omap_hwmod.o
arch/arm/mach-omap2/omap_hwmod.c: In function '_reconfigure_io_chain':
arch/arm/mach-omap2/omap_hwmod.c:1797: error: implicit declaration of 
function 'omap3xxx_prm_reconfigure_io_chain'
make[1]: *** [arch/arm/mach-omap2/omap_hwmod.o] Error 1
make: *** [arch/arm/mach-omap2] Error 2

regards,
Rajendra

> +
> +	if (cpu_is_omap44xx())
> +		io_chain_trigger_func = omap4_trigger_io_chain;
> +
>   	return 0;
>   }
>   postcore_initcall(omap2_common_pm_init);
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index b737b11..f9dac40 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -22,6 +22,7 @@ extern int omap3_can_sleep(void);
>   extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
>   extern int omap3_idle_init(void);
>   extern int omap4_idle_init(void);
> +extern void omap_trigger_io_chain(void);
>
>   #if defined(CONFIG_PM_OPP)
>   extern int omap3_opp_init(void);

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

* [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux
  2012-06-22 11:45   ` Rajendra Nayak
@ 2012-06-22 18:39     ` Paul Walmsley
  0 siblings, 0 replies; 30+ messages in thread
From: Paul Walmsley @ 2012-06-22 18:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 22 Jun 2012, Rajendra Nayak wrote:

> While testing with one of Tero's OMAP4 OFF mode support branches (which
> also include these patches) I found a OMAP4 standalone build fails
> here..
> 
> CC      arch/arm/mach-omap2/omap_hwmod.o
> arch/arm/mach-omap2/omap_hwmod.c: In function '_reconfigure_io_chain':
> arch/arm/mach-omap2/omap_hwmod.c:1797: error: implicit declaration of function
> 'omap3xxx_prm_reconfigure_io_chain'
> make[1]: *** [arch/arm/mach-omap2/omap_hwmod.o] Error 1
> make: *** [arch/arm/mach-omap2] Error 2

This should be fixed by Kevin's "ARM: OMAP2+: PRM: fix compile for 
OMAP4-only build" patch, part of the following pull request:

http://marc.info/?l=linux-omap&m=134037965609802&w=2


- Paul

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

end of thread, other threads:[~2012-06-22 18:39 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-06 15:11 [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Tero Kristo
2012-03-06 15:11 ` [PATCHv5 1/6] ARM: OMAP3 PM: correct enable/disable of daisy io chain Tero Kristo
2012-03-10  3:48   ` Paul Walmsley
2012-03-06 15:11 ` [PATCHv5 2/6] ARM: OMAP3 PM: Move IO Daisychain function to omap3 prm file Tero Kristo
2012-03-06 15:57   ` Nishanth Menon
2012-03-06 16:05     ` Tero Kristo
2012-03-10  0:40   ` Paul Walmsley
2012-03-12  5:50     ` Rajendra Nayak
2012-03-12  9:19       ` Tero Kristo
2012-03-12 10:15         ` Rajendra Nayak
2012-03-10  3:50   ` Paul Walmsley
2012-03-06 15:11 ` [PATCHv5 3/6] ARM: OMAP4 PM: Add IO Daisychain support Tero Kristo
2012-03-10  3:59   ` Paul Walmsley
2012-03-12  5:52     ` Rajendra Nayak
2012-03-12  6:10       ` Rajendra Nayak
2012-03-12  6:51       ` Paul Walmsley
2012-03-06 15:11 ` [PATCHv5 4/6] ARM: OMAP3+: PRM: Enable IO wake up Tero Kristo
2012-03-10  4:00   ` Paul Walmsley
2012-03-06 15:11 ` [PATCHv5 5/6] ARM: OMAP3PLUS PM: Add IO Daisychain support via hwmod mux Tero Kristo
2012-03-10  4:01   ` Paul Walmsley
2012-06-22 11:45   ` Rajendra Nayak
2012-06-22 18:39     ` Paul Walmsley
2012-03-06 15:11 ` [PATCHv5 6/6] ARM: OMAP3 PM: Remove IO Daisychain control from cpuidle Tero Kristo
2012-03-10  4:02   ` Paul Walmsley
2012-03-10  4:05 ` [PATCHv5 0/6] ARM: OMAP3+: IO daisy chain support fixes Paul Walmsley
2012-03-12  5:53   ` Rajendra Nayak
2012-03-12 10:00   ` Tero Kristo
2012-03-12 10:13     ` Paul Walmsley
2012-03-10 21:29 ` Paul Walmsley
2012-03-12  5:55   ` Rajendra Nayak

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