All of lore.kernel.org
 help / color / mirror / Atom feed
* arm: omap3: am35x: Powerdomain, EMIF4, etc. fixups
@ 2012-04-11 19:05 ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul

The am35x family of SoCs has several differences from
standard OMAP3 SoCs that haven't been accounted for in
Linux ARM code.  These differences include:

- There is no IVA.
- The device doesn't not support RETENTION & OFF
  power states.
- The SDRC *module* has an EMIF4 submodule instead
  of an SDRC submodule.

This series of patches tries to account for those changes.
They do the following:

- Prevent the cpu_idle thread and cpu_idle driver from
  sleeping because there are no I/O wake-ups to wake
  things back up again.
- Add a new cpu feature that indicates whether the device
  supports RETENTION & OFF power states.  Add code to
  support devices that only have INACTIVE & ON states.
- Add a parallel set of clockdomain dependencies that
  don't include the IVA.
- Add a new cpu feature that indicates whether the device
  has an EMIF4 or SDRC submodule of the SDRC module (the
  SDRC term/acronym is overloaded).  Add a minimal amount
  of code to support the EMIF4 submodule.
- Some miscellaneous patches to fix issues found while
  developing & testing the changes outlined above.

With these patches, the am3517 EVM boots and suspend-to-RAM
functions.  Unfortunately, though, after all of this, I still
can't manage to get the CORE power domain to enter the INACTIVE
state (at least according to /sys/kernel/debug/pm_debug/count
with debugfs mounted under /sys/kernel/debug).

The EMIF4 support is fairly minimal because there is an
EMIF driver working its way to mainline.  If more changes
are necessary, they can be made once the final version of
that driver is in mainline.

Please note that the SDRC submodule mapping is used by the
EMIF4 code.  They are at the same physical addresses and are
the same size so it works okay.  The reason I left the
mapping alone is because when those mappings are made, its
too early to use cpu_is_xxx() or omap3_has_sdrc_emif4() and
I didn't want to bloat the kernel with something that's
not strictly necessary.  I already have the code for the
separate mappings, so adding it in is easy, if that's
preferred.  I tried to make the mapping reuse clear with the
commit log and by adding a comment in am35xx_init_early().

These patches are based on the latest mainline kernel as
of this writing, commit 258f742635360175564e9470eb060ff4d4b984e7,
(modpost: Fix modpost license checking of vmlinux.o).  That
kernel with these patches was tested on an am35x EVM, am37x EVM,
and a Beagleboard-xM.  Testing included suspend-to-RAM
(i.e., "echo mem > /sys/power/state") with a rootfs mounted from
mmc and nfs (except for the Beagleboard-xM).

Mark
--

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

* arm: omap3: am35x: Powerdomain, EMIF4, etc. fixups
@ 2012-04-11 19:05 ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

The am35x family of SoCs has several differences from
standard OMAP3 SoCs that haven't been accounted for in
Linux ARM code.  These differences include:

- There is no IVA.
- The device doesn't not support RETENTION & OFF
  power states.
- The SDRC *module* has an EMIF4 submodule instead
  of an SDRC submodule.

This series of patches tries to account for those changes.
They do the following:

- Prevent the cpu_idle thread and cpu_idle driver from
  sleeping because there are no I/O wake-ups to wake
  things back up again.
- Add a new cpu feature that indicates whether the device
  supports RETENTION & OFF power states.  Add code to
  support devices that only have INACTIVE & ON states.
- Add a parallel set of clockdomain dependencies that
  don't include the IVA.
- Add a new cpu feature that indicates whether the device
  has an EMIF4 or SDRC submodule of the SDRC module (the
  SDRC term/acronym is overloaded).  Add a minimal amount
  of code to support the EMIF4 submodule.
- Some miscellaneous patches to fix issues found while
  developing & testing the changes outlined above.

With these patches, the am3517 EVM boots and suspend-to-RAM
functions.  Unfortunately, though, after all of this, I still
can't manage to get the CORE power domain to enter the INACTIVE
state (at least according to /sys/kernel/debug/pm_debug/count
with debugfs mounted under /sys/kernel/debug).

The EMIF4 support is fairly minimal because there is an
EMIF driver working its way to mainline.  If more changes
are necessary, they can be made once the final version of
that driver is in mainline.

Please note that the SDRC submodule mapping is used by the
EMIF4 code.  They are at the same physical addresses and are
the same size so it works okay.  The reason I left the
mapping alone is because when those mappings are made, its
too early to use cpu_is_xxx() or omap3_has_sdrc_emif4() and
I didn't want to bloat the kernel with something that's
not strictly necessary.  I already have the code for the
separate mappings, so adding it in is easy, if that's
preferred.  I tried to make the mapping reuse clear with the
commit log and by adding a comment in am35xx_init_early().

These patches are based on the latest mainline kernel as
of this writing, commit 258f742635360175564e9470eb060ff4d4b984e7,
(modpost: Fix modpost license checking of vmlinux.o).  That
kernel with these patches was tested on an am35x EVM, am37x EVM,
and a Beagleboard-xM.  Testing included suspend-to-RAM
(i.e., "echo mem > /sys/power/state") with a rootfs mounted from
mmc and nfs (except for the Beagleboard-xM).

Mark
--

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

* [PATCH 01/12] arm: omap3: Only access IVA if one exists
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

prcm_setup_regs() blindly accesses IVA bits
in the PRM and calls omap3_iva_idle() which
does more IVA related register accesses.
Only do this if the IVA hardware actually
exists.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/pm34xx.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 703bd10..ec92676 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -583,10 +583,13 @@ static void __init prcm_setup_regs(void)
 			  OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
 
 	/* Don't attach IVA interrupts */
-	omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
-	omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
-	omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
-	omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
+	if (omap3_has_iva()) {
+		omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
+		omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
+		omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
+		omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD,
+					OMAP3430_PM_IVAGRPSEL);
+	}
 
 	/* Clear any pending 'reset' flags */
 	omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
@@ -600,7 +603,9 @@ static void __init prcm_setup_regs(void)
 	/* Clear any pending PRCM interrupts */
 	omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
-	omap3_iva_idle();
+	if (omap3_has_iva())
+		omap3_iva_idle();
+
 	omap3_d2d_idle();
 }
 
-- 
1.7.9.4


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

* [PATCH 01/12] arm: omap3: Only access IVA if one exists
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

prcm_setup_regs() blindly accesses IVA bits
in the PRM and calls omap3_iva_idle() which
does more IVA related register accesses.
Only do this if the IVA hardware actually
exists.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/pm34xx.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 703bd10..ec92676 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -583,10 +583,13 @@ static void __init prcm_setup_regs(void)
 			  OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
 
 	/* Don't attach IVA interrupts */
-	omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
-	omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
-	omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
-	omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
+	if (omap3_has_iva()) {
+		omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
+		omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
+		omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
+		omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD,
+					OMAP3430_PM_IVAGRPSEL);
+	}
 
 	/* Clear any pending 'reset' flags */
 	omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
@@ -600,7 +603,9 @@ static void __init prcm_setup_regs(void)
 	/* Clear any pending PRCM interrupts */
 	omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
-	omap3_iva_idle();
+	if (omap3_has_iva())
+		omap3_iva_idle();
+
 	omap3_d2d_idle();
 }
 
-- 
1.7.9.4

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

* [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

Currently in the OMAP3 code, cpu_idle() calls pm_idle(),
which is a function pointer set to omap3_pm_idle()).
omap3_pm_idle() calls omap_sram_idle() which eventually
causes a 'wfi' instruction to be executed effectively
putting the system to sleep.  It is assumed that an
I/O wake-up event will occur to wake the system up again.
This doesn't work on systems that don't support I/O wake-ups
(indicated by omap3_has_io_wakeup() returning false).

Leaving pm_idle() pointing to default_idle() won't work
either because the cpu_<processor>_do_idle() routine which
is eventually called may also execute a 'wfi' instruction
(e.g., cpu_v7_do_idle()).

To handle this, leave pm_idle() pointing to omap3_pm_idle()
but add a check in omap3_pm_idle() so it avoids calling
omap_sram_idle() when I/O wake-ups aren't supported.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/pm34xx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ec92676..b7bbcee 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -397,7 +397,7 @@ static void omap3_pm_idle(void)
 {
 	local_fiq_disable();
 
-	if (omap_irq_pending())
+	if (omap_irq_pending() || !omap3_has_io_wakeup())
 		goto out;
 
 	trace_power_start(POWER_CSTATE, 1, smp_processor_id());
-- 
1.7.9.4


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

* [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

Currently in the OMAP3 code, cpu_idle() calls pm_idle(),
which is a function pointer set to omap3_pm_idle()).
omap3_pm_idle() calls omap_sram_idle() which eventually
causes a 'wfi' instruction to be executed effectively
putting the system to sleep.  It is assumed that an
I/O wake-up event will occur to wake the system up again.
This doesn't work on systems that don't support I/O wake-ups
(indicated by omap3_has_io_wakeup() returning false).

Leaving pm_idle() pointing to default_idle() won't work
either because the cpu_<processor>_do_idle() routine which
is eventually called may also execute a 'wfi' instruction
(e.g., cpu_v7_do_idle()).

To handle this, leave pm_idle() pointing to omap3_pm_idle()
but add a check in omap3_pm_idle() so it avoids calling
omap_sram_idle() when I/O wake-ups aren't supported.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/pm34xx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ec92676..b7bbcee 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -397,7 +397,7 @@ static void omap3_pm_idle(void)
 {
 	local_fiq_disable();
 
-	if (omap_irq_pending())
+	if (omap_irq_pending() || !omap3_has_io_wakeup())
 		goto out;
 
 	trace_power_start(POWER_CSTATE, 1, smp_processor_id());
-- 
1.7.9.4

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
which calls omap_sram_idle().  omap_sram_idle() eventually
causes a 'wfi' instruction to be executed effectively putting
the system to sleep.  It is assumed that an I/O wake-up event
will occur to wake the system up again.  This doesn't work on
systems that don't support I/O wake-ups (indicated by
omap3_has_io_wakeup() returning false).

To handle this, follow the same path in omap3_enter_idle()
that would be followed if an interrupt were pending.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 5358664..12cf81d 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -100,7 +100,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
 	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
 	pwrdm_set_next_pwrst(core_pd, core_state);
 
-	if (omap_irq_pending() || need_resched())
+	if (omap_irq_pending() || need_resched() || !omap3_has_io_wakeup())
 		goto return_sleep_time;
 
 	/* Deny idle for C1 */
-- 
1.7.9.4


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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
which calls omap_sram_idle().  omap_sram_idle() eventually
causes a 'wfi' instruction to be executed effectively putting
the system to sleep.  It is assumed that an I/O wake-up event
will occur to wake the system up again.  This doesn't work on
systems that don't support I/O wake-ups (indicated by
omap3_has_io_wakeup() returning false).

To handle this, follow the same path in omap3_enter_idle()
that would be followed if an interrupt were pending.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 5358664..12cf81d 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -100,7 +100,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
 	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
 	pwrdm_set_next_pwrst(core_pd, core_state);
 
-	if (omap_irq_pending() || need_resched())
+	if (omap_irq_pending() || need_resched() || !omap3_has_io_wakeup())
 		goto return_sleep_time;
 
 	/* Deny idle for C1 */
-- 
1.7.9.4

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

* [PATCH 04/12] arm: omap3: am35x: Don't mark missing features as present
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

The Chip Identification register on the am35x family of SoCs
has bits 12, 7:5, and 3:2 marked as reserved and are read as
zeroes.  Unfortunately, on other omap SoCs, a 0 bit means a
feature is "Full Use" so the OMAP3_CHECK_FEATURE() macro
called by omap3_check_features() will incorrectly interpret
those zeroes to mean that a feature is present even though it
isn't.  To fix that, the feature bits that are incorrectly
set (namely, OMAP3_HAS_IVA and OMAP3_HAS_ISP) need to be
cleared after all of the calls to OMAP3_CHECK_FEATURE() in
omap3_check_features() are made.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/id.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 0e79b7b..9736049 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -248,6 +248,17 @@ void __init omap3xxx_check_features(void)
 	omap_features |= OMAP3_HAS_SDRC;
 
 	/*
+	 * am35x fixups:
+	 * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as
+	 *   reserved and therefore return 0 when read.  Unfortunately,
+	 *   OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
+	 *   mean that a feature is present even though it isn't so clear
+	 *   the incorrectly set feature bits.
+	 */
+	if (cpu_is_omap3505() || cpu_is_omap3517())
+		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);
+
+	/*
 	 * TODO: Get additional info (where applicable)
 	 *       e.g. Size of L2 cache.
 	 */
-- 
1.7.9.4


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

* [PATCH 04/12] arm: omap3: am35x: Don't mark missing features as present
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

The Chip Identification register on the am35x family of SoCs
has bits 12, 7:5, and 3:2 marked as reserved and are read as
zeroes.  Unfortunately, on other omap SoCs, a 0 bit means a
feature is "Full Use" so the OMAP3_CHECK_FEATURE() macro
called by omap3_check_features() will incorrectly interpret
those zeroes to mean that a feature is present even though it
isn't.  To fix that, the feature bits that are incorrectly
set (namely, OMAP3_HAS_IVA and OMAP3_HAS_ISP) need to be
cleared after all of the calls to OMAP3_CHECK_FEATURE() in
omap3_check_features() are made.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/id.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 0e79b7b..9736049 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -248,6 +248,17 @@ void __init omap3xxx_check_features(void)
 	omap_features |= OMAP3_HAS_SDRC;
 
 	/*
+	 * am35x fixups:
+	 * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as
+	 *   reserved and therefore return 0 when read.  Unfortunately,
+	 *   OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
+	 *   mean that a feature is present even though it isn't so clear
+	 *   the incorrectly set feature bits.
+	 */
+	if (cpu_is_omap3505() || cpu_is_omap3517())
+		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);
+
+	/*
 	 * TODO: Get additional info (where applicable)
 	 *       e.g. Size of L2 cache.
 	 */
-- 
1.7.9.4

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

* [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

Typical OMAP3 SoCs have four power domain states: ON,
INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
has only two states: ON and INACTIVE.  To distinguish which
set of states the current device has, add the 'OMAP3_HAS_PWROFF'
feature.  When that feature/bit is set, the device supports the
RETENTION and OFF states; otherwise, it doesn't.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/id.c              |    7 +++++--
 arch/arm/plat-omap/include/plat/cpu.h |    8 +++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 9736049..b6508e5 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -245,7 +245,7 @@ void __init omap3xxx_check_features(void)
 	    omap_rev() == OMAP3430_REV_ES3_1_2)
 		omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
 
-	omap_features |= OMAP3_HAS_SDRC;
+	omap_features |= OMAP3_HAS_SDRC | OMAP3_HAS_PWROFF;
 
 	/*
 	 * am35x fixups:
@@ -254,9 +254,12 @@ void __init omap3xxx_check_features(void)
 	 *   OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
 	 *   mean that a feature is present even though it isn't so clear
 	 *   the incorrectly set feature bits.
+	 * - Indicate that am35x SoCs don't support the PWRDM_POWER_RET
+	 *   and PWRDM_POWER_OFF states by clearing OMAP3_HAS_PWROFF.
 	 */
 	if (cpu_is_omap3505() || cpu_is_omap3517())
-		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);
+		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP |
+			OMAP3_HAS_PWROFF);
 
 	/*
 	 * TODO: Get additional info (where applicable)
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index dc6a86b..c3f1a42 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -477,9 +477,10 @@ extern u32 omap_features;
 #define OMAP3_HAS_IO_WAKEUP		BIT(6)
 #define OMAP3_HAS_SDRC			BIT(7)
 #define OMAP3_HAS_IO_CHAIN_CTRL		BIT(8)
-#define OMAP4_HAS_MPU_1GHZ		BIT(9)
-#define OMAP4_HAS_MPU_1_2GHZ		BIT(10)
-#define OMAP4_HAS_MPU_1_5GHZ		BIT(11)
+#define OMAP3_HAS_PWROFF		BIT(9)
+#define OMAP4_HAS_MPU_1GHZ		BIT(10)
+#define OMAP4_HAS_MPU_1_2GHZ		BIT(11)
+#define OMAP4_HAS_MPU_1_5GHZ		BIT(12)
 
 
 #define OMAP3_HAS_FEATURE(feat,flag)			\
@@ -497,6 +498,7 @@ OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
 OMAP3_HAS_FEATURE(sdrc, SDRC)
 OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
+OMAP3_HAS_FEATURE(pwroff, PWROFF)
 
 /*
  * Runtime detection of OMAP4 features
-- 
1.7.9.4


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

* [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

Typical OMAP3 SoCs have four power domain states: ON,
INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
has only two states: ON and INACTIVE.  To distinguish which
set of states the current device has, add the 'OMAP3_HAS_PWROFF'
feature.  When that feature/bit is set, the device supports the
RETENTION and OFF states; otherwise, it doesn't.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/id.c              |    7 +++++--
 arch/arm/plat-omap/include/plat/cpu.h |    8 +++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 9736049..b6508e5 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -245,7 +245,7 @@ void __init omap3xxx_check_features(void)
 	    omap_rev() == OMAP3430_REV_ES3_1_2)
 		omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
 
-	omap_features |= OMAP3_HAS_SDRC;
+	omap_features |= OMAP3_HAS_SDRC | OMAP3_HAS_PWROFF;
 
 	/*
 	 * am35x fixups:
@@ -254,9 +254,12 @@ void __init omap3xxx_check_features(void)
 	 *   OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
 	 *   mean that a feature is present even though it isn't so clear
 	 *   the incorrectly set feature bits.
+	 * - Indicate that am35x SoCs don't support the PWRDM_POWER_RET
+	 *   and PWRDM_POWER_OFF states by clearing OMAP3_HAS_PWROFF.
 	 */
 	if (cpu_is_omap3505() || cpu_is_omap3517())
-		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);
+		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP |
+			OMAP3_HAS_PWROFF);
 
 	/*
 	 * TODO: Get additional info (where applicable)
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index dc6a86b..c3f1a42 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -477,9 +477,10 @@ extern u32 omap_features;
 #define OMAP3_HAS_IO_WAKEUP		BIT(6)
 #define OMAP3_HAS_SDRC			BIT(7)
 #define OMAP3_HAS_IO_CHAIN_CTRL		BIT(8)
-#define OMAP4_HAS_MPU_1GHZ		BIT(9)
-#define OMAP4_HAS_MPU_1_2GHZ		BIT(10)
-#define OMAP4_HAS_MPU_1_5GHZ		BIT(11)
+#define OMAP3_HAS_PWROFF		BIT(9)
+#define OMAP4_HAS_MPU_1GHZ		BIT(10)
+#define OMAP4_HAS_MPU_1_2GHZ		BIT(11)
+#define OMAP4_HAS_MPU_1_5GHZ		BIT(12)
 
 
 #define OMAP3_HAS_FEATURE(feat,flag)			\
@@ -497,6 +498,7 @@ OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
 OMAP3_HAS_FEATURE(sdrc, SDRC)
 OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
+OMAP3_HAS_FEATURE(pwroff, PWROFF)
 
 /*
  * Runtime detection of OMAP4 features
-- 
1.7.9.4

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

* [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

The am35x family of SoCs only support PWRDM_POWER_ON
and PWRDM_POWER_INACTIVE power states. This causes
an issue in some areas of the OMAP3 power-related
code because of assumptions that PWRDM_POWER_RET
and/or PWRDM_POWER_OFF are always valid states.

To get am35x SoCs to work properly, add missing support
for PWRDM_POWER_INACTIVE and remove assumptions that
PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c |   29 +++++++++++++++++++++++--
 arch/arm/mach-omap2/pm-debug.c    |    8 +++++--
 arch/arm/mach-omap2/pm34xx.c      |   43 +++++++++++++++++++++++--------------
 3 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 12cf81d..187872a 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -175,12 +175,23 @@ static int next_valid_state(struct cpuidle_device *dev,
 	struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
 	struct cpuidle_state *curr = &drv->states[index];
 	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
-	u32 mpu_deepest_state = PWRDM_POWER_RET;
-	u32 core_deepest_state = PWRDM_POWER_RET;
+	u32 mpu_deepest_state;
+	u32 core_deepest_state;
 	int next_index = -1;
 
+	if (omap3_has_pwroff()) {
+		mpu_deepest_state = PWRDM_POWER_RET;
+		core_deepest_state = PWRDM_POWER_RET;
+	} else {
+		mpu_deepest_state = PWRDM_POWER_INACTIVE;
+		core_deepest_state = PWRDM_POWER_INACTIVE;
+	}
+
 	if (enable_off_mode) {
+		WARN_ON(!omap3_has_pwroff());
+
 		mpu_deepest_state = PWRDM_POWER_OFF;
+
 		/*
 		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
 		 * CORE OFF mode is not supported in a stable form, restrict
@@ -311,6 +322,9 @@ void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
 			cpuidle_board_params[i].exit_latency;
 		cpuidle_params_table[i].target_residency =
 			cpuidle_board_params[i].target_residency;
+
+		WARN_ON(!omap3_has_pwroff() && (i >= 2) &&
+				cpuidle_params_table[i].valid);
 	}
 	return;
 }
@@ -349,6 +363,16 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage(
 	return cx;
 }
 
+/* Only C1 & C2 C states valid when RET & OFF states aren't supported */
+static void omap3_cstate_valid_fixup(void)
+{
+	int idx;
+
+	if (!omap3_has_pwroff())
+		for (idx = 2; idx < OMAP3_NUM_STATES; idx++)
+			cpuidle_params_table[idx].valid = 0;
+}
+
 /**
  * omap3_idle_init - Init routine for OMAP3 idle
  *
@@ -366,6 +390,7 @@ int __init omap3_idle_init(void)
 	per_pd = pwrdm_lookup("per_pwrdm");
 	cam_pd = pwrdm_lookup("cam_pwrdm");
 
+	omap3_cstate_valid_fixup();
 
 	drv->safe_state_index = -1;
 	dev = &per_cpu(omap3_idle_dev, smp_processor_id());
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 814bcd9..339ed42 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -239,19 +239,23 @@ static int option_get(void *data, u64 *val)
 static int option_set(void *data, u64 val)
 {
 	u32 *option = data;
+	int ret = -EINVAL;
 
 	*option = val;
 
-	if (option == &enable_off_mode) {
+	if (omap3_has_pwroff() && (option == &enable_off_mode)) {
 		if (val)
 			omap_pm_enable_off_mode();
 		else
 			omap_pm_disable_off_mode();
+
 		if (cpu_is_omap34xx())
 			omap3_pm_off_mode_enable(val);
+
+		ret = 0;
 	}
 
-	return 0;
+	return ret;
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b7bbcee..00c4abe 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -279,6 +279,7 @@ void omap_sram_idle(void)
 	mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
 	switch (mpu_next_state) {
 	case PWRDM_POWER_ON:
+	case PWRDM_POWER_INACTIVE:
 	case PWRDM_POWER_RET:
 		/* No need to save context */
 		save_state = 0;
@@ -614,6 +615,8 @@ void omap3_pm_off_mode_enable(int enable)
 	struct power_state *pwrst;
 	u32 state;
 
+	WARN_ON(!omap3_has_pwroff());
+
 	if (enable)
 		state = PWRDM_POWER_OFF;
 	else
@@ -668,7 +671,12 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+
+	if (omap3_has_pwroff())
+		pwrst->next_state = PWRDM_POWER_RET;
+	else
+		pwrst->next_state = PWRDM_POWER_INACTIVE;
+
 	list_add(&pwrst->node, &pwrst_list);
 
 	if (pwrdm_has_hdwr_sar(pwrdm))
@@ -781,25 +789,28 @@ static int __init omap3_pm_init(void)
 		omap3630_ctrl_disable_rta();
 
 	clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
-	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
-		omap3_secure_ram_storage =
-			kmalloc(0x803F, GFP_KERNEL);
-		if (!omap3_secure_ram_storage)
-			pr_err("Memory allocation failed when "
-			       "allocating for secure sram context\n");
 
-		local_irq_disable();
-		local_fiq_disable();
+	if (omap3_has_pwroff()) {
+		if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+			omap3_secure_ram_storage =
+				kmalloc(0x803F, GFP_KERNEL);
+			if (!omap3_secure_ram_storage)
+				pr_err("Memory allocation failed when "
+				       "allocating for secure sram context\n");
 
-		omap_dma_global_context_save();
-		omap3_save_secure_ram_context();
-		omap_dma_global_context_restore();
+			local_irq_disable();
+			local_fiq_disable();
 
-		local_irq_enable();
-		local_fiq_enable();
-	}
+			omap_dma_global_context_save();
+			omap3_save_secure_ram_context();
+			omap_dma_global_context_restore();
+
+			local_irq_enable();
+			local_fiq_enable();
 
-	omap3_save_scratchpad_contents();
+			omap3_save_scratchpad_contents();
+		}
+	}
 	return ret;
 
 err3:
-- 
1.7.9.4


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

* [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

The am35x family of SoCs only support PWRDM_POWER_ON
and PWRDM_POWER_INACTIVE power states. This causes
an issue in some areas of the OMAP3 power-related
code because of assumptions that PWRDM_POWER_RET
and/or PWRDM_POWER_OFF are always valid states.

To get am35x SoCs to work properly, add missing support
for PWRDM_POWER_INACTIVE and remove assumptions that
PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c |   29 +++++++++++++++++++++++--
 arch/arm/mach-omap2/pm-debug.c    |    8 +++++--
 arch/arm/mach-omap2/pm34xx.c      |   43 +++++++++++++++++++++++--------------
 3 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 12cf81d..187872a 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -175,12 +175,23 @@ static int next_valid_state(struct cpuidle_device *dev,
 	struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
 	struct cpuidle_state *curr = &drv->states[index];
 	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
-	u32 mpu_deepest_state = PWRDM_POWER_RET;
-	u32 core_deepest_state = PWRDM_POWER_RET;
+	u32 mpu_deepest_state;
+	u32 core_deepest_state;
 	int next_index = -1;
 
+	if (omap3_has_pwroff()) {
+		mpu_deepest_state = PWRDM_POWER_RET;
+		core_deepest_state = PWRDM_POWER_RET;
+	} else {
+		mpu_deepest_state = PWRDM_POWER_INACTIVE;
+		core_deepest_state = PWRDM_POWER_INACTIVE;
+	}
+
 	if (enable_off_mode) {
+		WARN_ON(!omap3_has_pwroff());
+
 		mpu_deepest_state = PWRDM_POWER_OFF;
+
 		/*
 		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
 		 * CORE OFF mode is not supported in a stable form, restrict
@@ -311,6 +322,9 @@ void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
 			cpuidle_board_params[i].exit_latency;
 		cpuidle_params_table[i].target_residency =
 			cpuidle_board_params[i].target_residency;
+
+		WARN_ON(!omap3_has_pwroff() && (i >= 2) &&
+				cpuidle_params_table[i].valid);
 	}
 	return;
 }
@@ -349,6 +363,16 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage(
 	return cx;
 }
 
+/* Only C1 & C2 C states valid when RET & OFF states aren't supported */
+static void omap3_cstate_valid_fixup(void)
+{
+	int idx;
+
+	if (!omap3_has_pwroff())
+		for (idx = 2; idx < OMAP3_NUM_STATES; idx++)
+			cpuidle_params_table[idx].valid = 0;
+}
+
 /**
  * omap3_idle_init - Init routine for OMAP3 idle
  *
@@ -366,6 +390,7 @@ int __init omap3_idle_init(void)
 	per_pd = pwrdm_lookup("per_pwrdm");
 	cam_pd = pwrdm_lookup("cam_pwrdm");
 
+	omap3_cstate_valid_fixup();
 
 	drv->safe_state_index = -1;
 	dev = &per_cpu(omap3_idle_dev, smp_processor_id());
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 814bcd9..339ed42 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -239,19 +239,23 @@ static int option_get(void *data, u64 *val)
 static int option_set(void *data, u64 val)
 {
 	u32 *option = data;
+	int ret = -EINVAL;
 
 	*option = val;
 
-	if (option == &enable_off_mode) {
+	if (omap3_has_pwroff() && (option == &enable_off_mode)) {
 		if (val)
 			omap_pm_enable_off_mode();
 		else
 			omap_pm_disable_off_mode();
+
 		if (cpu_is_omap34xx())
 			omap3_pm_off_mode_enable(val);
+
+		ret = 0;
 	}
 
-	return 0;
+	return ret;
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b7bbcee..00c4abe 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -279,6 +279,7 @@ void omap_sram_idle(void)
 	mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
 	switch (mpu_next_state) {
 	case PWRDM_POWER_ON:
+	case PWRDM_POWER_INACTIVE:
 	case PWRDM_POWER_RET:
 		/* No need to save context */
 		save_state = 0;
@@ -614,6 +615,8 @@ void omap3_pm_off_mode_enable(int enable)
 	struct power_state *pwrst;
 	u32 state;
 
+	WARN_ON(!omap3_has_pwroff());
+
 	if (enable)
 		state = PWRDM_POWER_OFF;
 	else
@@ -668,7 +671,12 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+
+	if (omap3_has_pwroff())
+		pwrst->next_state = PWRDM_POWER_RET;
+	else
+		pwrst->next_state = PWRDM_POWER_INACTIVE;
+
 	list_add(&pwrst->node, &pwrst_list);
 
 	if (pwrdm_has_hdwr_sar(pwrdm))
@@ -781,25 +789,28 @@ static int __init omap3_pm_init(void)
 		omap3630_ctrl_disable_rta();
 
 	clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
-	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
-		omap3_secure_ram_storage =
-			kmalloc(0x803F, GFP_KERNEL);
-		if (!omap3_secure_ram_storage)
-			pr_err("Memory allocation failed when "
-			       "allocating for secure sram context\n");
 
-		local_irq_disable();
-		local_fiq_disable();
+	if (omap3_has_pwroff()) {
+		if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+			omap3_secure_ram_storage =
+				kmalloc(0x803F, GFP_KERNEL);
+			if (!omap3_secure_ram_storage)
+				pr_err("Memory allocation failed when "
+				       "allocating for secure sram context\n");
 
-		omap_dma_global_context_save();
-		omap3_save_secure_ram_context();
-		omap_dma_global_context_restore();
+			local_irq_disable();
+			local_fiq_disable();
 
-		local_irq_enable();
-		local_fiq_enable();
-	}
+			omap_dma_global_context_save();
+			omap3_save_secure_ram_context();
+			omap_dma_global_context_restore();
+
+			local_irq_enable();
+			local_fiq_enable();
 
-	omap3_save_scratchpad_contents();
+			omap3_save_scratchpad_contents();
+		}
+	}
 	return ret;
 
 err3:
-- 
1.7.9.4

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

* [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

The am35x family of SoCs only support PWRSTS_ON
and PWRSTS_INACTIVE states so create a new set
of powerdomain structures that ensure that only
the ON and INACTIVE states are entered.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/powerdomain.h           |    1 +
 arch/arm/mach-omap2/powerdomains3xxx_data.c |  134 ++++++++++++++++++++++++---
 2 files changed, 123 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 0d72a8a..561cb27 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -43,6 +43,7 @@
 #define PWRSTS_OFF_ON		(PWRSTS_OFF | PWRSTS_ON)
 #define PWRSTS_OFF_RET		(PWRSTS_OFF | PWRSTS_RET)
 #define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
+#define PWRSTS_INACTIVE_ON	(PWRSTS_INACTIVE | PWRSTS_ON)
 #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON)
 
 
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index b7ea468..fae6dea 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -71,6 +71,22 @@ static struct powerdomain mpu_3xxx_pwrdm = {
 	.voltdm           = { .name = "mpu_iva" },
 };
 
+static struct powerdomain mpu_am35x_pwrdm = {
+	.name		  = "mpu_pwrdm",
+	.prcm_offs	  = MPU_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.flags		  = PWRDM_HAS_MPU_QUIRK,
+	.banks		  = 1,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE,
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_INACTIVE_ON,
+	},
+	.voltdm           = { .name = "mpu_iva" },
+};
+
 /*
  * The USBTLL Save-and-Restore mechanism is broken on
  * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
@@ -120,6 +136,23 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
 	.voltdm           = { .name = "core" },
 };
 
+static struct powerdomain core_am35x_pwrdm = {
+	.name		  = "core_pwrdm",
+	.prcm_offs	  = CORE_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.banks		  = 2,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE,	 /* MEM1RETSTATE */
+		[1] = PWRSTS_INACTIVE,	 /* MEM2RETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_INACTIVE_ON, /* MEM1ONSTATE */
+		[1] = PWRSTS_INACTIVE_ON, /* MEM2ONSTATE */
+	},
+	.voltdm           = { .name = "core" },
+};
+
 static struct powerdomain dss_pwrdm = {
 	.name		  = "dss_pwrdm",
 	.prcm_offs	  = OMAP3430_DSS_MOD,
@@ -135,6 +168,21 @@ static struct powerdomain dss_pwrdm = {
 	.voltdm           = { .name = "core" },
 };
 
+static struct powerdomain dss_am35x_pwrdm = {
+	.name		  = "dss_pwrdm",
+	.prcm_offs	  = OMAP3430_DSS_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.banks		  = 1,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
+	},
+	.voltdm           = { .name = "core" },
+};
+
 /*
  * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
  * possible SGX powerstate, the SGX device itself does not support
@@ -156,6 +204,21 @@ static struct powerdomain sgx_pwrdm = {
 	.voltdm           = { .name = "core" },
 };
 
+static struct powerdomain sgx_am35x_pwrdm = {
+	.name		  = "sgx_pwrdm",
+	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.banks		  = 1,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
+	},
+	.voltdm           = { .name = "core" },
+};
+
 static struct powerdomain cam_pwrdm = {
 	.name		  = "cam_pwrdm",
 	.prcm_offs	  = OMAP3430_CAM_MOD,
@@ -186,6 +249,21 @@ static struct powerdomain per_pwrdm = {
 	.voltdm           = { .name = "core" },
 };
 
+static struct powerdomain per_am35x_pwrdm = {
+	.name		  = "per_pwrdm",
+	.prcm_offs	  = OMAP3430_PER_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.banks		  = 1,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
+	},
+	.voltdm           = { .name = "core" },
+};
+
 static struct powerdomain emu_pwrdm = {
 	.name		= "emu_pwrdm",
 	.prcm_offs	= OMAP3430_EMU_MOD,
@@ -200,6 +278,14 @@ static struct powerdomain neon_pwrdm = {
 	.voltdm           = { .name = "mpu_iva" },
 };
 
+static struct powerdomain neon_am35x_pwrdm = {
+	.name		  = "neon_pwrdm",
+	.prcm_offs	  = OMAP3430_NEON_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.voltdm           = { .name = "mpu_iva" },
+};
+
 static struct powerdomain usbhost_pwrdm = {
 	.name		  = "usbhost_pwrdm",
 	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
@@ -293,6 +379,22 @@ static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
 	NULL
 };
 
+static struct powerdomain *powerdomains_am35x[] __initdata = {
+	&wkup_omap2_pwrdm,
+	&mpu_am35x_pwrdm,
+	&neon_am35x_pwrdm,
+	&core_am35x_pwrdm,
+	&sgx_am35x_pwrdm,
+	&dss_am35x_pwrdm,
+	&per_am35x_pwrdm,
+	&emu_pwrdm,
+	&dpll1_pwrdm,
+	&dpll3_pwrdm,
+	&dpll4_pwrdm,
+	&dpll5_pwrdm,
+	NULL
+};
+
 void __init omap3xxx_powerdomains_init(void)
 {
 	unsigned int rev;
@@ -301,21 +403,29 @@ void __init omap3xxx_powerdomains_init(void)
 		return;
 
 	pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
-	pwrdm_register_pwrdms(powerdomains_omap3430_common);
 
 	rev = omap_rev();
 
-	if (rev == OMAP3430_REV_ES1_0)
-		pwrdm_register_pwrdms(powerdomains_omap3430es1);
-	else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
-		 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
-		pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
-	else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
-		 rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 ||
-		 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
-		pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
-	else
-		WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
+	if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1)
+		pwrdm_register_pwrdms(powerdomains_am35x);
+	else {
+		pwrdm_register_pwrdms(powerdomains_omap3430_common);
+
+		if (rev == OMAP3430_REV_ES1_0)
+			pwrdm_register_pwrdms(powerdomains_omap3430es1);
+		else if (rev == OMAP3430_REV_ES2_0 ||
+			 rev == OMAP3430_REV_ES2_1 ||
+			 rev == OMAP3430_REV_ES3_0 ||
+			 rev == OMAP3630_REV_ES1_0)
+			pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
+		else if (rev == OMAP3430_REV_ES3_1 ||
+			 rev == OMAP3430_REV_ES3_1_2 ||
+			 rev == OMAP3630_REV_ES1_1 ||
+			 rev == OMAP3630_REV_ES1_2)
+			pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
+		else
+			WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
+	}
 
 	pwrdm_complete_init();
 }
-- 
1.7.9.4


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

* [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

The am35x family of SoCs only support PWRSTS_ON
and PWRSTS_INACTIVE states so create a new set
of powerdomain structures that ensure that only
the ON and INACTIVE states are entered.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/powerdomain.h           |    1 +
 arch/arm/mach-omap2/powerdomains3xxx_data.c |  134 ++++++++++++++++++++++++---
 2 files changed, 123 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 0d72a8a..561cb27 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -43,6 +43,7 @@
 #define PWRSTS_OFF_ON		(PWRSTS_OFF | PWRSTS_ON)
 #define PWRSTS_OFF_RET		(PWRSTS_OFF | PWRSTS_RET)
 #define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
+#define PWRSTS_INACTIVE_ON	(PWRSTS_INACTIVE | PWRSTS_ON)
 #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON)
 
 
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index b7ea468..fae6dea 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -71,6 +71,22 @@ static struct powerdomain mpu_3xxx_pwrdm = {
 	.voltdm           = { .name = "mpu_iva" },
 };
 
+static struct powerdomain mpu_am35x_pwrdm = {
+	.name		  = "mpu_pwrdm",
+	.prcm_offs	  = MPU_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.flags		  = PWRDM_HAS_MPU_QUIRK,
+	.banks		  = 1,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE,
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_INACTIVE_ON,
+	},
+	.voltdm           = { .name = "mpu_iva" },
+};
+
 /*
  * The USBTLL Save-and-Restore mechanism is broken on
  * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
@@ -120,6 +136,23 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
 	.voltdm           = { .name = "core" },
 };
 
+static struct powerdomain core_am35x_pwrdm = {
+	.name		  = "core_pwrdm",
+	.prcm_offs	  = CORE_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.banks		  = 2,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE,	 /* MEM1RETSTATE */
+		[1] = PWRSTS_INACTIVE,	 /* MEM2RETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_INACTIVE_ON, /* MEM1ONSTATE */
+		[1] = PWRSTS_INACTIVE_ON, /* MEM2ONSTATE */
+	},
+	.voltdm           = { .name = "core" },
+};
+
 static struct powerdomain dss_pwrdm = {
 	.name		  = "dss_pwrdm",
 	.prcm_offs	  = OMAP3430_DSS_MOD,
@@ -135,6 +168,21 @@ static struct powerdomain dss_pwrdm = {
 	.voltdm           = { .name = "core" },
 };
 
+static struct powerdomain dss_am35x_pwrdm = {
+	.name		  = "dss_pwrdm",
+	.prcm_offs	  = OMAP3430_DSS_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.banks		  = 1,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
+	},
+	.voltdm           = { .name = "core" },
+};
+
 /*
  * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
  * possible SGX powerstate, the SGX device itself does not support
@@ -156,6 +204,21 @@ static struct powerdomain sgx_pwrdm = {
 	.voltdm           = { .name = "core" },
 };
 
+static struct powerdomain sgx_am35x_pwrdm = {
+	.name		  = "sgx_pwrdm",
+	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.banks		  = 1,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
+	},
+	.voltdm           = { .name = "core" },
+};
+
 static struct powerdomain cam_pwrdm = {
 	.name		  = "cam_pwrdm",
 	.prcm_offs	  = OMAP3430_CAM_MOD,
@@ -186,6 +249,21 @@ static struct powerdomain per_pwrdm = {
 	.voltdm           = { .name = "core" },
 };
 
+static struct powerdomain per_am35x_pwrdm = {
+	.name		  = "per_pwrdm",
+	.prcm_offs	  = OMAP3430_PER_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.banks		  = 1,
+	.pwrsts_mem_ret	  = {
+		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
+	},
+	.pwrsts_mem_on	  = {
+		[0] = PWRSTS_ON,  /* MEMONSTATE */
+	},
+	.voltdm           = { .name = "core" },
+};
+
 static struct powerdomain emu_pwrdm = {
 	.name		= "emu_pwrdm",
 	.prcm_offs	= OMAP3430_EMU_MOD,
@@ -200,6 +278,14 @@ static struct powerdomain neon_pwrdm = {
 	.voltdm           = { .name = "mpu_iva" },
 };
 
+static struct powerdomain neon_am35x_pwrdm = {
+	.name		  = "neon_pwrdm",
+	.prcm_offs	  = OMAP3430_NEON_MOD,
+	.pwrsts		  = PWRSTS_INACTIVE_ON,
+	.pwrsts_logic_ret = PWRSTS_INACTIVE,
+	.voltdm           = { .name = "mpu_iva" },
+};
+
 static struct powerdomain usbhost_pwrdm = {
 	.name		  = "usbhost_pwrdm",
 	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
@@ -293,6 +379,22 @@ static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
 	NULL
 };
 
+static struct powerdomain *powerdomains_am35x[] __initdata = {
+	&wkup_omap2_pwrdm,
+	&mpu_am35x_pwrdm,
+	&neon_am35x_pwrdm,
+	&core_am35x_pwrdm,
+	&sgx_am35x_pwrdm,
+	&dss_am35x_pwrdm,
+	&per_am35x_pwrdm,
+	&emu_pwrdm,
+	&dpll1_pwrdm,
+	&dpll3_pwrdm,
+	&dpll4_pwrdm,
+	&dpll5_pwrdm,
+	NULL
+};
+
 void __init omap3xxx_powerdomains_init(void)
 {
 	unsigned int rev;
@@ -301,21 +403,29 @@ void __init omap3xxx_powerdomains_init(void)
 		return;
 
 	pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
-	pwrdm_register_pwrdms(powerdomains_omap3430_common);
 
 	rev = omap_rev();
 
-	if (rev == OMAP3430_REV_ES1_0)
-		pwrdm_register_pwrdms(powerdomains_omap3430es1);
-	else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
-		 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
-		pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
-	else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
-		 rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 ||
-		 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
-		pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
-	else
-		WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
+	if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1)
+		pwrdm_register_pwrdms(powerdomains_am35x);
+	else {
+		pwrdm_register_pwrdms(powerdomains_omap3430_common);
+
+		if (rev == OMAP3430_REV_ES1_0)
+			pwrdm_register_pwrdms(powerdomains_omap3430es1);
+		else if (rev == OMAP3430_REV_ES2_0 ||
+			 rev == OMAP3430_REV_ES2_1 ||
+			 rev == OMAP3430_REV_ES3_0 ||
+			 rev == OMAP3630_REV_ES1_0)
+			pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
+		else if (rev == OMAP3430_REV_ES3_1 ||
+			 rev == OMAP3430_REV_ES3_1_2 ||
+			 rev == OMAP3630_REV_ES1_1 ||
+			 rev == OMAP3630_REV_ES1_2)
+			pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
+		else
+			WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
+	}
 
 	pwrdm_complete_init();
 }
-- 
1.7.9.4

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

The am35x family of SoCs do not have an IVA so
a parallel set of clockdomain dependencies are
required that are simililar to OMAP3 but without
any IVA dependencies.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/clockdomains3xxx_data.c |  146 ++++++++++++++++++++++++++-
 1 file changed, 141 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index b84e138..a05a8cb 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -59,6 +59,12 @@ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
+	{ .clkdm_name = "mpu_clkdm", },
+	{ .clkdm_name = "wkup_clkdm", },
+	{ NULL },
+};
+
 /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
 static struct clkdm_dep per_wkdeps[] = {
 	{ .clkdm_name = "core_l3_clkdm" },
@@ -69,6 +75,14 @@ static struct clkdm_dep per_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep per_am35x_wkdeps[] = {
+	{ .clkdm_name = "core_l3_clkdm" },
+	{ .clkdm_name = "core_l4_clkdm" },
+	{ .clkdm_name = "mpu_clkdm" },
+	{ .clkdm_name = "wkup_clkdm" },
+	{ NULL },
+};
+
 /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
 static struct clkdm_dep usbhost_wkdeps[] = {
 	{ .clkdm_name = "core_l3_clkdm" },
@@ -79,6 +93,14 @@ static struct clkdm_dep usbhost_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep usbhost_am35x_wkdeps[] = {
+	{ .clkdm_name = "core_l3_clkdm" },
+	{ .clkdm_name = "core_l4_clkdm" },
+	{ .clkdm_name = "mpu_clkdm" },
+	{ .clkdm_name = "wkup_clkdm" },
+	{ NULL },
+};
+
 /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
 static struct clkdm_dep mpu_3xxx_wkdeps[] = {
 	{ .clkdm_name = "core_l3_clkdm" },
@@ -89,6 +111,14 @@ static struct clkdm_dep mpu_3xxx_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep mpu_am35x_wkdeps[] = {
+	{ .clkdm_name = "core_l3_clkdm" },
+	{ .clkdm_name = "core_l4_clkdm" },
+	{ .clkdm_name = "dss_clkdm" },
+	{ .clkdm_name = "per_clkdm" },
+	{ NULL },
+};
+
 /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
 static struct clkdm_dep iva2_wkdeps[] = {
 	{ .clkdm_name = "core_l3_clkdm" },
@@ -116,6 +146,12 @@ static struct clkdm_dep dss_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep dss_am35x_wkdeps[] = {
+	{ .clkdm_name = "mpu_clkdm" },
+	{ .clkdm_name = "wkup_clkdm" },
+	{ NULL },
+};
+
 /* 3430: PM_WKDEP_NEON: MPU */
 static struct clkdm_dep neon_wkdeps[] = {
 	{ .clkdm_name = "mpu_clkdm" },
@@ -131,6 +167,11 @@ static struct clkdm_dep dss_sleepdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep dss_am35x_sleepdeps[] = {
+	{ .clkdm_name = "mpu_clkdm" },
+	{ NULL },
+};
+
 /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
 static struct clkdm_dep per_sleepdeps[] = {
 	{ .clkdm_name = "mpu_clkdm" },
@@ -138,6 +179,11 @@ static struct clkdm_dep per_sleepdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep per_am35x_sleepdeps[] = {
+	{ .clkdm_name = "mpu_clkdm" },
+	{ NULL },
+};
+
 /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
 static struct clkdm_dep usbhost_sleepdeps[] = {
 	{ .clkdm_name = "mpu_clkdm" },
@@ -145,6 +191,11 @@ static struct clkdm_dep usbhost_sleepdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep usbhost_am35x_sleepdeps[] = {
+	{ .clkdm_name = "mpu_clkdm" },
+	{ NULL },
+};
+
 /* 3430: CM_SLEEPDEP_CAM: MPU */
 static struct clkdm_dep cam_sleepdeps[] = {
 	{ .clkdm_name = "mpu_clkdm" },
@@ -175,6 +226,15 @@ static struct clockdomain mpu_3xxx_clkdm = {
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
 };
 
+static struct clockdomain mpu_am35x_clkdm = {
+	.name		= "mpu_clkdm",
+	.pwrdm		= { .name = "mpu_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
+	.dep_bit	= OMAP3430_EN_MPU_SHIFT,
+	.wkdep_srcs	= mpu_am35x_wkdeps,
+	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
+};
+
 static struct clockdomain neon_clkdm = {
 	.name		= "neon_clkdm",
 	.pwrdm		= { .name = "neon_pwrdm" },
@@ -210,6 +270,15 @@ static struct clockdomain sgx_clkdm = {
 	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
 };
 
+static struct clockdomain sgx_am35x_clkdm = {
+	.name		= "sgx_clkdm",
+	.pwrdm		= { .name = "sgx_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.wkdep_srcs	= gfx_sgx_am35x_wkdeps,
+	.sleepdep_srcs	= gfx_sgx_sleepdeps,
+	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
+};
+
 /*
  * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
  * then that information was removed from the 34xx ES2+ TRM.  It is
@@ -261,6 +330,16 @@ static struct clockdomain dss_3xxx_clkdm = {
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
 };
 
+static struct clockdomain dss_am35x_clkdm = {
+	.name		= "dss_clkdm",
+	.pwrdm		= { .name = "dss_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.dep_bit	= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
+	.wkdep_srcs	= dss_am35x_wkdeps,
+	.sleepdep_srcs	= dss_am35x_sleepdeps,
+	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
+};
+
 static struct clockdomain cam_clkdm = {
 	.name		= "cam_clkdm",
 	.pwrdm		= { .name = "cam_pwrdm" },
@@ -279,6 +358,15 @@ static struct clockdomain usbhost_clkdm = {
 	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
 };
 
+static struct clockdomain usbhost_am35x_clkdm = {
+	.name		= "usbhost_clkdm",
+	.pwrdm		= { .name = "core_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.wkdep_srcs	= usbhost_am35x_wkdeps,
+	.sleepdep_srcs	= usbhost_am35x_sleepdeps,
+	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
+};
+
 static struct clockdomain per_clkdm = {
 	.name		= "per_clkdm",
 	.pwrdm		= { .name = "per_pwrdm" },
@@ -289,6 +377,16 @@ static struct clockdomain per_clkdm = {
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
 };
 
+static struct clockdomain per_am35x_clkdm = {
+	.name		= "per_clkdm",
+	.pwrdm		= { .name = "per_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.dep_bit	= OMAP3430_EN_PER_SHIFT,
+	.wkdep_srcs	= per_am35x_wkdeps,
+	.sleepdep_srcs	= per_am35x_sleepdeps,
+	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
+};
+
 /*
  * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
  * switched of even if sdti is in use
@@ -341,6 +439,15 @@ static struct clkdm_autodep clkdm_autodeps[] = {
 	}
 };
 
+static struct clkdm_autodep clkdm_am35x_autodeps[] = {
+	{
+		.clkdm = { .name = "mpu_clkdm" },
+	},
+	{
+		.clkdm = { .name = NULL },
+	}
+};
+
 /*
  *
  */
@@ -366,6 +473,26 @@ static struct clockdomain *clockdomains_omap3430_common[] __initdata = {
 	NULL
 };
 
+static struct clockdomain *clockdomains_am35x_common[] __initdata = {
+	&wkup_common_clkdm,
+	&cm_common_clkdm,
+	&prm_common_clkdm,
+	&mpu_am35x_clkdm,
+	&neon_clkdm,
+	&sgx_am35x_clkdm,
+	&core_l3_3xxx_clkdm,
+	&core_l4_3xxx_clkdm,
+	&dss_am35x_clkdm,
+	&per_am35x_clkdm,
+	&emu_clkdm,
+	&usbhost_am35x_clkdm,
+	&dpll1_clkdm,
+	&dpll3_clkdm,
+	&dpll4_clkdm,
+	&dpll5_clkdm,
+	NULL
+};
+
 static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
 	&gfx_3430es1_clkdm,
 	NULL,
@@ -381,18 +508,27 @@ static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {
 void __init omap3xxx_clockdomains_init(void)
 {
 	struct clockdomain **sc;
+	unsigned int rev;
 
 	if (!cpu_is_omap34xx())
 		return;
 
 	clkdm_register_platform_funcs(&omap3_clkdm_operations);
-	clkdm_register_clkdms(clockdomains_omap3430_common);
 
-	sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 :
-		clockdomains_omap3430es2plus;
+	rev = omap_rev();
 
-	clkdm_register_clkdms(sc);
+	if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1) {
+		clkdm_register_clkdms(clockdomains_am35x_common);
+		clkdm_register_autodeps(clkdm_am35x_autodeps);
+	} else {
+		clkdm_register_clkdms(clockdomains_omap3430_common);
+
+		sc = (rev == OMAP3430_REV_ES1_0) ?
+			clockdomains_omap3430es1 : clockdomains_omap3430es2plus;
+
+		clkdm_register_clkdms(sc);
+		clkdm_register_autodeps(clkdm_autodeps);
+	}
 
-	clkdm_register_autodeps(clkdm_autodeps);
 	clkdm_complete_init();
 }
-- 
1.7.9.4


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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

The am35x family of SoCs do not have an IVA so
a parallel set of clockdomain dependencies are
required that are simililar to OMAP3 but without
any IVA dependencies.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/clockdomains3xxx_data.c |  146 ++++++++++++++++++++++++++-
 1 file changed, 141 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index b84e138..a05a8cb 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -59,6 +59,12 @@ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
+	{ .clkdm_name = "mpu_clkdm", },
+	{ .clkdm_name = "wkup_clkdm", },
+	{ NULL },
+};
+
 /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
 static struct clkdm_dep per_wkdeps[] = {
 	{ .clkdm_name = "core_l3_clkdm" },
@@ -69,6 +75,14 @@ static struct clkdm_dep per_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep per_am35x_wkdeps[] = {
+	{ .clkdm_name = "core_l3_clkdm" },
+	{ .clkdm_name = "core_l4_clkdm" },
+	{ .clkdm_name = "mpu_clkdm" },
+	{ .clkdm_name = "wkup_clkdm" },
+	{ NULL },
+};
+
 /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
 static struct clkdm_dep usbhost_wkdeps[] = {
 	{ .clkdm_name = "core_l3_clkdm" },
@@ -79,6 +93,14 @@ static struct clkdm_dep usbhost_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep usbhost_am35x_wkdeps[] = {
+	{ .clkdm_name = "core_l3_clkdm" },
+	{ .clkdm_name = "core_l4_clkdm" },
+	{ .clkdm_name = "mpu_clkdm" },
+	{ .clkdm_name = "wkup_clkdm" },
+	{ NULL },
+};
+
 /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
 static struct clkdm_dep mpu_3xxx_wkdeps[] = {
 	{ .clkdm_name = "core_l3_clkdm" },
@@ -89,6 +111,14 @@ static struct clkdm_dep mpu_3xxx_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep mpu_am35x_wkdeps[] = {
+	{ .clkdm_name = "core_l3_clkdm" },
+	{ .clkdm_name = "core_l4_clkdm" },
+	{ .clkdm_name = "dss_clkdm" },
+	{ .clkdm_name = "per_clkdm" },
+	{ NULL },
+};
+
 /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
 static struct clkdm_dep iva2_wkdeps[] = {
 	{ .clkdm_name = "core_l3_clkdm" },
@@ -116,6 +146,12 @@ static struct clkdm_dep dss_wkdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep dss_am35x_wkdeps[] = {
+	{ .clkdm_name = "mpu_clkdm" },
+	{ .clkdm_name = "wkup_clkdm" },
+	{ NULL },
+};
+
 /* 3430: PM_WKDEP_NEON: MPU */
 static struct clkdm_dep neon_wkdeps[] = {
 	{ .clkdm_name = "mpu_clkdm" },
@@ -131,6 +167,11 @@ static struct clkdm_dep dss_sleepdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep dss_am35x_sleepdeps[] = {
+	{ .clkdm_name = "mpu_clkdm" },
+	{ NULL },
+};
+
 /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
 static struct clkdm_dep per_sleepdeps[] = {
 	{ .clkdm_name = "mpu_clkdm" },
@@ -138,6 +179,11 @@ static struct clkdm_dep per_sleepdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep per_am35x_sleepdeps[] = {
+	{ .clkdm_name = "mpu_clkdm" },
+	{ NULL },
+};
+
 /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
 static struct clkdm_dep usbhost_sleepdeps[] = {
 	{ .clkdm_name = "mpu_clkdm" },
@@ -145,6 +191,11 @@ static struct clkdm_dep usbhost_sleepdeps[] = {
 	{ NULL },
 };
 
+static struct clkdm_dep usbhost_am35x_sleepdeps[] = {
+	{ .clkdm_name = "mpu_clkdm" },
+	{ NULL },
+};
+
 /* 3430: CM_SLEEPDEP_CAM: MPU */
 static struct clkdm_dep cam_sleepdeps[] = {
 	{ .clkdm_name = "mpu_clkdm" },
@@ -175,6 +226,15 @@ static struct clockdomain mpu_3xxx_clkdm = {
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
 };
 
+static struct clockdomain mpu_am35x_clkdm = {
+	.name		= "mpu_clkdm",
+	.pwrdm		= { .name = "mpu_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
+	.dep_bit	= OMAP3430_EN_MPU_SHIFT,
+	.wkdep_srcs	= mpu_am35x_wkdeps,
+	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
+};
+
 static struct clockdomain neon_clkdm = {
 	.name		= "neon_clkdm",
 	.pwrdm		= { .name = "neon_pwrdm" },
@@ -210,6 +270,15 @@ static struct clockdomain sgx_clkdm = {
 	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
 };
 
+static struct clockdomain sgx_am35x_clkdm = {
+	.name		= "sgx_clkdm",
+	.pwrdm		= { .name = "sgx_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.wkdep_srcs	= gfx_sgx_am35x_wkdeps,
+	.sleepdep_srcs	= gfx_sgx_sleepdeps,
+	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
+};
+
 /*
  * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
  * then that information was removed from the 34xx ES2+ TRM.  It is
@@ -261,6 +330,16 @@ static struct clockdomain dss_3xxx_clkdm = {
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
 };
 
+static struct clockdomain dss_am35x_clkdm = {
+	.name		= "dss_clkdm",
+	.pwrdm		= { .name = "dss_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.dep_bit	= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
+	.wkdep_srcs	= dss_am35x_wkdeps,
+	.sleepdep_srcs	= dss_am35x_sleepdeps,
+	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
+};
+
 static struct clockdomain cam_clkdm = {
 	.name		= "cam_clkdm",
 	.pwrdm		= { .name = "cam_pwrdm" },
@@ -279,6 +358,15 @@ static struct clockdomain usbhost_clkdm = {
 	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
 };
 
+static struct clockdomain usbhost_am35x_clkdm = {
+	.name		= "usbhost_clkdm",
+	.pwrdm		= { .name = "core_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.wkdep_srcs	= usbhost_am35x_wkdeps,
+	.sleepdep_srcs	= usbhost_am35x_sleepdeps,
+	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
+};
+
 static struct clockdomain per_clkdm = {
 	.name		= "per_clkdm",
 	.pwrdm		= { .name = "per_pwrdm" },
@@ -289,6 +377,16 @@ static struct clockdomain per_clkdm = {
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
 };
 
+static struct clockdomain per_am35x_clkdm = {
+	.name		= "per_clkdm",
+	.pwrdm		= { .name = "per_pwrdm" },
+	.flags		= CLKDM_CAN_HWSUP_SWSUP,
+	.dep_bit	= OMAP3430_EN_PER_SHIFT,
+	.wkdep_srcs	= per_am35x_wkdeps,
+	.sleepdep_srcs	= per_am35x_sleepdeps,
+	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
+};
+
 /*
  * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
  * switched of even if sdti is in use
@@ -341,6 +439,15 @@ static struct clkdm_autodep clkdm_autodeps[] = {
 	}
 };
 
+static struct clkdm_autodep clkdm_am35x_autodeps[] = {
+	{
+		.clkdm = { .name = "mpu_clkdm" },
+	},
+	{
+		.clkdm = { .name = NULL },
+	}
+};
+
 /*
  *
  */
@@ -366,6 +473,26 @@ static struct clockdomain *clockdomains_omap3430_common[] __initdata = {
 	NULL
 };
 
+static struct clockdomain *clockdomains_am35x_common[] __initdata = {
+	&wkup_common_clkdm,
+	&cm_common_clkdm,
+	&prm_common_clkdm,
+	&mpu_am35x_clkdm,
+	&neon_clkdm,
+	&sgx_am35x_clkdm,
+	&core_l3_3xxx_clkdm,
+	&core_l4_3xxx_clkdm,
+	&dss_am35x_clkdm,
+	&per_am35x_clkdm,
+	&emu_clkdm,
+	&usbhost_am35x_clkdm,
+	&dpll1_clkdm,
+	&dpll3_clkdm,
+	&dpll4_clkdm,
+	&dpll5_clkdm,
+	NULL
+};
+
 static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
 	&gfx_3430es1_clkdm,
 	NULL,
@@ -381,18 +508,27 @@ static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {
 void __init omap3xxx_clockdomains_init(void)
 {
 	struct clockdomain **sc;
+	unsigned int rev;
 
 	if (!cpu_is_omap34xx())
 		return;
 
 	clkdm_register_platform_funcs(&omap3_clkdm_operations);
-	clkdm_register_clkdms(clockdomains_omap3430_common);
 
-	sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 :
-		clockdomains_omap3430es2plus;
+	rev = omap_rev();
 
-	clkdm_register_clkdms(sc);
+	if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1) {
+		clkdm_register_clkdms(clockdomains_am35x_common);
+		clkdm_register_autodeps(clkdm_am35x_autodeps);
+	} else {
+		clkdm_register_clkdms(clockdomains_omap3430_common);
+
+		sc = (rev == OMAP3430_REV_ES1_0) ?
+			clockdomains_omap3430es1 : clockdomains_omap3430es2plus;
+
+		clkdm_register_clkdms(sc);
+		clkdm_register_autodeps(clkdm_autodeps);
+	}
 
-	clkdm_register_autodeps(clkdm_autodeps);
 	clkdm_complete_init();
 }
-- 
1.7.9.4

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

* [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

The typical SDRAM Controller Subsystem module (SDRC)
on TI OMAP3 devices has two submodules: the SDRAM Memory
Scheduler (SMS) submodule, and the SDRC submodule--the
'SDRC' acronym/term is overloaded.  The am35x family of
devices is different in that it has an EMIF4 submodule
instead of an SDRC submodule.  The SMS submodules are
similar, though.

To allow code to determine whether the current device has an
SDRC submodule or and EMIF4 submodule, add the 'OMAP3_HAS_SDRC_EMIF4'
feature and set it when running on an am35x SoC.

So when:
- omap3_has_sdrc() returns true: the system has an SDRC module
	consisting of an SMS submodule and either an SDRC submodule
	or an EMIF4 submodule.
- omap3_has_sdrc_emif4() returns true: the system has an EMIF4
	submodule.  It is assumed that this feature will only be
	checked when there is an SDRC module present (i.e., when
	omap3_has_sdrc() would return true).

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/id.c              |    5 ++++-
 arch/arm/plat-omap/include/plat/cpu.h |   12 +++++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index b6508e5..abb5e51 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -256,10 +256,13 @@ void __init omap3xxx_check_features(void)
 	 *   the incorrectly set feature bits.
 	 * - Indicate that am35x SoCs don't support the PWRDM_POWER_RET
 	 *   and PWRDM_POWER_OFF states by clearing OMAP3_HAS_PWROFF.
+	 * - Indicate that am35x SoCs have an EMIF4 SDRC submodule.
 	 */
-	if (cpu_is_omap3505() || cpu_is_omap3517())
+	if (cpu_is_omap3505() || cpu_is_omap3517()) {
 		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP |
 			OMAP3_HAS_PWROFF);
+		omap_features |= OMAP3_HAS_SDRC_EMIF4;
+	}
 
 	/*
 	 * TODO: Get additional info (where applicable)
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index c3f1a42..207f21b 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -476,11 +476,12 @@ extern u32 omap_features;
 #define OMAP3_HAS_192MHZ_CLK		BIT(5)
 #define OMAP3_HAS_IO_WAKEUP		BIT(6)
 #define OMAP3_HAS_SDRC			BIT(7)
-#define OMAP3_HAS_IO_CHAIN_CTRL		BIT(8)
-#define OMAP3_HAS_PWROFF		BIT(9)
-#define OMAP4_HAS_MPU_1GHZ		BIT(10)
-#define OMAP4_HAS_MPU_1_2GHZ		BIT(11)
-#define OMAP4_HAS_MPU_1_5GHZ		BIT(12)
+#define OMAP3_HAS_SDRC_EMIF4		BIT(8)
+#define OMAP3_HAS_IO_CHAIN_CTRL		BIT(9)
+#define OMAP3_HAS_PWROFF		BIT(10)
+#define OMAP4_HAS_MPU_1GHZ		BIT(11)
+#define OMAP4_HAS_MPU_1_2GHZ		BIT(12)
+#define OMAP4_HAS_MPU_1_5GHZ		BIT(13)
 
 
 #define OMAP3_HAS_FEATURE(feat,flag)			\
@@ -497,6 +498,7 @@ OMAP3_HAS_FEATURE(isp, ISP)
 OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
 OMAP3_HAS_FEATURE(sdrc, SDRC)
+OMAP3_HAS_FEATURE(sdrc_emif4, SDRC_EMIF4)
 OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
 OMAP3_HAS_FEATURE(pwroff, PWROFF)
 
-- 
1.7.9.4


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

* [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

The typical SDRAM Controller Subsystem module (SDRC)
on TI OMAP3 devices has two submodules: the SDRAM Memory
Scheduler (SMS) submodule, and the SDRC submodule--the
'SDRC' acronym/term is overloaded.  The am35x family of
devices is different in that it has an EMIF4 submodule
instead of an SDRC submodule.  The SMS submodules are
similar, though.

To allow code to determine whether the current device has an
SDRC submodule or and EMIF4 submodule, add the 'OMAP3_HAS_SDRC_EMIF4'
feature and set it when running on an am35x SoC.

So when:
- omap3_has_sdrc() returns true: the system has an SDRC module
	consisting of an SMS submodule and either an SDRC submodule
	or an EMIF4 submodule.
- omap3_has_sdrc_emif4() returns true: the system has an EMIF4
	submodule.  It is assumed that this feature will only be
	checked when there is an SDRC module present (i.e., when
	omap3_has_sdrc() would return true).

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/id.c              |    5 ++++-
 arch/arm/plat-omap/include/plat/cpu.h |   12 +++++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index b6508e5..abb5e51 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -256,10 +256,13 @@ void __init omap3xxx_check_features(void)
 	 *   the incorrectly set feature bits.
 	 * - Indicate that am35x SoCs don't support the PWRDM_POWER_RET
 	 *   and PWRDM_POWER_OFF states by clearing OMAP3_HAS_PWROFF.
+	 * - Indicate that am35x SoCs have an EMIF4 SDRC submodule.
 	 */
-	if (cpu_is_omap3505() || cpu_is_omap3517())
+	if (cpu_is_omap3505() || cpu_is_omap3517()) {
 		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP |
 			OMAP3_HAS_PWROFF);
+		omap_features |= OMAP3_HAS_SDRC_EMIF4;
+	}
 
 	/*
 	 * TODO: Get additional info (where applicable)
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index c3f1a42..207f21b 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -476,11 +476,12 @@ extern u32 omap_features;
 #define OMAP3_HAS_192MHZ_CLK		BIT(5)
 #define OMAP3_HAS_IO_WAKEUP		BIT(6)
 #define OMAP3_HAS_SDRC			BIT(7)
-#define OMAP3_HAS_IO_CHAIN_CTRL		BIT(8)
-#define OMAP3_HAS_PWROFF		BIT(9)
-#define OMAP4_HAS_MPU_1GHZ		BIT(10)
-#define OMAP4_HAS_MPU_1_2GHZ		BIT(11)
-#define OMAP4_HAS_MPU_1_5GHZ		BIT(12)
+#define OMAP3_HAS_SDRC_EMIF4		BIT(8)
+#define OMAP3_HAS_IO_CHAIN_CTRL		BIT(9)
+#define OMAP3_HAS_PWROFF		BIT(10)
+#define OMAP4_HAS_MPU_1GHZ		BIT(11)
+#define OMAP4_HAS_MPU_1_2GHZ		BIT(12)
+#define OMAP4_HAS_MPU_1_5GHZ		BIT(13)
 
 
 #define OMAP3_HAS_FEATURE(feat,flag)			\
@@ -497,6 +498,7 @@ OMAP3_HAS_FEATURE(isp, ISP)
 OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
 OMAP3_HAS_FEATURE(sdrc, SDRC)
+OMAP3_HAS_FEATURE(sdrc_emif4, SDRC_EMIF4)
 OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
 OMAP3_HAS_FEATURE(pwroff, PWROFF)
 
-- 
1.7.9.4

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

* [PATCH 10/12] arm: omap3: am35x: Add minimal EMIF4 support
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

The typical SDRAM Controller Subsystem module (SDRC)
on TI OMAP3 devices has two submodules: the SDRAM Memory
Scheduler (SMS) submodule, and the SDRC submodule--the
'SDRC' acronym/term is overloaded.  The am35x family of
devices is different in that it has an EMIF4 submodule
instead of an SDRC submodule.  The SMS submodules are
similar, though.

Currently, the code assumes that if its an OMAP3 device,
then it has an SDRC module and if it has an SDRC module,
it has an SDRC submodule.  Since the SDRC module can now
have an EMIF4 submodule, the code needs to be reworked.

This rework can be minimal since there is an EMIF driver being
developed which should take care of most of the EMIF4 details.
In the meantime:
- enable smart-idle and VTP power save mode in the EMIF4
- have omap3_core_dpll_m2_set_rate() return an error when
  there's an EMIF4 module because it assumes there's an
  SDRC submodule
- don't bother pushing map3_sram_configure_core_dpll()
  to sram since its not used when there's an EMIF4
  submodule.

NOTE: There is still a bit of ugliness in that the SDRC
submodule's mapping (in omap34xx_io_desc[]) is used.
That works okay since the address and size of the EMIF4
submodule is the same as the SDRC submodule's.  To fix that,
a special "early_cpu_is_xxx()" or "early_omap3_has_sdrc_emif4()"
routine needs to be created because its too early to use the
regular cpu_is_xxx() or omap3_has_sdrc_emif4() calls.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/clkt34xx_dpll3m2.c |    6 +++-
 arch/arm/mach-omap2/io.c               |    9 ++++++
 arch/arm/mach-omap2/sdrc.c             |   52 ++++++++++++++++++++++----------
 arch/arm/mach-omap2/sdrc.h             |   13 ++++++++
 arch/arm/plat-omap/sram.c              |    8 +++--
 5 files changed, 68 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
index d6e34dd..3864528 100644
--- a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
+++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
+#include <plat/cpu.h>
 #include <plat/clock.h>
 #include <plat/sram.h>
 #include <plat/sdrc.h>
@@ -45,7 +46,7 @@
  * @rate: rounded target rate
  *
  * Program the DPLL M2 divider with the rounded target rate.  Returns
- * -EINVAL upon error, or 0 upon success.
+ * -EINVAL upon error or if there's an EMIF4 submodule, or 0 upon success.
  */
 int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 {
@@ -60,6 +61,9 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 	if (!clk || !rate)
 		return -EINVAL;
 
+	if (omap3_has_sdrc_emif4())
+		return -EINVAL;
+
 	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
 	if (validrate != rate)
 		return -EINVAL;
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 065bd76..1accc90 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -450,6 +450,15 @@ void __init omap3630_init_early(void)
 
 void __init am35xx_init_early(void)
 {
+	/*
+	 * The am35x has an EMIF4 submodule in the SDRC module instead
+	 * of an SDRC submodule like other OMAP3 SoCs.  Fortunately,
+	 * the EMIF4 and SDRC submodules are at the same physical address
+	 * so we can use the SDRC mapping to access the EMIF4 submodule.
+	 * The reason for not making a separate mapping for the EMIF4 is
+	 * to avoid creating an early_cpu_is_xxx()-like call because its
+	 * too early to use cpu_is_3505/3517() or omap3_has_sdrc_emif4().
+	 */
 	omap3_init_early();
 }
 
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index e3d345f..d804065 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -24,11 +24,13 @@
 #include <linux/io.h>
 
 #include "common.h"
+#include "control.h"
 #include <plat/clock.h>
 #include <plat/sram.h>
 
 #include <plat/sdrc.h>
 #include "sdrc.h"
+#include "emif4.h"
 
 static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1;
 
@@ -136,28 +138,46 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
 			    struct omap_sdrc_params *sdrc_cs1)
 {
 	u32 l;
+	void __iomem *ctrl_base;
 
 	l = sms_read_reg(SMS_SYSCONFIG);
 	l &= ~(0x3 << 3);
 	l |= (0x2 << 3);
 	sms_write_reg(l, SMS_SYSCONFIG);
 
-	l = sdrc_read_reg(SDRC_SYSCONFIG);
-	l &= ~(0x3 << 3);
-	l |= (0x2 << 3);
-	sdrc_write_reg(l, SDRC_SYSCONFIG);
-
-	sdrc_init_params_cs0 = sdrc_cs0;
-	sdrc_init_params_cs1 = sdrc_cs1;
-
-	/* XXX Enable SRFRONIDLEREQ here also? */
-	/*
-	 * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA
-	 * can cause random memory corruption
-	 */
-	l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
-		(1 << SDRC_POWER_PAGEPOLICY_SHIFT);
-	sdrc_write_reg(l, SDRC_POWER);
+	if (omap3_has_sdrc_emif4()) {
+		l = emif4_read_reg(EMIF4_PWR_MGMT_CTRL);
+		l &= ~(0x3 << 30);
+		l |= (0x2 << 30);
+		emif4_write_reg(l, EMIF4_PWR_MGMT_CTRL);
+
+		/* Enable VTP Power Save Mode */
+		ctrl_base = omap_ctrl_base_get();
+		if (ctrl_base) {
+			l = __raw_readl(ctrl_base + AM35XX_CONTROL_DEVCONF3);
+			l &= ~(0x3 << 13);
+			l |= (0x1 << 13);
+			__raw_writel(l, ctrl_base + AM35XX_CONTROL_DEVCONF3);
+		}
+	} else {
+		l = sdrc_read_reg(SDRC_SYSCONFIG);
+		l &= ~(0x3 << 3);
+		l |= (0x2 << 3);
+		sdrc_write_reg(l, SDRC_SYSCONFIG);
+
+		sdrc_init_params_cs0 = sdrc_cs0;
+		sdrc_init_params_cs1 = sdrc_cs1;
+
+		/* XXX Enable SRFRONIDLEREQ here also? */
+		/*
+		 * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA
+		 * can cause random memory corruption
+		 */
+		l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
+			(1 << SDRC_POWER_PAGEPOLICY_SHIFT);
+		sdrc_write_reg(l, SDRC_POWER);
+	}
+
 	omap2_sms_save_context();
 }
 
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h
index b3f8379..5fb6490 100644
--- a/arch/arm/mach-omap2/sdrc.h
+++ b/arch/arm/mach-omap2/sdrc.h
@@ -25,6 +25,7 @@ extern void __iomem *omap2_sdrc_base;
 extern void __iomem *omap2_sms_base;
 
 #define OMAP_SDRC_REGADDR(reg)			(omap2_sdrc_base + (reg))
+#define OMAP_EMIF4_REGADDR(reg)			(omap2_sdrc_base + (reg))
 #define OMAP_SMS_REGADDR(reg)			(omap2_sms_base + (reg))
 
 /* SDRC global register get/set */
@@ -39,6 +40,18 @@ static inline u32 sdrc_read_reg(u16 reg)
 	return __raw_readl(OMAP_SDRC_REGADDR(reg));
 }
 
+/* EMIF4 global register get/set */
+
+static inline void emif4_write_reg(u32 val, u16 reg)
+{
+	__raw_writel(val, OMAP_EMIF4_REGADDR(reg));
+}
+
+static inline u32 emif4_read_reg(u16 reg)
+{
+	return __raw_readl(OMAP_EMIF4_REGADDR(reg));
+}
+
 /* SMS global register get/set */
 
 static inline void sms_write_reg(u32 val, u16 reg)
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index eec98af..42ccfcb 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -353,9 +353,11 @@ void omap3_sram_restore_context(void)
 {
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 
-	_omap3_sram_configure_core_dpll =
-		omap_sram_push(omap3_sram_configure_core_dpll,
-			       omap3_sram_configure_core_dpll_sz);
+	if (!omap3_has_sdrc_emif4())
+		_omap3_sram_configure_core_dpll =
+			omap_sram_push(omap3_sram_configure_core_dpll,
+				       omap3_sram_configure_core_dpll_sz);
+
 	omap_push_sram_idle();
 }
 #endif /* CONFIG_PM */
-- 
1.7.9.4


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

* [PATCH 10/12] arm: omap3: am35x: Add minimal EMIF4 support
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

The typical SDRAM Controller Subsystem module (SDRC)
on TI OMAP3 devices has two submodules: the SDRAM Memory
Scheduler (SMS) submodule, and the SDRC submodule--the
'SDRC' acronym/term is overloaded.  The am35x family of
devices is different in that it has an EMIF4 submodule
instead of an SDRC submodule.  The SMS submodules are
similar, though.

Currently, the code assumes that if its an OMAP3 device,
then it has an SDRC module and if it has an SDRC module,
it has an SDRC submodule.  Since the SDRC module can now
have an EMIF4 submodule, the code needs to be reworked.

This rework can be minimal since there is an EMIF driver being
developed which should take care of most of the EMIF4 details.
In the meantime:
- enable smart-idle and VTP power save mode in the EMIF4
- have omap3_core_dpll_m2_set_rate() return an error when
  there's an EMIF4 module because it assumes there's an
  SDRC submodule
- don't bother pushing map3_sram_configure_core_dpll()
  to sram since its not used when there's an EMIF4
  submodule.

NOTE: There is still a bit of ugliness in that the SDRC
submodule's mapping (in omap34xx_io_desc[]) is used.
That works okay since the address and size of the EMIF4
submodule is the same as the SDRC submodule's.  To fix that,
a special "early_cpu_is_xxx()" or "early_omap3_has_sdrc_emif4()"
routine needs to be created because its too early to use the
regular cpu_is_xxx() or omap3_has_sdrc_emif4() calls.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/clkt34xx_dpll3m2.c |    6 +++-
 arch/arm/mach-omap2/io.c               |    9 ++++++
 arch/arm/mach-omap2/sdrc.c             |   52 ++++++++++++++++++++++----------
 arch/arm/mach-omap2/sdrc.h             |   13 ++++++++
 arch/arm/plat-omap/sram.c              |    8 +++--
 5 files changed, 68 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
index d6e34dd..3864528 100644
--- a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
+++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
+#include <plat/cpu.h>
 #include <plat/clock.h>
 #include <plat/sram.h>
 #include <plat/sdrc.h>
@@ -45,7 +46,7 @@
  * @rate: rounded target rate
  *
  * Program the DPLL M2 divider with the rounded target rate.  Returns
- * -EINVAL upon error, or 0 upon success.
+ * -EINVAL upon error or if there's an EMIF4 submodule, or 0 upon success.
  */
 int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 {
@@ -60,6 +61,9 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 	if (!clk || !rate)
 		return -EINVAL;
 
+	if (omap3_has_sdrc_emif4())
+		return -EINVAL;
+
 	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
 	if (validrate != rate)
 		return -EINVAL;
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 065bd76..1accc90 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -450,6 +450,15 @@ void __init omap3630_init_early(void)
 
 void __init am35xx_init_early(void)
 {
+	/*
+	 * The am35x has an EMIF4 submodule in the SDRC module instead
+	 * of an SDRC submodule like other OMAP3 SoCs.  Fortunately,
+	 * the EMIF4 and SDRC submodules are at the same physical address
+	 * so we can use the SDRC mapping to access the EMIF4 submodule.
+	 * The reason for not making a separate mapping for the EMIF4 is
+	 * to avoid creating an early_cpu_is_xxx()-like call because its
+	 * too early to use cpu_is_3505/3517() or omap3_has_sdrc_emif4().
+	 */
 	omap3_init_early();
 }
 
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index e3d345f..d804065 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -24,11 +24,13 @@
 #include <linux/io.h>
 
 #include "common.h"
+#include "control.h"
 #include <plat/clock.h>
 #include <plat/sram.h>
 
 #include <plat/sdrc.h>
 #include "sdrc.h"
+#include "emif4.h"
 
 static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1;
 
@@ -136,28 +138,46 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
 			    struct omap_sdrc_params *sdrc_cs1)
 {
 	u32 l;
+	void __iomem *ctrl_base;
 
 	l = sms_read_reg(SMS_SYSCONFIG);
 	l &= ~(0x3 << 3);
 	l |= (0x2 << 3);
 	sms_write_reg(l, SMS_SYSCONFIG);
 
-	l = sdrc_read_reg(SDRC_SYSCONFIG);
-	l &= ~(0x3 << 3);
-	l |= (0x2 << 3);
-	sdrc_write_reg(l, SDRC_SYSCONFIG);
-
-	sdrc_init_params_cs0 = sdrc_cs0;
-	sdrc_init_params_cs1 = sdrc_cs1;
-
-	/* XXX Enable SRFRONIDLEREQ here also? */
-	/*
-	 * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA
-	 * can cause random memory corruption
-	 */
-	l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
-		(1 << SDRC_POWER_PAGEPOLICY_SHIFT);
-	sdrc_write_reg(l, SDRC_POWER);
+	if (omap3_has_sdrc_emif4()) {
+		l = emif4_read_reg(EMIF4_PWR_MGMT_CTRL);
+		l &= ~(0x3 << 30);
+		l |= (0x2 << 30);
+		emif4_write_reg(l, EMIF4_PWR_MGMT_CTRL);
+
+		/* Enable VTP Power Save Mode */
+		ctrl_base = omap_ctrl_base_get();
+		if (ctrl_base) {
+			l = __raw_readl(ctrl_base + AM35XX_CONTROL_DEVCONF3);
+			l &= ~(0x3 << 13);
+			l |= (0x1 << 13);
+			__raw_writel(l, ctrl_base + AM35XX_CONTROL_DEVCONF3);
+		}
+	} else {
+		l = sdrc_read_reg(SDRC_SYSCONFIG);
+		l &= ~(0x3 << 3);
+		l |= (0x2 << 3);
+		sdrc_write_reg(l, SDRC_SYSCONFIG);
+
+		sdrc_init_params_cs0 = sdrc_cs0;
+		sdrc_init_params_cs1 = sdrc_cs1;
+
+		/* XXX Enable SRFRONIDLEREQ here also? */
+		/*
+		 * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA
+		 * can cause random memory corruption
+		 */
+		l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
+			(1 << SDRC_POWER_PAGEPOLICY_SHIFT);
+		sdrc_write_reg(l, SDRC_POWER);
+	}
+
 	omap2_sms_save_context();
 }
 
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h
index b3f8379..5fb6490 100644
--- a/arch/arm/mach-omap2/sdrc.h
+++ b/arch/arm/mach-omap2/sdrc.h
@@ -25,6 +25,7 @@ extern void __iomem *omap2_sdrc_base;
 extern void __iomem *omap2_sms_base;
 
 #define OMAP_SDRC_REGADDR(reg)			(omap2_sdrc_base + (reg))
+#define OMAP_EMIF4_REGADDR(reg)			(omap2_sdrc_base + (reg))
 #define OMAP_SMS_REGADDR(reg)			(omap2_sms_base + (reg))
 
 /* SDRC global register get/set */
@@ -39,6 +40,18 @@ static inline u32 sdrc_read_reg(u16 reg)
 	return __raw_readl(OMAP_SDRC_REGADDR(reg));
 }
 
+/* EMIF4 global register get/set */
+
+static inline void emif4_write_reg(u32 val, u16 reg)
+{
+	__raw_writel(val, OMAP_EMIF4_REGADDR(reg));
+}
+
+static inline u32 emif4_read_reg(u16 reg)
+{
+	return __raw_readl(OMAP_EMIF4_REGADDR(reg));
+}
+
 /* SMS global register get/set */
 
 static inline void sms_write_reg(u32 val, u16 reg)
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index eec98af..42ccfcb 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -353,9 +353,11 @@ void omap3_sram_restore_context(void)
 {
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 
-	_omap3_sram_configure_core_dpll =
-		omap_sram_push(omap3_sram_configure_core_dpll,
-			       omap3_sram_configure_core_dpll_sz);
+	if (!omap3_has_sdrc_emif4())
+		_omap3_sram_configure_core_dpll =
+			omap_sram_push(omap3_sram_configure_core_dpll,
+				       omap3_sram_configure_core_dpll_sz);
+
 	omap_push_sram_idle();
 }
 #endif /* CONFIG_PM */
-- 
1.7.9.4

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

* [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel
  Cc: khilman, paul, Mark A. Greer, Ranjith Lohithakshan

From: "Mark A. Greer" <mgreer@animalcreek.com>

The typical SDRAM Controller Subsystem module (SDRC)
on TI OMAP3 devices has two submodules: the SDRAM Memory
Scheduler (SMS) submodule, and the SDRC submodule--the
'SDRC' acronym/term is overloaded.  The am35x family of
devices is different in that it has an EMIF4 submodule
instead of an SDRC submodule.  The SMS submodules are
similar, though.

The difference in SDRC/EMIF4 submodules is important because
omap34xx_cpu_suspend() will ultimately access the submodule's
registers and the register sets are different.  To support
the EMIF4 submodule, add the omap3_emif4_do_wfi() routine which
roughly does for the EMIF4 submodule what omap3_do_wfi() does
for the SDRC submodule.  This requires omap34xx_cpu_suspend()
to use a pointer set up in omap_push_sram_idle() so that it
jumps to the correct omap3*_do_wfi() routine in either SDRAM
or SRAM.

Credits: arch/arm/mach-omap2/sleep3517.S in TI's am35x SDK
(05.03.02.00) which appears to be authored by Ranjith Lohithakshan
<ranjithl@ti.com> was used as a reference.

CC: Ranjith Lohithakshan <ranjithl@ti.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/control.c              |    5 +-
 arch/arm/mach-omap2/emif4.h                |   24 ++++++++++
 arch/arm/mach-omap2/pm.h                   |    7 ++-
 arch/arm/mach-omap2/pm34xx.c               |   11 ++++-
 arch/arm/mach-omap2/sleep34xx.S            |   69 ++++++++++++++++++++++++++--
 arch/arm/plat-omap/include/plat/omap34xx.h |    1 +
 6 files changed, 107 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm/mach-omap2/emif4.h

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 08e674b..c659217 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -283,8 +283,9 @@ void omap3_save_scratchpad_contents(void)
 	if (cpu_is_omap3630())
 		scratchpad_contents.public_restore_ptr =
 			virt_to_phys(omap3_restore_3630);
-	else if (omap_rev() != OMAP3430_REV_ES3_0 &&
-					omap_rev() != OMAP3430_REV_ES3_1)
+	else if (omap3_has_sdrc_emif4() ||
+			(omap_rev() != OMAP3430_REV_ES3_0 &&
+			 omap_rev() != OMAP3430_REV_ES3_1))
 		scratchpad_contents.public_restore_ptr =
 			virt_to_phys(omap3_restore);
 	else
diff --git a/arch/arm/mach-omap2/emif4.h b/arch/arm/mach-omap2/emif4.h
new file mode 100644
index 0000000..0126af3
--- /dev/null
+++ b/arch/arm/mach-omap2/emif4.h
@@ -0,0 +1,24 @@
+/*
+ * SDRC Module, EMIF4 Submodule Definitions
+ *
+ * Author: Mark A. Greer <mgreer@animalcreek.com>
+ *
+ * Copyright (c) 2012 by Animal Creek Technologies, Inc.
+ *
+ * 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.
+ */
+#ifndef ____ASM_ARCH_EMIF4_H
+#define ____ASM_ARCH_EMIF4_H
+
+#ifdef __ASSEMBLER__
+
+#define OMAP34XX_EMIF4_REGADDR(reg) \
+		OMAP2_L3_IO_ADDRESS(OMAP343X_EMIF4_BASE + (reg))
+
+#endif
+
+#define EMIF4_PWR_MGMT_CTRL	0x38
+
+#endif
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 36fa90b..ab1262b 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -85,10 +85,13 @@ extern unsigned int omap24xx_cpu_suspend_sz;
 /* 3xxx */
 extern void omap34xx_cpu_suspend(int save_state);
 
-/* omap3_do_wfi function pointer and size, for copy to SRAM */
+/* omap3*_do_wfi function pointers and sizes, for copy to SRAM */
 extern void omap3_do_wfi(void);
 extern unsigned int omap3_do_wfi_sz;
-/* ... and its pointer from SRAM after copy */
+extern void omap3_emif4_do_wfi(void);
+extern unsigned int omap3_emif4_do_wfi_sz;
+/* ... and pointers when in SDRAM and in SRAM after copy */
+extern void (*omap3_do_wfi_sdram)(void);
 extern void (*omap3_do_wfi_sram)(void);
 
 /* save_secure_ram_context function pointer and size, for copy to SRAM */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 00c4abe..c1dee25 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -66,6 +66,7 @@ struct power_state {
 static LIST_HEAD(pwrst_list);
 
 static int (*_omap_save_secure_sram)(u32 *addr);
+void (*omap3_do_wfi_sdram)(void);
 void (*omap3_do_wfi_sram)(void);
 
 static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
@@ -694,7 +695,15 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
  */
 void omap_push_sram_idle(void)
 {
-	omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
+	if (omap3_has_sdrc_emif4()) {
+		omap3_do_wfi_sdram = omap3_emif4_do_wfi;
+		omap3_do_wfi_sram = omap_sram_push(omap3_emif4_do_wfi,
+				omap3_emif4_do_wfi_sz);
+	} else {
+		omap3_do_wfi_sdram = omap3_do_wfi;
+		omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi,
+				omap3_do_wfi_sz);
+	}
 
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
 		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 1f62f23..22aac4c 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -33,6 +33,7 @@
 #include "cm2xxx_3xxx.h"
 #include "prm2xxx_3xxx.h"
 #include "sdrc.h"
+#include "emif4.h"
 #include "control.h"
 
 /*
@@ -67,6 +68,8 @@
 #define SDRC_DLLA_STATUS_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
 #define SDRC_DLLA_CTRL_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
 
+#define PWR_MGMT_CTRL_V		OMAP34XX_EMIF4_REGADDR(EMIF4_PWR_MGMT_CTRL)
+
 /*
  * This file needs be built unconditionally as ARM to interoperate correctly
  * with non-Thumb-2-capable firmware.
@@ -163,8 +166,12 @@ ENTRY(omap34xx_cpu_suspend)
 	 */
 
 	/*
-	 * For OFF mode: save context and jump to WFI in SDRAM (omap3_do_wfi)
-	 * For non-OFF modes: jump to the WFI code in SRAM (omap3_do_wfi_sram)
+	 * For OFF mode: save context and jump to WFI in SDRAM
+	 * (omap3_do_wfi_sdram). For non-OFF modes: jump to the WFI code
+	 * in SRAM (omap3_do_wfi_sram).  Note that omap_push_sram_idle()
+	 * will have set omap3_do_wfi_sdram and omap3_do_wfi_sram to the
+	 * SDRAM and SRAM addresses of either omap3_do_wfi or
+	 * omap3_emif4_do_wfi depending on the type of SDRC submodule.
 	 */
 	ldr	r4, omap3_do_wfi_sram_addr
 	ldr	r5, [r4]
@@ -216,11 +223,15 @@ save_context_wfi:
  THUMB(	nop		)
 	.arm
 
-	b	omap3_do_wfi
+	ldr	r4, omap3_do_wfi_sdram_addr
+	ldr	r5, [r4]
+	bx	r5			@  jump to the WFI code in SRAM
 
 /*
  * Local variables
  */
+omap3_do_wfi_sdram_addr:
+	.word omap3_do_wfi_sdram
 omap3_do_wfi_sram_addr:
 	.word omap3_do_wfi_sram
 kernel_flush:
@@ -232,8 +243,7 @@ kernel_flush:
  */
 
 /*
- * Do WFI instruction
- * Includes the resume path for non-OFF modes
+ * Do WFI instruction (SDRC module has SDRC submodule)
  *
  * This code gets copied to internal SRAM and is accessible
  * from both SDRAM and SRAM:
@@ -391,6 +401,52 @@ wait_dll_lock_counter:
 ENTRY(omap3_do_wfi_sz)
 	.word	. - omap3_do_wfi
 
+/*
+ * Do WFI instruction (SDRC module has EMIF4 submodule)
+ *
+ * This code gets copied to internal SRAM and is accessible
+ * from both SDRAM and SRAM:
+ * - executed from SRAM for non-off modes (omap3_emif4_do_wfi_sram),
+ * - executed from SDRAM for OFF mode (omap3_emif4_do_wfi).
+ */
+	.align	3
+ENTRY(omap3_emif4_do_wfi)
+	/* Put EMIF in self-refresh */
+	ldr     r4, pwr_mgmt_ctrl
+	ldr     r5, [r4]
+	orr     r5, r5, #0x200
+	str     r5, [r4]
+
+	dsb
+	dmb
+
+	wfi
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* Take EMIF out of self-refresh */
+	ldr     r4, pwr_mgmt_ctrl
+	ldr     r5, [r4]
+	bic     r5, r5, #0x200
+	str     r5, [r4]
+
+	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
+
+pwr_mgmt_ctrl:
+	.word   PWR_MGMT_CTRL_V
+ENDPROC(omap3_emif4_do_wfi)
+ENTRY(omap3_emif4_do_wfi_sz)
+	.word	. - omap3_emif4_do_wfi
+
 
 /*
  * ==============================
@@ -564,6 +620,9 @@ l2dis_3630:
 /*
  * This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0
  * Copied to and run from SRAM in order to reconfigure the SDRC parameters.
+ *
+ * Note: Never call this routine when running on an am35x device since it
+ *  has an EMIF4 submodule instead of the standard SDRC submodule.
  */
 	.text
 	.align	3
diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
index 0d818ac..3a84520 100644
--- a/arch/arm/plat-omap/include/plat/omap34xx.h
+++ b/arch/arm/plat-omap/include/plat/omap34xx.h
@@ -42,6 +42,7 @@
 #define OMAP3430_PRM_BASE	0x48306800
 #define OMAP343X_SMS_BASE	0x6C000000
 #define OMAP343X_SDRC_BASE	0x6D000000
+#define OMAP343X_EMIF4_BASE	0x6D000000
 #define OMAP34XX_GPMC_BASE	0x6E000000
 #define OMAP343X_SCM_BASE	0x48002000
 #define OMAP343X_CTRL_BASE	OMAP343X_SCM_BASE
-- 
1.7.9.4


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

* [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

The typical SDRAM Controller Subsystem module (SDRC)
on TI OMAP3 devices has two submodules: the SDRAM Memory
Scheduler (SMS) submodule, and the SDRC submodule--the
'SDRC' acronym/term is overloaded.  The am35x family of
devices is different in that it has an EMIF4 submodule
instead of an SDRC submodule.  The SMS submodules are
similar, though.

The difference in SDRC/EMIF4 submodules is important because
omap34xx_cpu_suspend() will ultimately access the submodule's
registers and the register sets are different.  To support
the EMIF4 submodule, add the omap3_emif4_do_wfi() routine which
roughly does for the EMIF4 submodule what omap3_do_wfi() does
for the SDRC submodule.  This requires omap34xx_cpu_suspend()
to use a pointer set up in omap_push_sram_idle() so that it
jumps to the correct omap3*_do_wfi() routine in either SDRAM
or SRAM.

Credits: arch/arm/mach-omap2/sleep3517.S in TI's am35x SDK
(05.03.02.00) which appears to be authored by Ranjith Lohithakshan
<ranjithl@ti.com> was used as a reference.

CC: Ranjith Lohithakshan <ranjithl@ti.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/control.c              |    5 +-
 arch/arm/mach-omap2/emif4.h                |   24 ++++++++++
 arch/arm/mach-omap2/pm.h                   |    7 ++-
 arch/arm/mach-omap2/pm34xx.c               |   11 ++++-
 arch/arm/mach-omap2/sleep34xx.S            |   69 ++++++++++++++++++++++++++--
 arch/arm/plat-omap/include/plat/omap34xx.h |    1 +
 6 files changed, 107 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm/mach-omap2/emif4.h

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 08e674b..c659217 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -283,8 +283,9 @@ void omap3_save_scratchpad_contents(void)
 	if (cpu_is_omap3630())
 		scratchpad_contents.public_restore_ptr =
 			virt_to_phys(omap3_restore_3630);
-	else if (omap_rev() != OMAP3430_REV_ES3_0 &&
-					omap_rev() != OMAP3430_REV_ES3_1)
+	else if (omap3_has_sdrc_emif4() ||
+			(omap_rev() != OMAP3430_REV_ES3_0 &&
+			 omap_rev() != OMAP3430_REV_ES3_1))
 		scratchpad_contents.public_restore_ptr =
 			virt_to_phys(omap3_restore);
 	else
diff --git a/arch/arm/mach-omap2/emif4.h b/arch/arm/mach-omap2/emif4.h
new file mode 100644
index 0000000..0126af3
--- /dev/null
+++ b/arch/arm/mach-omap2/emif4.h
@@ -0,0 +1,24 @@
+/*
+ * SDRC Module, EMIF4 Submodule Definitions
+ *
+ * Author: Mark A. Greer <mgreer@animalcreek.com>
+ *
+ * Copyright (c) 2012 by Animal Creek Technologies, Inc.
+ *
+ * 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.
+ */
+#ifndef ____ASM_ARCH_EMIF4_H
+#define ____ASM_ARCH_EMIF4_H
+
+#ifdef __ASSEMBLER__
+
+#define OMAP34XX_EMIF4_REGADDR(reg) \
+		OMAP2_L3_IO_ADDRESS(OMAP343X_EMIF4_BASE + (reg))
+
+#endif
+
+#define EMIF4_PWR_MGMT_CTRL	0x38
+
+#endif
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 36fa90b..ab1262b 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -85,10 +85,13 @@ extern unsigned int omap24xx_cpu_suspend_sz;
 /* 3xxx */
 extern void omap34xx_cpu_suspend(int save_state);
 
-/* omap3_do_wfi function pointer and size, for copy to SRAM */
+/* omap3*_do_wfi function pointers and sizes, for copy to SRAM */
 extern void omap3_do_wfi(void);
 extern unsigned int omap3_do_wfi_sz;
-/* ... and its pointer from SRAM after copy */
+extern void omap3_emif4_do_wfi(void);
+extern unsigned int omap3_emif4_do_wfi_sz;
+/* ... and pointers when in SDRAM and in SRAM after copy */
+extern void (*omap3_do_wfi_sdram)(void);
 extern void (*omap3_do_wfi_sram)(void);
 
 /* save_secure_ram_context function pointer and size, for copy to SRAM */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 00c4abe..c1dee25 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -66,6 +66,7 @@ struct power_state {
 static LIST_HEAD(pwrst_list);
 
 static int (*_omap_save_secure_sram)(u32 *addr);
+void (*omap3_do_wfi_sdram)(void);
 void (*omap3_do_wfi_sram)(void);
 
 static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
@@ -694,7 +695,15 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
  */
 void omap_push_sram_idle(void)
 {
-	omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
+	if (omap3_has_sdrc_emif4()) {
+		omap3_do_wfi_sdram = omap3_emif4_do_wfi;
+		omap3_do_wfi_sram = omap_sram_push(omap3_emif4_do_wfi,
+				omap3_emif4_do_wfi_sz);
+	} else {
+		omap3_do_wfi_sdram = omap3_do_wfi;
+		omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi,
+				omap3_do_wfi_sz);
+	}
 
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
 		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 1f62f23..22aac4c 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -33,6 +33,7 @@
 #include "cm2xxx_3xxx.h"
 #include "prm2xxx_3xxx.h"
 #include "sdrc.h"
+#include "emif4.h"
 #include "control.h"
 
 /*
@@ -67,6 +68,8 @@
 #define SDRC_DLLA_STATUS_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
 #define SDRC_DLLA_CTRL_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
 
+#define PWR_MGMT_CTRL_V		OMAP34XX_EMIF4_REGADDR(EMIF4_PWR_MGMT_CTRL)
+
 /*
  * This file needs be built unconditionally as ARM to interoperate correctly
  * with non-Thumb-2-capable firmware.
@@ -163,8 +166,12 @@ ENTRY(omap34xx_cpu_suspend)
 	 */
 
 	/*
-	 * For OFF mode: save context and jump to WFI in SDRAM (omap3_do_wfi)
-	 * For non-OFF modes: jump to the WFI code in SRAM (omap3_do_wfi_sram)
+	 * For OFF mode: save context and jump to WFI in SDRAM
+	 * (omap3_do_wfi_sdram). For non-OFF modes: jump to the WFI code
+	 * in SRAM (omap3_do_wfi_sram).  Note that omap_push_sram_idle()
+	 * will have set omap3_do_wfi_sdram and omap3_do_wfi_sram to the
+	 * SDRAM and SRAM addresses of either omap3_do_wfi or
+	 * omap3_emif4_do_wfi depending on the type of SDRC submodule.
 	 */
 	ldr	r4, omap3_do_wfi_sram_addr
 	ldr	r5, [r4]
@@ -216,11 +223,15 @@ save_context_wfi:
  THUMB(	nop		)
 	.arm
 
-	b	omap3_do_wfi
+	ldr	r4, omap3_do_wfi_sdram_addr
+	ldr	r5, [r4]
+	bx	r5			@  jump to the WFI code in SRAM
 
 /*
  * Local variables
  */
+omap3_do_wfi_sdram_addr:
+	.word omap3_do_wfi_sdram
 omap3_do_wfi_sram_addr:
 	.word omap3_do_wfi_sram
 kernel_flush:
@@ -232,8 +243,7 @@ kernel_flush:
  */
 
 /*
- * Do WFI instruction
- * Includes the resume path for non-OFF modes
+ * Do WFI instruction (SDRC module has SDRC submodule)
  *
  * This code gets copied to internal SRAM and is accessible
  * from both SDRAM and SRAM:
@@ -391,6 +401,52 @@ wait_dll_lock_counter:
 ENTRY(omap3_do_wfi_sz)
 	.word	. - omap3_do_wfi
 
+/*
+ * Do WFI instruction (SDRC module has EMIF4 submodule)
+ *
+ * This code gets copied to internal SRAM and is accessible
+ * from both SDRAM and SRAM:
+ * - executed from SRAM for non-off modes (omap3_emif4_do_wfi_sram),
+ * - executed from SDRAM for OFF mode (omap3_emif4_do_wfi).
+ */
+	.align	3
+ENTRY(omap3_emif4_do_wfi)
+	/* Put EMIF in self-refresh */
+	ldr     r4, pwr_mgmt_ctrl
+	ldr     r5, [r4]
+	orr     r5, r5, #0x200
+	str     r5, [r4]
+
+	dsb
+	dmb
+
+	wfi
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* Take EMIF out of self-refresh */
+	ldr     r4, pwr_mgmt_ctrl
+	ldr     r5, [r4]
+	bic     r5, r5, #0x200
+	str     r5, [r4]
+
+	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
+
+pwr_mgmt_ctrl:
+	.word   PWR_MGMT_CTRL_V
+ENDPROC(omap3_emif4_do_wfi)
+ENTRY(omap3_emif4_do_wfi_sz)
+	.word	. - omap3_emif4_do_wfi
+
 
 /*
  * ==============================
@@ -564,6 +620,9 @@ l2dis_3630:
 /*
  * This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0
  * Copied to and run from SRAM in order to reconfigure the SDRC parameters.
+ *
+ * Note: Never call this routine when running on an am35x device since it
+ *  has an EMIF4 submodule instead of the standard SDRC submodule.
  */
 	.text
 	.align	3
diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
index 0d818ac..3a84520 100644
--- a/arch/arm/plat-omap/include/plat/omap34xx.h
+++ b/arch/arm/plat-omap/include/plat/omap34xx.h
@@ -42,6 +42,7 @@
 #define OMAP3430_PRM_BASE	0x48306800
 #define OMAP343X_SMS_BASE	0x6C000000
 #define OMAP343X_SDRC_BASE	0x6D000000
+#define OMAP343X_EMIF4_BASE	0x6D000000
 #define OMAP34XX_GPMC_BASE	0x6E000000
 #define OMAP343X_SCM_BASE	0x48002000
 #define OMAP343X_CTRL_BASE	OMAP343X_SCM_BASE
-- 
1.7.9.4

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

* [PATCH 12/12] arm: omap3: am35x: Register davinci_mdio before davinci_emac
  2012-04-11 19:05 ` Mark A. Greer
@ 2012-04-11 19:05   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel; +Cc: khilman, paul, Mark A. Greer

From: "Mark A. Greer" <mgreer@animalcreek.com>

Problem:
--------
When resuming from a Suspend-to-RAM event, the eth0 device
(davinci emac/mdio) on am35xx boards wouldn't work and the
following error message appeared on the console:

"net eth0: could not connect to phy davinci_mdio-0:00"

Cause:
------
When davinci_emac_resume() calls emac_dev_open() which
ultimately calls davinci_mdio_read(), the 'data->suspended'
flag in davinci_mdio.c is still set to 'true'.  This causes
davinci_mdio_read() to fail which ripples back up the call
chain causing davinci_emac_resume() to fail.  The reason
'data->suspended' is still set to 'true' is that
davinci_mdio_resume() hasn't been called yet as it should
have been.  davinci_mdio_resume() must be called before
davinci_emac_resume().

Solution:
---------
Register the "davinci_mdio" platform device before registering
the "davinci_emac" platform device so davinci_mdio_resume()
is called before davinci_emac_resume() and eth0 can resume.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/am35xx-emac.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
index 1f97e74..d23bd6c 100644
--- a/arch/arm/mach-omap2/am35xx-emac.c
+++ b/arch/arm/mach-omap2/am35xx-emac.c
@@ -97,11 +97,6 @@ void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
 
 	am35xx_emac_pdata.rmii_en = rmii_en;
 	am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq;
-	err = platform_device_register(&am35xx_emac_device);
-	if (err) {
-		pr_err("AM35x: failed registering EMAC device: %d\n", err);
-		return;
-	}
 
 	err = platform_device_register(&am35xx_emac_mdio_device);
 	if (err) {
@@ -110,6 +105,12 @@ void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
 		return;
 	}
 
+	err = platform_device_register(&am35xx_emac_device);
+	if (err) {
+		pr_err("AM35x: failed registering EMAC device: %d\n", err);
+		return;
+	}
+
 	regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
 	regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
 	omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
-- 
1.7.9.4


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

* [PATCH 12/12] arm: omap3: am35x: Register davinci_mdio before davinci_emac
@ 2012-04-11 19:05   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: "Mark A. Greer" <mgreer@animalcreek.com>

Problem:
--------
When resuming from a Suspend-to-RAM event, the eth0 device
(davinci emac/mdio) on am35xx boards wouldn't work and the
following error message appeared on the console:

"net eth0: could not connect to phy davinci_mdio-0:00"

Cause:
------
When davinci_emac_resume() calls emac_dev_open() which
ultimately calls davinci_mdio_read(), the 'data->suspended'
flag in davinci_mdio.c is still set to 'true'.  This causes
davinci_mdio_read() to fail which ripples back up the call
chain causing davinci_emac_resume() to fail.  The reason
'data->suspended' is still set to 'true' is that
davinci_mdio_resume() hasn't been called yet as it should
have been.  davinci_mdio_resume() must be called before
davinci_emac_resume().

Solution:
---------
Register the "davinci_mdio" platform device before registering
the "davinci_emac" platform device so davinci_mdio_resume()
is called before davinci_emac_resume() and eth0 can resume.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/am35xx-emac.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
index 1f97e74..d23bd6c 100644
--- a/arch/arm/mach-omap2/am35xx-emac.c
+++ b/arch/arm/mach-omap2/am35xx-emac.c
@@ -97,11 +97,6 @@ void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
 
 	am35xx_emac_pdata.rmii_en = rmii_en;
 	am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq;
-	err = platform_device_register(&am35xx_emac_device);
-	if (err) {
-		pr_err("AM35x: failed registering EMAC device: %d\n", err);
-		return;
-	}
 
 	err = platform_device_register(&am35xx_emac_mdio_device);
 	if (err) {
@@ -110,6 +105,12 @@ void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
 		return;
 	}
 
+	err = platform_device_register(&am35xx_emac_device);
+	if (err) {
+		pr_err("AM35x: failed registering EMAC device: %d\n", err);
+		return;
+	}
+
 	regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
 	regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
 	omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
-- 
1.7.9.4

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

* Re: [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 20:56     ` Jean Pihet
  -1 siblings, 0 replies; 126+ messages in thread
From: Jean Pihet @ 2012-04-11 20:56 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman, paul

Hi Mark,

On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> From: "Mark A. Greer" <mgreer@animalcreek.com>
>
> The am35x family of SoCs only support PWRDM_POWER_ON
> and PWRDM_POWER_INACTIVE power states. This causes
> an issue in some areas of the OMAP3 power-related
> code because of assumptions that PWRDM_POWER_RET
> and/or PWRDM_POWER_OFF are always valid states.
>
> To get am35x SoCs to work properly, add missing support
> for PWRDM_POWER_INACTIVE and remove assumptions that
> PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
introduce the power domains functional states' [1] which I think
should be used to base your patches on. This patch set introduces
functional states for the power domains power ans logic states, and
the conversion functions between the internal power and logic states
and the functional states.

I would be glad to help on the AM35x support for the functional states.

What do you think?

[1] http://marc.info/?l=linux-omap&m=133417729712693&w=2

Regards,
Jean

> ---
>  arch/arm/mach-omap2/cpuidle34xx.c |   29 +++++++++++++++++++++++--
>  arch/arm/mach-omap2/pm-debug.c    |    8 +++++--
>  arch/arm/mach-omap2/pm34xx.c      |   43 +++++++++++++++++++++++--------------
>  3 files changed, 60 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 12cf81d..187872a 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -175,12 +175,23 @@ static int next_valid_state(struct cpuidle_device *dev,
>        struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
>        struct cpuidle_state *curr = &drv->states[index];
>        struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
> -       u32 mpu_deepest_state = PWRDM_POWER_RET;
> -       u32 core_deepest_state = PWRDM_POWER_RET;
> +       u32 mpu_deepest_state;
> +       u32 core_deepest_state;
>        int next_index = -1;
>
> +       if (omap3_has_pwroff()) {
> +               mpu_deepest_state = PWRDM_POWER_RET;
> +               core_deepest_state = PWRDM_POWER_RET;
> +       } else {
> +               mpu_deepest_state = PWRDM_POWER_INACTIVE;
> +               core_deepest_state = PWRDM_POWER_INACTIVE;
> +       }
> +
>        if (enable_off_mode) {
> +               WARN_ON(!omap3_has_pwroff());
> +
>                mpu_deepest_state = PWRDM_POWER_OFF;
> +
>                /*
>                 * Erratum i583: valable for ES rev < Es1.2 on 3630.
>                 * CORE OFF mode is not supported in a stable form, restrict
> @@ -311,6 +322,9 @@ void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
>                        cpuidle_board_params[i].exit_latency;
>                cpuidle_params_table[i].target_residency =
>                        cpuidle_board_params[i].target_residency;
> +
> +               WARN_ON(!omap3_has_pwroff() && (i >= 2) &&
> +                               cpuidle_params_table[i].valid);
>        }
>        return;
>  }
> @@ -349,6 +363,16 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage(
>        return cx;
>  }
>
> +/* Only C1 & C2 C states valid when RET & OFF states aren't supported */
> +static void omap3_cstate_valid_fixup(void)
> +{
> +       int idx;
> +
> +       if (!omap3_has_pwroff())
> +               for (idx = 2; idx < OMAP3_NUM_STATES; idx++)
> +                       cpuidle_params_table[idx].valid = 0;
> +}
> +
>  /**
>  * omap3_idle_init - Init routine for OMAP3 idle
>  *
> @@ -366,6 +390,7 @@ int __init omap3_idle_init(void)
>        per_pd = pwrdm_lookup("per_pwrdm");
>        cam_pd = pwrdm_lookup("cam_pwrdm");
>
> +       omap3_cstate_valid_fixup();
>
>        drv->safe_state_index = -1;
>        dev = &per_cpu(omap3_idle_dev, smp_processor_id());
> diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
> index 814bcd9..339ed42 100644
> --- a/arch/arm/mach-omap2/pm-debug.c
> +++ b/arch/arm/mach-omap2/pm-debug.c
> @@ -239,19 +239,23 @@ static int option_get(void *data, u64 *val)
>  static int option_set(void *data, u64 val)
>  {
>        u32 *option = data;
> +       int ret = -EINVAL;
>
>        *option = val;
>
> -       if (option == &enable_off_mode) {
> +       if (omap3_has_pwroff() && (option == &enable_off_mode)) {
>                if (val)
>                        omap_pm_enable_off_mode();
>                else
>                        omap_pm_disable_off_mode();
> +
>                if (cpu_is_omap34xx())
>                        omap3_pm_off_mode_enable(val);
> +
> +               ret = 0;
>        }
>
> -       return 0;
> +       return ret;
>  }
>
>  DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index b7bbcee..00c4abe 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -279,6 +279,7 @@ void omap_sram_idle(void)
>        mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
>        switch (mpu_next_state) {
>        case PWRDM_POWER_ON:
> +       case PWRDM_POWER_INACTIVE:
>        case PWRDM_POWER_RET:
>                /* No need to save context */
>                save_state = 0;
> @@ -614,6 +615,8 @@ void omap3_pm_off_mode_enable(int enable)
>        struct power_state *pwrst;
>        u32 state;
>
> +       WARN_ON(!omap3_has_pwroff());
> +
>        if (enable)
>                state = PWRDM_POWER_OFF;
>        else
> @@ -668,7 +671,12 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
>        if (!pwrst)
>                return -ENOMEM;
>        pwrst->pwrdm = pwrdm;
> -       pwrst->next_state = PWRDM_POWER_RET;
> +
> +       if (omap3_has_pwroff())
> +               pwrst->next_state = PWRDM_POWER_RET;
> +       else
> +               pwrst->next_state = PWRDM_POWER_INACTIVE;
> +
>        list_add(&pwrst->node, &pwrst_list);
>
>        if (pwrdm_has_hdwr_sar(pwrdm))
> @@ -781,25 +789,28 @@ static int __init omap3_pm_init(void)
>                omap3630_ctrl_disable_rta();
>
>        clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
> -       if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
> -               omap3_secure_ram_storage =
> -                       kmalloc(0x803F, GFP_KERNEL);
> -               if (!omap3_secure_ram_storage)
> -                       pr_err("Memory allocation failed when "
> -                              "allocating for secure sram context\n");
>
> -               local_irq_disable();
> -               local_fiq_disable();
> +       if (omap3_has_pwroff()) {
> +               if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
> +                       omap3_secure_ram_storage =
> +                               kmalloc(0x803F, GFP_KERNEL);
> +                       if (!omap3_secure_ram_storage)
> +                               pr_err("Memory allocation failed when "
> +                                      "allocating for secure sram context\n");
>
> -               omap_dma_global_context_save();
> -               omap3_save_secure_ram_context();
> -               omap_dma_global_context_restore();
> +                       local_irq_disable();
> +                       local_fiq_disable();
>
> -               local_irq_enable();
> -               local_fiq_enable();
> -       }
> +                       omap_dma_global_context_save();
> +                       omap3_save_secure_ram_context();
> +                       omap_dma_global_context_restore();
> +
> +                       local_irq_enable();
> +                       local_fiq_enable();
>
> -       omap3_save_scratchpad_contents();
> +                       omap3_save_scratchpad_contents();
> +               }
> +       }
>        return ret;
>
>  err3:
> --
> 1.7.9.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
--
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 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
@ 2012-04-11 20:56     ` Jean Pihet
  0 siblings, 0 replies; 126+ messages in thread
From: Jean Pihet @ 2012-04-11 20:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> From: "Mark A. Greer" <mgreer@animalcreek.com>
>
> The am35x family of SoCs only support PWRDM_POWER_ON
> and PWRDM_POWER_INACTIVE power states. This causes
> an issue in some areas of the OMAP3 power-related
> code because of assumptions that PWRDM_POWER_RET
> and/or PWRDM_POWER_OFF are always valid states.
>
> To get am35x SoCs to work properly, add missing support
> for PWRDM_POWER_INACTIVE and remove assumptions that
> PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
introduce the power domains functional states' [1] which I think
should be used to base your patches on. This patch set introduces
functional states for the power domains power ans logic states, and
the conversion functions between the internal power and logic states
and the functional states.

I would be glad to help on the AM35x support for the functional states.

What do you think?

[1] http://marc.info/?l=linux-omap&m=133417729712693&w=2

Regards,
Jean

> ---
> ?arch/arm/mach-omap2/cpuidle34xx.c | ? 29 +++++++++++++++++++++++--
> ?arch/arm/mach-omap2/pm-debug.c ? ?| ? ?8 +++++--
> ?arch/arm/mach-omap2/pm34xx.c ? ? ?| ? 43 +++++++++++++++++++++++--------------
> ?3 files changed, 60 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 12cf81d..187872a 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -175,12 +175,23 @@ static int next_valid_state(struct cpuidle_device *dev,
> ? ? ? ?struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
> ? ? ? ?struct cpuidle_state *curr = &drv->states[index];
> ? ? ? ?struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
> - ? ? ? u32 mpu_deepest_state = PWRDM_POWER_RET;
> - ? ? ? u32 core_deepest_state = PWRDM_POWER_RET;
> + ? ? ? u32 mpu_deepest_state;
> + ? ? ? u32 core_deepest_state;
> ? ? ? ?int next_index = -1;
>
> + ? ? ? if (omap3_has_pwroff()) {
> + ? ? ? ? ? ? ? mpu_deepest_state = PWRDM_POWER_RET;
> + ? ? ? ? ? ? ? core_deepest_state = PWRDM_POWER_RET;
> + ? ? ? } else {
> + ? ? ? ? ? ? ? mpu_deepest_state = PWRDM_POWER_INACTIVE;
> + ? ? ? ? ? ? ? core_deepest_state = PWRDM_POWER_INACTIVE;
> + ? ? ? }
> +
> ? ? ? ?if (enable_off_mode) {
> + ? ? ? ? ? ? ? WARN_ON(!omap3_has_pwroff());
> +
> ? ? ? ? ? ? ? ?mpu_deepest_state = PWRDM_POWER_OFF;
> +
> ? ? ? ? ? ? ? ?/*
> ? ? ? ? ? ? ? ? * Erratum i583: valable for ES rev < Es1.2 on 3630.
> ? ? ? ? ? ? ? ? * CORE OFF mode is not supported in a stable form, restrict
> @@ -311,6 +322,9 @@ void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
> ? ? ? ? ? ? ? ? ? ? ? ?cpuidle_board_params[i].exit_latency;
> ? ? ? ? ? ? ? ?cpuidle_params_table[i].target_residency =
> ? ? ? ? ? ? ? ? ? ? ? ?cpuidle_board_params[i].target_residency;
> +
> + ? ? ? ? ? ? ? WARN_ON(!omap3_has_pwroff() && (i >= 2) &&
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cpuidle_params_table[i].valid);
> ? ? ? ?}
> ? ? ? ?return;
> ?}
> @@ -349,6 +363,16 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage(
> ? ? ? ?return cx;
> ?}
>
> +/* Only C1 & C2 C states valid when RET & OFF states aren't supported */
> +static void omap3_cstate_valid_fixup(void)
> +{
> + ? ? ? int idx;
> +
> + ? ? ? if (!omap3_has_pwroff())
> + ? ? ? ? ? ? ? for (idx = 2; idx < OMAP3_NUM_STATES; idx++)
> + ? ? ? ? ? ? ? ? ? ? ? cpuidle_params_table[idx].valid = 0;
> +}
> +
> ?/**
> ?* omap3_idle_init - Init routine for OMAP3 idle
> ?*
> @@ -366,6 +390,7 @@ int __init omap3_idle_init(void)
> ? ? ? ?per_pd = pwrdm_lookup("per_pwrdm");
> ? ? ? ?cam_pd = pwrdm_lookup("cam_pwrdm");
>
> + ? ? ? omap3_cstate_valid_fixup();
>
> ? ? ? ?drv->safe_state_index = -1;
> ? ? ? ?dev = &per_cpu(omap3_idle_dev, smp_processor_id());
> diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
> index 814bcd9..339ed42 100644
> --- a/arch/arm/mach-omap2/pm-debug.c
> +++ b/arch/arm/mach-omap2/pm-debug.c
> @@ -239,19 +239,23 @@ static int option_get(void *data, u64 *val)
> ?static int option_set(void *data, u64 val)
> ?{
> ? ? ? ?u32 *option = data;
> + ? ? ? int ret = -EINVAL;
>
> ? ? ? ?*option = val;
>
> - ? ? ? if (option == &enable_off_mode) {
> + ? ? ? if (omap3_has_pwroff() && (option == &enable_off_mode)) {
> ? ? ? ? ? ? ? ?if (val)
> ? ? ? ? ? ? ? ? ? ? ? ?omap_pm_enable_off_mode();
> ? ? ? ? ? ? ? ?else
> ? ? ? ? ? ? ? ? ? ? ? ?omap_pm_disable_off_mode();
> +
> ? ? ? ? ? ? ? ?if (cpu_is_omap34xx())
> ? ? ? ? ? ? ? ? ? ? ? ?omap3_pm_off_mode_enable(val);
> +
> + ? ? ? ? ? ? ? ret = 0;
> ? ? ? ?}
>
> - ? ? ? return 0;
> + ? ? ? return ret;
> ?}
>
> ?DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index b7bbcee..00c4abe 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -279,6 +279,7 @@ void omap_sram_idle(void)
> ? ? ? ?mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
> ? ? ? ?switch (mpu_next_state) {
> ? ? ? ?case PWRDM_POWER_ON:
> + ? ? ? case PWRDM_POWER_INACTIVE:
> ? ? ? ?case PWRDM_POWER_RET:
> ? ? ? ? ? ? ? ?/* No need to save context */
> ? ? ? ? ? ? ? ?save_state = 0;
> @@ -614,6 +615,8 @@ void omap3_pm_off_mode_enable(int enable)
> ? ? ? ?struct power_state *pwrst;
> ? ? ? ?u32 state;
>
> + ? ? ? WARN_ON(!omap3_has_pwroff());
> +
> ? ? ? ?if (enable)
> ? ? ? ? ? ? ? ?state = PWRDM_POWER_OFF;
> ? ? ? ?else
> @@ -668,7 +671,12 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
> ? ? ? ?if (!pwrst)
> ? ? ? ? ? ? ? ?return -ENOMEM;
> ? ? ? ?pwrst->pwrdm = pwrdm;
> - ? ? ? pwrst->next_state = PWRDM_POWER_RET;
> +
> + ? ? ? if (omap3_has_pwroff())
> + ? ? ? ? ? ? ? pwrst->next_state = PWRDM_POWER_RET;
> + ? ? ? else
> + ? ? ? ? ? ? ? pwrst->next_state = PWRDM_POWER_INACTIVE;
> +
> ? ? ? ?list_add(&pwrst->node, &pwrst_list);
>
> ? ? ? ?if (pwrdm_has_hdwr_sar(pwrdm))
> @@ -781,25 +789,28 @@ static int __init omap3_pm_init(void)
> ? ? ? ? ? ? ? ?omap3630_ctrl_disable_rta();
>
> ? ? ? ?clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
> - ? ? ? if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
> - ? ? ? ? ? ? ? omap3_secure_ram_storage =
> - ? ? ? ? ? ? ? ? ? ? ? kmalloc(0x803F, GFP_KERNEL);
> - ? ? ? ? ? ? ? if (!omap3_secure_ram_storage)
> - ? ? ? ? ? ? ? ? ? ? ? pr_err("Memory allocation failed when "
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"allocating for secure sram context\n");
>
> - ? ? ? ? ? ? ? local_irq_disable();
> - ? ? ? ? ? ? ? local_fiq_disable();
> + ? ? ? if (omap3_has_pwroff()) {
> + ? ? ? ? ? ? ? if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
> + ? ? ? ? ? ? ? ? ? ? ? omap3_secure_ram_storage =
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? kmalloc(0x803F, GFP_KERNEL);
> + ? ? ? ? ? ? ? ? ? ? ? if (!omap3_secure_ram_storage)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pr_err("Memory allocation failed when "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"allocating for secure sram context\n");
>
> - ? ? ? ? ? ? ? omap_dma_global_context_save();
> - ? ? ? ? ? ? ? omap3_save_secure_ram_context();
> - ? ? ? ? ? ? ? omap_dma_global_context_restore();
> + ? ? ? ? ? ? ? ? ? ? ? local_irq_disable();
> + ? ? ? ? ? ? ? ? ? ? ? local_fiq_disable();
>
> - ? ? ? ? ? ? ? local_irq_enable();
> - ? ? ? ? ? ? ? local_fiq_enable();
> - ? ? ? }
> + ? ? ? ? ? ? ? ? ? ? ? omap_dma_global_context_save();
> + ? ? ? ? ? ? ? ? ? ? ? omap3_save_secure_ram_context();
> + ? ? ? ? ? ? ? ? ? ? ? omap_dma_global_context_restore();
> +
> + ? ? ? ? ? ? ? ? ? ? ? local_irq_enable();
> + ? ? ? ? ? ? ? ? ? ? ? local_fiq_enable();
>
> - ? ? ? omap3_save_scratchpad_contents();
> + ? ? ? ? ? ? ? ? ? ? ? omap3_save_scratchpad_contents();
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> ? ? ? ?return ret;
>
> ?err3:
> --
> 1.7.9.4
>
> --
> 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 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
  2012-04-11 20:56     ` Jean Pihet
@ 2012-04-11 21:08       ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:08 UTC (permalink / raw)
  To: Jean Pihet; +Cc: Mark A. Greer, linux-omap, linux-arm-kernel, khilman

Hi

On Wed, 11 Apr 2012, Jean Pihet wrote:

> On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > The am35x family of SoCs only support PWRDM_POWER_ON
> > and PWRDM_POWER_INACTIVE power states. This causes
> > an issue in some areas of the OMAP3 power-related
> > code because of assumptions that PWRDM_POWER_RET
> > and/or PWRDM_POWER_OFF are always valid states.
> >
> > To get am35x SoCs to work properly, add missing support
> > for PWRDM_POWER_INACTIVE and remove assumptions that
> > PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
> >
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
> introduce the power domains functional states' [1] which I think
> should be used to base your patches on. This patch set introduces
> functional states for the power domains power ans logic states, and
> the conversion functions between the internal power and logic states
> and the functional states.
> 
> I would be glad to help on the AM35x support for the functional states.

Since it might take a while for the functional powerstate code to go 
upstream, if Mark wants to do this, I'd suggest that he split the
powerdomain-specific patches off from the rest of his series.  This should 
avoid blocking the rest of his patches on the infrastructure changes.

- Paul

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

* [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
@ 2012-04-11 21:08       ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Wed, 11 Apr 2012, Jean Pihet wrote:

> On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > The am35x family of SoCs only support PWRDM_POWER_ON
> > and PWRDM_POWER_INACTIVE power states. This causes
> > an issue in some areas of the OMAP3 power-related
> > code because of assumptions that PWRDM_POWER_RET
> > and/or PWRDM_POWER_OFF are always valid states.
> >
> > To get am35x SoCs to work properly, add missing support
> > for PWRDM_POWER_INACTIVE and remove assumptions that
> > PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
> >
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
> introduce the power domains functional states' [1] which I think
> should be used to base your patches on. This patch set introduces
> functional states for the power domains power ans logic states, and
> the conversion functions between the internal power and logic states
> and the functional states.
> 
> I would be glad to help on the AM35x support for the functional states.

Since it might take a while for the functional powerstate code to go 
upstream, if Mark wants to do this, I'd suggest that he split the
powerdomain-specific patches off from the rest of his series.  This should 
avoid blocking the rest of his patches on the infrastructure changes.

- Paul

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

* Re: [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
  2012-04-11 20:56     ` Jean Pihet
@ 2012-04-11 21:12       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 21:12 UTC (permalink / raw)
  To: Jean Pihet; +Cc: linux-omap, linux-arm-kernel, khilman, paul

On Wed, Apr 11, 2012 at 10:56:01PM +0200, Jean Pihet wrote:
> Hi Mark,
> 
> On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > The am35x family of SoCs only support PWRDM_POWER_ON
> > and PWRDM_POWER_INACTIVE power states. This causes
> > an issue in some areas of the OMAP3 power-related
> > code because of assumptions that PWRDM_POWER_RET
> > and/or PWRDM_POWER_OFF are always valid states.
> >
> > To get am35x SoCs to work properly, add missing support
> > for PWRDM_POWER_INACTIVE and remove assumptions that
> > PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
> >
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
> introduce the power domains functional states' [1] which I think
> should be used to base your patches on. This patch set introduces
> functional states for the power domains power ans logic states, and
> the conversion functions between the internal power and logic states
> and the functional states.
> 
> I would be glad to help on the AM35x support for the functional states.
> 
> What do you think?

Sure.  Sounds like the right thing to do.

> [1] http://marc.info/?l=linux-omap&m=133417729712693&w=2

Thanks for the pointer.  I'll do a little research and contact you
out-of-band.

Mark
--

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

* [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
@ 2012-04-11 21:12       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 21:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 10:56:01PM +0200, Jean Pihet wrote:
> Hi Mark,
> 
> On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > The am35x family of SoCs only support PWRDM_POWER_ON
> > and PWRDM_POWER_INACTIVE power states. This causes
> > an issue in some areas of the OMAP3 power-related
> > code because of assumptions that PWRDM_POWER_RET
> > and/or PWRDM_POWER_OFF are always valid states.
> >
> > To get am35x SoCs to work properly, add missing support
> > for PWRDM_POWER_INACTIVE and remove assumptions that
> > PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
> >
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
> introduce the power domains functional states' [1] which I think
> should be used to base your patches on. This patch set introduces
> functional states for the power domains power ans logic states, and
> the conversion functions between the internal power and logic states
> and the functional states.
> 
> I would be glad to help on the AM35x support for the functional states.
> 
> What do you think?

Sure.  Sounds like the right thing to do.

> [1] http://marc.info/?l=linux-omap&m=133417729712693&w=2

Thanks for the pointer.  I'll do a little research and contact you
out-of-band.

Mark
--

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

* Re: [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
  2012-04-11 21:08       ` Paul Walmsley
@ 2012-04-11 21:14         ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 21:14 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: Jean Pihet, linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 03:08:54PM -0600, Paul Walmsley wrote:
> Hi
> 
> On Wed, 11 Apr 2012, Jean Pihet wrote:
> 
> > On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> > > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > >
> > > The am35x family of SoCs only support PWRDM_POWER_ON
> > > and PWRDM_POWER_INACTIVE power states. This causes
> > > an issue in some areas of the OMAP3 power-related
> > > code because of assumptions that PWRDM_POWER_RET
> > > and/or PWRDM_POWER_OFF are always valid states.
> > >
> > > To get am35x SoCs to work properly, add missing support
> > > for PWRDM_POWER_INACTIVE and remove assumptions that
> > > PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
> > >
> > > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> > 
> > I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
> > introduce the power domains functional states' [1] which I think
> > should be used to base your patches on. This patch set introduces
> > functional states for the power domains power ans logic states, and
> > the conversion functions between the internal power and logic states
> > and the functional states.
> > 
> > I would be glad to help on the AM35x support for the functional states.
> 
> Since it might take a while for the functional powerstate code to go 
> upstream, if Mark wants to do this, I'd suggest that he split the
> powerdomain-specific patches off from the rest of his series.  This should 
> avoid blocking the rest of his patches on the infrastructure changes.

Another good idea.  I'll do the split in another day or so in case there
are more comments I can address when I respin & separate the patches.

Mark
--

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

* [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
@ 2012-04-11 21:14         ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 21:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:08:54PM -0600, Paul Walmsley wrote:
> Hi
> 
> On Wed, 11 Apr 2012, Jean Pihet wrote:
> 
> > On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> > > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > >
> > > The am35x family of SoCs only support PWRDM_POWER_ON
> > > and PWRDM_POWER_INACTIVE power states. This causes
> > > an issue in some areas of the OMAP3 power-related
> > > code because of assumptions that PWRDM_POWER_RET
> > > and/or PWRDM_POWER_OFF are always valid states.
> > >
> > > To get am35x SoCs to work properly, add missing support
> > > for PWRDM_POWER_INACTIVE and remove assumptions that
> > > PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
> > >
> > > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> > 
> > I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
> > introduce the power domains functional states' [1] which I think
> > should be used to base your patches on. This patch set introduces
> > functional states for the power domains power ans logic states, and
> > the conversion functions between the internal power and logic states
> > and the functional states.
> > 
> > I would be glad to help on the AM35x support for the functional states.
> 
> Since it might take a while for the functional powerstate code to go 
> upstream, if Mark wants to do this, I'd suggest that he split the
> powerdomain-specific patches off from the rest of his series.  This should 
> avoid blocking the rest of his patches on the infrastructure changes.

Another good idea.  I'll do the split in another day or so in case there
are more comments I can address when I respin & separate the patches.

Mark
--

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

* Re: [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
  2012-04-11 21:14         ` Mark A. Greer
@ 2012-04-11 21:15           ` Jean Pihet
  -1 siblings, 0 replies; 126+ messages in thread
From: Jean Pihet @ 2012-04-11 21:15 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: Paul Walmsley, linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 11:14 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> On Wed, Apr 11, 2012 at 03:08:54PM -0600, Paul Walmsley wrote:
>> Hi
>>
>> On Wed, 11 Apr 2012, Jean Pihet wrote:
>>
>> > On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
>> > > From: "Mark A. Greer" <mgreer@animalcreek.com>
>> > >
>> > > The am35x family of SoCs only support PWRDM_POWER_ON
>> > > and PWRDM_POWER_INACTIVE power states. This causes
>> > > an issue in some areas of the OMAP3 power-related
>> > > code because of assumptions that PWRDM_POWER_RET
>> > > and/or PWRDM_POWER_OFF are always valid states.
>> > >
>> > > To get am35x SoCs to work properly, add missing support
>> > > for PWRDM_POWER_INACTIVE and remove assumptions that
>> > > PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
>> > >
>> > > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
>> >
>> > I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
>> > introduce the power domains functional states' [1] which I think
>> > should be used to base your patches on. This patch set introduces
>> > functional states for the power domains power ans logic states, and
>> > the conversion functions between the internal power and logic states
>> > and the functional states.
>> >
>> > I would be glad to help on the AM35x support for the functional states.
>>
>> Since it might take a while for the functional powerstate code to go
>> upstream, if Mark wants to do this, I'd suggest that he split the
>> powerdomain-specific patches off from the rest of his series.  This should
>> avoid blocking the rest of his patches on the infrastructure changes.
>
> Another good idea.  I'll do the split in another day or so in case there
> are more comments I can address when I respin & separate the patches.
Sounds great!

Regards,
Jean

>
> Mark
> --
--
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 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
@ 2012-04-11 21:15           ` Jean Pihet
  0 siblings, 0 replies; 126+ messages in thread
From: Jean Pihet @ 2012-04-11 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 11:14 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> On Wed, Apr 11, 2012 at 03:08:54PM -0600, Paul Walmsley wrote:
>> Hi
>>
>> On Wed, 11 Apr 2012, Jean Pihet wrote:
>>
>> > On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
>> > > From: "Mark A. Greer" <mgreer@animalcreek.com>
>> > >
>> > > The am35x family of SoCs only support PWRDM_POWER_ON
>> > > and PWRDM_POWER_INACTIVE power states. This causes
>> > > an issue in some areas of the OMAP3 power-related
>> > > code because of assumptions that PWRDM_POWER_RET
>> > > and/or PWRDM_POWER_OFF are always valid states.
>> > >
>> > > To get am35x SoCs to work properly, add missing support
>> > > for PWRDM_POWER_INACTIVE and remove assumptions that
>> > > PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
>> > >
>> > > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
>> >
>> > I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
>> > introduce the power domains functional states' [1] which I think
>> > should be used to base your patches on. This patch set introduces
>> > functional states for the power domains power ans logic states, and
>> > the conversion functions between the internal power and logic states
>> > and the functional states.
>> >
>> > I would be glad to help on the AM35x support for the functional states.
>>
>> Since it might take a while for the functional powerstate code to go
>> upstream, if Mark wants to do this, I'd suggest that he split the
>> powerdomain-specific patches off from the rest of his series. ?This should
>> avoid blocking the rest of his patches on the infrastructure changes.
>
> Another good idea. ?I'll do the split in another day or so in case there
> are more comments I can address when I respin & separate the patches.
Sounds great!

Regards,
Jean

>
> Mark
> --

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

* Re: [PATCH 12/12] arm: omap3: am35x: Register davinci_mdio before davinci_emac
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 21:24     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:24 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman, Ilya Yanok

cc Ilya

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> Problem:
> --------
> When resuming from a Suspend-to-RAM event, the eth0 device
> (davinci emac/mdio) on am35xx boards wouldn't work and the
> following error message appeared on the console:
> 
> "net eth0: could not connect to phy davinci_mdio-0:00"

...

> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/am35xx-emac.c |   11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
> index 1f97e74..d23bd6c 100644
> --- a/arch/arm/mach-omap2/am35xx-emac.c
> +++ b/arch/arm/mach-omap2/am35xx-emac.c

This is a little off-topic from this patch, but we should get rid of this 
arch/arm/mach-omap2/am35xx-emac.c file.  These on-chip devices should be 
registered via the hwmod code.  Looking at 
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c, I don't see any trace of the 
EMAC or MDIO in there.  That's where all of these IPSS IP blocks should be 
declared...


- Paul

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

* [PATCH 12/12] arm: omap3: am35x: Register davinci_mdio before davinci_emac
@ 2012-04-11 21:24     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:24 UTC (permalink / raw)
  To: linux-arm-kernel

cc Ilya

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> Problem:
> --------
> When resuming from a Suspend-to-RAM event, the eth0 device
> (davinci emac/mdio) on am35xx boards wouldn't work and the
> following error message appeared on the console:
> 
> "net eth0: could not connect to phy davinci_mdio-0:00"

...

> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/am35xx-emac.c |   11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
> index 1f97e74..d23bd6c 100644
> --- a/arch/arm/mach-omap2/am35xx-emac.c
> +++ b/arch/arm/mach-omap2/am35xx-emac.c

This is a little off-topic from this patch, but we should get rid of this 
arch/arm/mach-omap2/am35xx-emac.c file.  These on-chip devices should be 
registered via the hwmod code.  Looking at 
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c, I don't see any trace of the 
EMAC or MDIO in there.  That's where all of these IPSS IP blocks should be 
declared...


- Paul

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

* Re: [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 21:29     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:29 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

Hi

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The typical SDRAM Controller Subsystem module (SDRC)
> on TI OMAP3 devices has two submodules: the SDRAM Memory
> Scheduler (SMS) submodule, and the SDRC submodule--the
> 'SDRC' acronym/term is overloaded.  The am35x family of
> devices is different in that it has an EMIF4 submodule
> instead of an SDRC submodule.  The SMS submodules are
> similar, though.
> 
> To allow code to determine whether the current device has an
> SDRC submodule or and EMIF4 submodule, add the 'OMAP3_HAS_SDRC_EMIF4'
> feature and set it when running on an am35x SoC.
> 
> So when:
> - omap3_has_sdrc() returns true: the system has an SDRC module
> 	consisting of an SMS submodule and either an SDRC submodule
> 	or an EMIF4 submodule.
> - omap3_has_sdrc_emif4() returns true: the system has an EMIF4
> 	submodule.  It is assumed that this feature will only be
> 	checked when there is an SDRC module present (i.e., when
> 	omap3_has_sdrc() would return true).
> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

We need to stop declaring these feature flags for IP blocks, and use the 
hwmod code instead.  hwmod code provides omap_hwmod_lookup() which can be 
used to determine whether a given IP block exists on a particular chip, so 
I don't think there's any need for omap3_has_sdrc(), 
omap3_has_sdrc_emif4(), omap3_has_iva(), omap3_has_isp(), etc.

So it would be best if you could simply add an EMIF hwmod data entry in 
omap_hwmod_3xxx_data.c.


> ---
>  arch/arm/mach-omap2/id.c              |    5 ++++-
>  arch/arm/plat-omap/include/plat/cpu.h |   12 +++++++-----
>  2 files changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
> index b6508e5..abb5e51 100644
> --- a/arch/arm/mach-omap2/id.c
> +++ b/arch/arm/mach-omap2/id.c
> @@ -256,10 +256,13 @@ void __init omap3xxx_check_features(void)
>  	 *   the incorrectly set feature bits.
>  	 * - Indicate that am35x SoCs don't support the PWRDM_POWER_RET
>  	 *   and PWRDM_POWER_OFF states by clearing OMAP3_HAS_PWROFF.
> +	 * - Indicate that am35x SoCs have an EMIF4 SDRC submodule.
>  	 */
> -	if (cpu_is_omap3505() || cpu_is_omap3517())
> +	if (cpu_is_omap3505() || cpu_is_omap3517()) {
>  		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP |
>  			OMAP3_HAS_PWROFF);
> +		omap_features |= OMAP3_HAS_SDRC_EMIF4;
> +	}
>  
>  	/*
>  	 * TODO: Get additional info (where applicable)
> diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
> index c3f1a42..207f21b 100644
> --- a/arch/arm/plat-omap/include/plat/cpu.h
> +++ b/arch/arm/plat-omap/include/plat/cpu.h
> @@ -476,11 +476,12 @@ extern u32 omap_features;
>  #define OMAP3_HAS_192MHZ_CLK		BIT(5)
>  #define OMAP3_HAS_IO_WAKEUP		BIT(6)
>  #define OMAP3_HAS_SDRC			BIT(7)
> -#define OMAP3_HAS_IO_CHAIN_CTRL		BIT(8)
> -#define OMAP3_HAS_PWROFF		BIT(9)
> -#define OMAP4_HAS_MPU_1GHZ		BIT(10)
> -#define OMAP4_HAS_MPU_1_2GHZ		BIT(11)
> -#define OMAP4_HAS_MPU_1_5GHZ		BIT(12)
> +#define OMAP3_HAS_SDRC_EMIF4		BIT(8)
> +#define OMAP3_HAS_IO_CHAIN_CTRL		BIT(9)
> +#define OMAP3_HAS_PWROFF		BIT(10)
> +#define OMAP4_HAS_MPU_1GHZ		BIT(11)
> +#define OMAP4_HAS_MPU_1_2GHZ		BIT(12)
> +#define OMAP4_HAS_MPU_1_5GHZ		BIT(13)
>  
>  
>  #define OMAP3_HAS_FEATURE(feat,flag)			\
> @@ -497,6 +498,7 @@ OMAP3_HAS_FEATURE(isp, ISP)
>  OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
>  OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
>  OMAP3_HAS_FEATURE(sdrc, SDRC)
> +OMAP3_HAS_FEATURE(sdrc_emif4, SDRC_EMIF4)
>  OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
>  OMAP3_HAS_FEATURE(pwroff, PWROFF)
>  
> -- 
> 1.7.9.4
> 


- Paul

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

* [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
@ 2012-04-11 21:29     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The typical SDRAM Controller Subsystem module (SDRC)
> on TI OMAP3 devices has two submodules: the SDRAM Memory
> Scheduler (SMS) submodule, and the SDRC submodule--the
> 'SDRC' acronym/term is overloaded.  The am35x family of
> devices is different in that it has an EMIF4 submodule
> instead of an SDRC submodule.  The SMS submodules are
> similar, though.
> 
> To allow code to determine whether the current device has an
> SDRC submodule or and EMIF4 submodule, add the 'OMAP3_HAS_SDRC_EMIF4'
> feature and set it when running on an am35x SoC.
> 
> So when:
> - omap3_has_sdrc() returns true: the system has an SDRC module
> 	consisting of an SMS submodule and either an SDRC submodule
> 	or an EMIF4 submodule.
> - omap3_has_sdrc_emif4() returns true: the system has an EMIF4
> 	submodule.  It is assumed that this feature will only be
> 	checked when there is an SDRC module present (i.e., when
> 	omap3_has_sdrc() would return true).
> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

We need to stop declaring these feature flags for IP blocks, and use the 
hwmod code instead.  hwmod code provides omap_hwmod_lookup() which can be 
used to determine whether a given IP block exists on a particular chip, so 
I don't think there's any need for omap3_has_sdrc(), 
omap3_has_sdrc_emif4(), omap3_has_iva(), omap3_has_isp(), etc.

So it would be best if you could simply add an EMIF hwmod data entry in 
omap_hwmod_3xxx_data.c.


> ---
>  arch/arm/mach-omap2/id.c              |    5 ++++-
>  arch/arm/plat-omap/include/plat/cpu.h |   12 +++++++-----
>  2 files changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
> index b6508e5..abb5e51 100644
> --- a/arch/arm/mach-omap2/id.c
> +++ b/arch/arm/mach-omap2/id.c
> @@ -256,10 +256,13 @@ void __init omap3xxx_check_features(void)
>  	 *   the incorrectly set feature bits.
>  	 * - Indicate that am35x SoCs don't support the PWRDM_POWER_RET
>  	 *   and PWRDM_POWER_OFF states by clearing OMAP3_HAS_PWROFF.
> +	 * - Indicate that am35x SoCs have an EMIF4 SDRC submodule.
>  	 */
> -	if (cpu_is_omap3505() || cpu_is_omap3517())
> +	if (cpu_is_omap3505() || cpu_is_omap3517()) {
>  		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP |
>  			OMAP3_HAS_PWROFF);
> +		omap_features |= OMAP3_HAS_SDRC_EMIF4;
> +	}
>  
>  	/*
>  	 * TODO: Get additional info (where applicable)
> diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
> index c3f1a42..207f21b 100644
> --- a/arch/arm/plat-omap/include/plat/cpu.h
> +++ b/arch/arm/plat-omap/include/plat/cpu.h
> @@ -476,11 +476,12 @@ extern u32 omap_features;
>  #define OMAP3_HAS_192MHZ_CLK		BIT(5)
>  #define OMAP3_HAS_IO_WAKEUP		BIT(6)
>  #define OMAP3_HAS_SDRC			BIT(7)
> -#define OMAP3_HAS_IO_CHAIN_CTRL		BIT(8)
> -#define OMAP3_HAS_PWROFF		BIT(9)
> -#define OMAP4_HAS_MPU_1GHZ		BIT(10)
> -#define OMAP4_HAS_MPU_1_2GHZ		BIT(11)
> -#define OMAP4_HAS_MPU_1_5GHZ		BIT(12)
> +#define OMAP3_HAS_SDRC_EMIF4		BIT(8)
> +#define OMAP3_HAS_IO_CHAIN_CTRL		BIT(9)
> +#define OMAP3_HAS_PWROFF		BIT(10)
> +#define OMAP4_HAS_MPU_1GHZ		BIT(11)
> +#define OMAP4_HAS_MPU_1_2GHZ		BIT(12)
> +#define OMAP4_HAS_MPU_1_5GHZ		BIT(13)
>  
>  
>  #define OMAP3_HAS_FEATURE(feat,flag)			\
> @@ -497,6 +498,7 @@ OMAP3_HAS_FEATURE(isp, ISP)
>  OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
>  OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
>  OMAP3_HAS_FEATURE(sdrc, SDRC)
> +OMAP3_HAS_FEATURE(sdrc_emif4, SDRC_EMIF4)
>  OMAP3_HAS_FEATURE(io_chain_ctrl, IO_CHAIN_CTRL)
>  OMAP3_HAS_FEATURE(pwroff, PWROFF)
>  
> -- 
> 1.7.9.4
> 


- Paul

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

* Re: [PATCH 10/12] arm: omap3: am35x: Add minimal EMIF4 support
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 21:31     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:31 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman, aneesh

cc Aneesh

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The typical SDRAM Controller Subsystem module (SDRC)
> on TI OMAP3 devices has two submodules: the SDRAM Memory
> Scheduler (SMS) submodule, and the SDRC submodule--the
> 'SDRC' acronym/term is overloaded.  The am35x family of
> devices is different in that it has an EMIF4 submodule
> instead of an SDRC submodule.  The SMS submodules are
> similar, though.

The best thing to do is to add an EMIF driver stub that is initialized 
based on hwmod data, rather than hacking this into the existing SDRC.

I don't know what the current state of the EMIF driver is.  Aneesh, 
do you know what the current status is?

If it's not going upstream for some reason, then I'd suggest adding 
arch/arm/mach-omap2/emif.c for now.


- Paul

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

* [PATCH 10/12] arm: omap3: am35x: Add minimal EMIF4 support
@ 2012-04-11 21:31     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:31 UTC (permalink / raw)
  To: linux-arm-kernel

cc Aneesh

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The typical SDRAM Controller Subsystem module (SDRC)
> on TI OMAP3 devices has two submodules: the SDRAM Memory
> Scheduler (SMS) submodule, and the SDRC submodule--the
> 'SDRC' acronym/term is overloaded.  The am35x family of
> devices is different in that it has an EMIF4 submodule
> instead of an SDRC submodule.  The SMS submodules are
> similar, though.

The best thing to do is to add an EMIF driver stub that is initialized 
based on hwmod data, rather than hacking this into the existing SDRC.

I don't know what the current state of the EMIF driver is.  Aneesh, 
do you know what the current status is?

If it's not going upstream for some reason, then I'd suggest adding 
arch/arm/mach-omap2/emif.c for now.


- Paul

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 21:37     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:37 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

Hi

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
> which calls omap_sram_idle().  omap_sram_idle() eventually
> causes a 'wfi' instruction to be executed effectively putting
> the system to sleep.  It is assumed that an I/O wake-up event
> will occur to wake the system up again.  This doesn't work on
> systems that don't support I/O wake-ups (indicated by
> omap3_has_io_wakeup() returning false).
> 
> To handle this, follow the same path in omap3_enter_idle()
> that would be followed if an interrupt were pending.

I don't quite understand this patch.  Are you saying that AM3517/3505 
can't wake from WFI?  That would seem odd.

There are other sources of wakeup on the system other than I/O wakeup.  
I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
RETENTION or OFF.  And as I understand it, neither of those apply to 
AM3517/3505?

Even if I/O wakeups aren't supported, many of the IP blocks on the system 
should be able to cause the ARM to exit WFI by asserting their 
SWAKEUP lines and raising their interrupt lines.

So this change doesn't seem quite right to me...

More broadly, if AM3517/3505 only supports powerdomains ON, then you 
should probably use your own CPUIdle driver that doesn't touch the 
powerdomain states at all.


- Paul


> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/cpuidle34xx.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 5358664..12cf81d 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -100,7 +100,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
>  	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
>  	pwrdm_set_next_pwrst(core_pd, core_state);
>  
> -	if (omap_irq_pending() || need_resched())
> +	if (omap_irq_pending() || need_resched() || !omap3_has_io_wakeup())
>  		goto return_sleep_time;
>  
>  	/* Deny idle for C1 */
> -- 
> 1.7.9.4
> 


- Paul

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-11 21:37     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
> which calls omap_sram_idle().  omap_sram_idle() eventually
> causes a 'wfi' instruction to be executed effectively putting
> the system to sleep.  It is assumed that an I/O wake-up event
> will occur to wake the system up again.  This doesn't work on
> systems that don't support I/O wake-ups (indicated by
> omap3_has_io_wakeup() returning false).
> 
> To handle this, follow the same path in omap3_enter_idle()
> that would be followed if an interrupt were pending.

I don't quite understand this patch.  Are you saying that AM3517/3505 
can't wake from WFI?  That would seem odd.

There are other sources of wakeup on the system other than I/O wakeup.  
I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
RETENTION or OFF.  And as I understand it, neither of those apply to 
AM3517/3505?

Even if I/O wakeups aren't supported, many of the IP blocks on the system 
should be able to cause the ARM to exit WFI by asserting their 
SWAKEUP lines and raising their interrupt lines.

So this change doesn't seem quite right to me...

More broadly, if AM3517/3505 only supports powerdomains ON, then you 
should probably use your own CPUIdle driver that doesn't touch the 
powerdomain states at all.


- Paul


> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/cpuidle34xx.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 5358664..12cf81d 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -100,7 +100,7 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
>  	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
>  	pwrdm_set_next_pwrst(core_pd, core_state);
>  
> -	if (omap_irq_pending() || need_resched())
> +	if (omap_irq_pending() || need_resched() || !omap3_has_io_wakeup())
>  		goto return_sleep_time;
>  
>  	/* Deny idle for C1 */
> -- 
> 1.7.9.4
> 


- Paul

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

* Re: [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 21:38     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:38 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> Currently in the OMAP3 code, cpu_idle() calls pm_idle(),
> which is a function pointer set to omap3_pm_idle()).
> omap3_pm_idle() calls omap_sram_idle() which eventually
> causes a 'wfi' instruction to be executed effectively
> putting the system to sleep.  It is assumed that an
> I/O wake-up event will occur to wake the system up again.
> This doesn't work on systems that don't support I/O wake-ups
> (indicated by omap3_has_io_wakeup() returning false).
> 
> Leaving pm_idle() pointing to default_idle() won't work
> either because the cpu_<processor>_do_idle() routine which
> is eventually called may also execute a 'wfi' instruction
> (e.g., cpu_v7_do_idle()).
> 
> To handle this, leave pm_idle() pointing to omap3_pm_idle()
> but add a check in omap3_pm_idle() so it avoids calling
> omap_sram_idle() when I/O wake-ups aren't supported.
> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

Same basic comments here as with your "arm: omap3: Only sleep in cpuidle 
driver if I/O wake-ups work" patch.


- Paul

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

* [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work
@ 2012-04-11 21:38     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> Currently in the OMAP3 code, cpu_idle() calls pm_idle(),
> which is a function pointer set to omap3_pm_idle()).
> omap3_pm_idle() calls omap_sram_idle() which eventually
> causes a 'wfi' instruction to be executed effectively
> putting the system to sleep.  It is assumed that an
> I/O wake-up event will occur to wake the system up again.
> This doesn't work on systems that don't support I/O wake-ups
> (indicated by omap3_has_io_wakeup() returning false).
> 
> Leaving pm_idle() pointing to default_idle() won't work
> either because the cpu_<processor>_do_idle() routine which
> is eventually called may also execute a 'wfi' instruction
> (e.g., cpu_v7_do_idle()).
> 
> To handle this, leave pm_idle() pointing to omap3_pm_idle()
> but add a check in omap3_pm_idle() so it avoids calling
> omap_sram_idle() when I/O wake-ups aren't supported.
> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

Same basic comments here as with your "arm: omap3: Only sleep in cpuidle 
driver if I/O wake-ups work" patch.


- Paul

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

* Re: [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 21:44     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:44 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

Hi

a few minor comments based on only a quick look

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The am35x family of SoCs do not have an IVA so
> a parallel set of clockdomain dependencies are
> required that are simililar to OMAP3 but without
> any IVA dependencies.
> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/clockdomains3xxx_data.c |  146 ++++++++++++++++++++++++++-
>  1 file changed, 141 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> index b84e138..a05a8cb 100644
> --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
> +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> @@ -59,6 +59,12 @@ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm", },
> +	{ .clkdm_name = "wkup_clkdm", },
> +	{ NULL },
> +};

Looks like there are an extra set of commas here, maybe just use:

static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
	{ .clkdm_name = "mpu_clkdm" },
	{ .clkdm_name = "wkup_clkdm" },
	{ NULL },
};

> +
>  /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
>  static struct clkdm_dep per_wkdeps[] = {
>  	{ .clkdm_name = "core_l3_clkdm" },
> @@ -69,6 +75,14 @@ static struct clkdm_dep per_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep per_am35x_wkdeps[] = {
> +	{ .clkdm_name = "core_l3_clkdm" },
> +	{ .clkdm_name = "core_l4_clkdm" },
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ .clkdm_name = "wkup_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
>  static struct clkdm_dep usbhost_wkdeps[] = {
>  	{ .clkdm_name = "core_l3_clkdm" },
> @@ -79,6 +93,14 @@ static struct clkdm_dep usbhost_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep usbhost_am35x_wkdeps[] = {
> +	{ .clkdm_name = "core_l3_clkdm" },
> +	{ .clkdm_name = "core_l4_clkdm" },
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ .clkdm_name = "wkup_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
>  static struct clkdm_dep mpu_3xxx_wkdeps[] = {
>  	{ .clkdm_name = "core_l3_clkdm" },
> @@ -89,6 +111,14 @@ static struct clkdm_dep mpu_3xxx_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep mpu_am35x_wkdeps[] = {
> +	{ .clkdm_name = "core_l3_clkdm" },
> +	{ .clkdm_name = "core_l4_clkdm" },
> +	{ .clkdm_name = "dss_clkdm" },
> +	{ .clkdm_name = "per_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
>  static struct clkdm_dep iva2_wkdeps[] = {
>  	{ .clkdm_name = "core_l3_clkdm" },
> @@ -116,6 +146,12 @@ static struct clkdm_dep dss_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep dss_am35x_wkdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ .clkdm_name = "wkup_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430: PM_WKDEP_NEON: MPU */
>  static struct clkdm_dep neon_wkdeps[] = {
>  	{ .clkdm_name = "mpu_clkdm" },
> @@ -131,6 +167,11 @@ static struct clkdm_dep dss_sleepdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep dss_am35x_sleepdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
>  static struct clkdm_dep per_sleepdeps[] = {
>  	{ .clkdm_name = "mpu_clkdm" },
> @@ -138,6 +179,11 @@ static struct clkdm_dep per_sleepdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep per_am35x_sleepdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
>  static struct clkdm_dep usbhost_sleepdeps[] = {
>  	{ .clkdm_name = "mpu_clkdm" },
> @@ -145,6 +191,11 @@ static struct clkdm_dep usbhost_sleepdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep usbhost_am35x_sleepdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430: CM_SLEEPDEP_CAM: MPU */
>  static struct clkdm_dep cam_sleepdeps[] = {
>  	{ .clkdm_name = "mpu_clkdm" },
> @@ -175,6 +226,15 @@ static struct clockdomain mpu_3xxx_clkdm = {
>  	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
>  };
>  
> +static struct clockdomain mpu_am35x_clkdm = {
> +	.name		= "mpu_clkdm",
> +	.pwrdm		= { .name = "mpu_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
> +	.dep_bit	= OMAP3430_EN_MPU_SHIFT,
> +	.wkdep_srcs	= mpu_am35x_wkdeps,
> +	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
> +};
> +
>  static struct clockdomain neon_clkdm = {
>  	.name		= "neon_clkdm",
>  	.pwrdm		= { .name = "neon_pwrdm" },
> @@ -210,6 +270,15 @@ static struct clockdomain sgx_clkdm = {
>  	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
>  };
>  
> +static struct clockdomain sgx_am35x_clkdm = {
> +	.name		= "sgx_clkdm",
> +	.pwrdm		= { .name = "sgx_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP_SWSUP,
> +	.wkdep_srcs	= gfx_sgx_am35x_wkdeps,
> +	.sleepdep_srcs	= gfx_sgx_sleepdeps,
> +	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
> +};
> +
>  /*
>   * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
>   * then that information was removed from the 34xx ES2+ TRM.  It is
> @@ -261,6 +330,16 @@ static struct clockdomain dss_3xxx_clkdm = {
>  	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
>  };
>  
> +static struct clockdomain dss_am35x_clkdm = {
> +	.name		= "dss_clkdm",
> +	.pwrdm		= { .name = "dss_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP_SWSUP,
> +	.dep_bit	= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
> +	.wkdep_srcs	= dss_am35x_wkdeps,
> +	.sleepdep_srcs	= dss_am35x_sleepdeps,
> +	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
> +};
> +
>  static struct clockdomain cam_clkdm = {
>  	.name		= "cam_clkdm",
>  	.pwrdm		= { .name = "cam_pwrdm" },
> @@ -279,6 +358,15 @@ static struct clockdomain usbhost_clkdm = {
>  	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
>  };
>  
> +static struct clockdomain usbhost_am35x_clkdm = {
> +	.name		= "usbhost_clkdm",
> +	.pwrdm		= { .name = "core_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP_SWSUP,
> +	.wkdep_srcs	= usbhost_am35x_wkdeps,
> +	.sleepdep_srcs	= usbhost_am35x_sleepdeps,
> +	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
> +};
> +
>  static struct clockdomain per_clkdm = {
>  	.name		= "per_clkdm",
>  	.pwrdm		= { .name = "per_pwrdm" },
> @@ -289,6 +377,16 @@ static struct clockdomain per_clkdm = {
>  	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
>  };
>  
> +static struct clockdomain per_am35x_clkdm = {
> +	.name		= "per_clkdm",
> +	.pwrdm		= { .name = "per_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP_SWSUP,
> +	.dep_bit	= OMAP3430_EN_PER_SHIFT,
> +	.wkdep_srcs	= per_am35x_wkdeps,
> +	.sleepdep_srcs	= per_am35x_sleepdeps,
> +	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
> +};
> +
>  /*
>   * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
>   * switched of even if sdti is in use
> @@ -341,6 +439,15 @@ static struct clkdm_autodep clkdm_autodeps[] = {
>  	}
>  };
>  
> +static struct clkdm_autodep clkdm_am35x_autodeps[] = {
> +	{
> +		.clkdm = { .name = "mpu_clkdm" },
> +	},
> +	{
> +		.clkdm = { .name = NULL },
> +	}
> +};
> +
>  /*
>   *
>   */
> @@ -366,6 +473,26 @@ static struct clockdomain *clockdomains_omap3430_common[] __initdata = {
>  	NULL
>  };
>  
> +static struct clockdomain *clockdomains_am35x_common[] __initdata = {
> +	&wkup_common_clkdm,
> +	&cm_common_clkdm,
> +	&prm_common_clkdm,
> +	&mpu_am35x_clkdm,
> +	&neon_clkdm,
> +	&sgx_am35x_clkdm,
> +	&core_l3_3xxx_clkdm,
> +	&core_l4_3xxx_clkdm,
> +	&dss_am35x_clkdm,
> +	&per_am35x_clkdm,
> +	&emu_clkdm,
> +	&usbhost_am35x_clkdm,
> +	&dpll1_clkdm,
> +	&dpll3_clkdm,
> +	&dpll4_clkdm,
> +	&dpll5_clkdm,
> +	NULL
> +};

Looks like many of these clockdomains are shared with the rest of 
OMAP3xxx.  Maybe move the shared ones into a common array, remove them 
from clockdomains_omap3430_common, and in the init function below, first 
register the shared ones?  That will avoid duplicate listings.

> +
>  static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
>  	&gfx_3430es1_clkdm,
>  	NULL,
> @@ -381,18 +508,27 @@ static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {
>  void __init omap3xxx_clockdomains_init(void)
>  {
>  	struct clockdomain **sc;
> +	unsigned int rev;
>  
>  	if (!cpu_is_omap34xx())
>  		return;
>  
>  	clkdm_register_platform_funcs(&omap3_clkdm_operations);
> -	clkdm_register_clkdms(clockdomains_omap3430_common);
>  
> -	sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 :
> -		clockdomains_omap3430es2plus;
> +	rev = omap_rev();
>  
> -	clkdm_register_clkdms(sc);
> +	if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1) {
> +		clkdm_register_clkdms(clockdomains_am35x_common);
> +		clkdm_register_autodeps(clkdm_am35x_autodeps);
> +	} else {
> +		clkdm_register_clkdms(clockdomains_omap3430_common);
> +
> +		sc = (rev == OMAP3430_REV_ES1_0) ?
> +			clockdomains_omap3430es1 : clockdomains_omap3430es2plus;
> +
> +		clkdm_register_clkdms(sc);
> +		clkdm_register_autodeps(clkdm_autodeps);
> +	}
>  
> -	clkdm_register_autodeps(clkdm_autodeps);
>  	clkdm_complete_init();
>  }
> -- 
> 1.7.9.4
> 


- Paul

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-11 21:44     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

a few minor comments based on only a quick look

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The am35x family of SoCs do not have an IVA so
> a parallel set of clockdomain dependencies are
> required that are simililar to OMAP3 but without
> any IVA dependencies.
> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/clockdomains3xxx_data.c |  146 ++++++++++++++++++++++++++-
>  1 file changed, 141 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> index b84e138..a05a8cb 100644
> --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
> +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> @@ -59,6 +59,12 @@ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm", },
> +	{ .clkdm_name = "wkup_clkdm", },
> +	{ NULL },
> +};

Looks like there are an extra set of commas here, maybe just use:

static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
	{ .clkdm_name = "mpu_clkdm" },
	{ .clkdm_name = "wkup_clkdm" },
	{ NULL },
};

> +
>  /* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
>  static struct clkdm_dep per_wkdeps[] = {
>  	{ .clkdm_name = "core_l3_clkdm" },
> @@ -69,6 +75,14 @@ static struct clkdm_dep per_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep per_am35x_wkdeps[] = {
> +	{ .clkdm_name = "core_l3_clkdm" },
> +	{ .clkdm_name = "core_l4_clkdm" },
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ .clkdm_name = "wkup_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
>  static struct clkdm_dep usbhost_wkdeps[] = {
>  	{ .clkdm_name = "core_l3_clkdm" },
> @@ -79,6 +93,14 @@ static struct clkdm_dep usbhost_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep usbhost_am35x_wkdeps[] = {
> +	{ .clkdm_name = "core_l3_clkdm" },
> +	{ .clkdm_name = "core_l4_clkdm" },
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ .clkdm_name = "wkup_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
>  static struct clkdm_dep mpu_3xxx_wkdeps[] = {
>  	{ .clkdm_name = "core_l3_clkdm" },
> @@ -89,6 +111,14 @@ static struct clkdm_dep mpu_3xxx_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep mpu_am35x_wkdeps[] = {
> +	{ .clkdm_name = "core_l3_clkdm" },
> +	{ .clkdm_name = "core_l4_clkdm" },
> +	{ .clkdm_name = "dss_clkdm" },
> +	{ .clkdm_name = "per_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
>  static struct clkdm_dep iva2_wkdeps[] = {
>  	{ .clkdm_name = "core_l3_clkdm" },
> @@ -116,6 +146,12 @@ static struct clkdm_dep dss_wkdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep dss_am35x_wkdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ .clkdm_name = "wkup_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430: PM_WKDEP_NEON: MPU */
>  static struct clkdm_dep neon_wkdeps[] = {
>  	{ .clkdm_name = "mpu_clkdm" },
> @@ -131,6 +167,11 @@ static struct clkdm_dep dss_sleepdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep dss_am35x_sleepdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430: CM_SLEEPDEP_PER: MPU, IVA */
>  static struct clkdm_dep per_sleepdeps[] = {
>  	{ .clkdm_name = "mpu_clkdm" },
> @@ -138,6 +179,11 @@ static struct clkdm_dep per_sleepdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep per_am35x_sleepdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
>  static struct clkdm_dep usbhost_sleepdeps[] = {
>  	{ .clkdm_name = "mpu_clkdm" },
> @@ -145,6 +191,11 @@ static struct clkdm_dep usbhost_sleepdeps[] = {
>  	{ NULL },
>  };
>  
> +static struct clkdm_dep usbhost_am35x_sleepdeps[] = {
> +	{ .clkdm_name = "mpu_clkdm" },
> +	{ NULL },
> +};
> +
>  /* 3430: CM_SLEEPDEP_CAM: MPU */
>  static struct clkdm_dep cam_sleepdeps[] = {
>  	{ .clkdm_name = "mpu_clkdm" },
> @@ -175,6 +226,15 @@ static struct clockdomain mpu_3xxx_clkdm = {
>  	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
>  };
>  
> +static struct clockdomain mpu_am35x_clkdm = {
> +	.name		= "mpu_clkdm",
> +	.pwrdm		= { .name = "mpu_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
> +	.dep_bit	= OMAP3430_EN_MPU_SHIFT,
> +	.wkdep_srcs	= mpu_am35x_wkdeps,
> +	.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
> +};
> +
>  static struct clockdomain neon_clkdm = {
>  	.name		= "neon_clkdm",
>  	.pwrdm		= { .name = "neon_pwrdm" },
> @@ -210,6 +270,15 @@ static struct clockdomain sgx_clkdm = {
>  	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
>  };
>  
> +static struct clockdomain sgx_am35x_clkdm = {
> +	.name		= "sgx_clkdm",
> +	.pwrdm		= { .name = "sgx_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP_SWSUP,
> +	.wkdep_srcs	= gfx_sgx_am35x_wkdeps,
> +	.sleepdep_srcs	= gfx_sgx_sleepdeps,
> +	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
> +};
> +
>  /*
>   * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
>   * then that information was removed from the 34xx ES2+ TRM.  It is
> @@ -261,6 +330,16 @@ static struct clockdomain dss_3xxx_clkdm = {
>  	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
>  };
>  
> +static struct clockdomain dss_am35x_clkdm = {
> +	.name		= "dss_clkdm",
> +	.pwrdm		= { .name = "dss_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP_SWSUP,
> +	.dep_bit	= OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
> +	.wkdep_srcs	= dss_am35x_wkdeps,
> +	.sleepdep_srcs	= dss_am35x_sleepdeps,
> +	.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
> +};
> +
>  static struct clockdomain cam_clkdm = {
>  	.name		= "cam_clkdm",
>  	.pwrdm		= { .name = "cam_pwrdm" },
> @@ -279,6 +358,15 @@ static struct clockdomain usbhost_clkdm = {
>  	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
>  };
>  
> +static struct clockdomain usbhost_am35x_clkdm = {
> +	.name		= "usbhost_clkdm",
> +	.pwrdm		= { .name = "core_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP_SWSUP,
> +	.wkdep_srcs	= usbhost_am35x_wkdeps,
> +	.sleepdep_srcs	= usbhost_am35x_sleepdeps,
> +	.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
> +};
> +
>  static struct clockdomain per_clkdm = {
>  	.name		= "per_clkdm",
>  	.pwrdm		= { .name = "per_pwrdm" },
> @@ -289,6 +377,16 @@ static struct clockdomain per_clkdm = {
>  	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
>  };
>  
> +static struct clockdomain per_am35x_clkdm = {
> +	.name		= "per_clkdm",
> +	.pwrdm		= { .name = "per_pwrdm" },
> +	.flags		= CLKDM_CAN_HWSUP_SWSUP,
> +	.dep_bit	= OMAP3430_EN_PER_SHIFT,
> +	.wkdep_srcs	= per_am35x_wkdeps,
> +	.sleepdep_srcs	= per_am35x_sleepdeps,
> +	.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
> +};
> +
>  /*
>   * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
>   * switched of even if sdti is in use
> @@ -341,6 +439,15 @@ static struct clkdm_autodep clkdm_autodeps[] = {
>  	}
>  };
>  
> +static struct clkdm_autodep clkdm_am35x_autodeps[] = {
> +	{
> +		.clkdm = { .name = "mpu_clkdm" },
> +	},
> +	{
> +		.clkdm = { .name = NULL },
> +	}
> +};
> +
>  /*
>   *
>   */
> @@ -366,6 +473,26 @@ static struct clockdomain *clockdomains_omap3430_common[] __initdata = {
>  	NULL
>  };
>  
> +static struct clockdomain *clockdomains_am35x_common[] __initdata = {
> +	&wkup_common_clkdm,
> +	&cm_common_clkdm,
> +	&prm_common_clkdm,
> +	&mpu_am35x_clkdm,
> +	&neon_clkdm,
> +	&sgx_am35x_clkdm,
> +	&core_l3_3xxx_clkdm,
> +	&core_l4_3xxx_clkdm,
> +	&dss_am35x_clkdm,
> +	&per_am35x_clkdm,
> +	&emu_clkdm,
> +	&usbhost_am35x_clkdm,
> +	&dpll1_clkdm,
> +	&dpll3_clkdm,
> +	&dpll4_clkdm,
> +	&dpll5_clkdm,
> +	NULL
> +};

Looks like many of these clockdomains are shared with the rest of 
OMAP3xxx.  Maybe move the shared ones into a common array, remove them 
from clockdomains_omap3430_common, and in the init function below, first 
register the shared ones?  That will avoid duplicate listings.

> +
>  static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
>  	&gfx_3430es1_clkdm,
>  	NULL,
> @@ -381,18 +508,27 @@ static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {
>  void __init omap3xxx_clockdomains_init(void)
>  {
>  	struct clockdomain **sc;
> +	unsigned int rev;
>  
>  	if (!cpu_is_omap34xx())
>  		return;
>  
>  	clkdm_register_platform_funcs(&omap3_clkdm_operations);
> -	clkdm_register_clkdms(clockdomains_omap3430_common);
>  
> -	sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 :
> -		clockdomains_omap3430es2plus;
> +	rev = omap_rev();
>  
> -	clkdm_register_clkdms(sc);
> +	if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1) {
> +		clkdm_register_clkdms(clockdomains_am35x_common);
> +		clkdm_register_autodeps(clkdm_am35x_autodeps);
> +	} else {
> +		clkdm_register_clkdms(clockdomains_omap3430_common);
> +
> +		sc = (rev == OMAP3430_REV_ES1_0) ?
> +			clockdomains_omap3430es1 : clockdomains_omap3430es2plus;
> +
> +		clkdm_register_clkdms(sc);
> +		clkdm_register_autodeps(clkdm_autodeps);
> +	}
>  
> -	clkdm_register_autodeps(clkdm_autodeps);
>  	clkdm_complete_init();
>  }
> -- 
> 1.7.9.4
> 


- Paul

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

* Re: [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 21:53     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:53 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

Hi

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The am35x family of SoCs only support PWRSTS_ON
> and PWRSTS_INACTIVE states so create a new set
> of powerdomain structures that ensure that only
> the ON and INACTIVE states are entered.

I'm still unsure what we should do about this INACTIVE state.  As far as I 
can tell, it does not actually represent a distinct powerdomain state on 
OMAP3.  We can't write it to the PM_PWSTCTRL_*.POWERSTATE bits, since that 
value is marked as "reserved".  And SPRUGR0B, the AM3517/3505 TRM, 
explicitly states "This register should not be programmed with reserved 
values of bit fields for proper functioning of power state control."
Of course SPRUGR0B also claims that AM3517/3505 supports RETENTION, so 
that is relatively confusing.

OMAP4 PRCM actually does seem to support powerdomain INACTIVE state, 
although it does not actually seem to represent a separate state.  As I 
understand it, it simply allows the clockdomains in the powerdomain to 
transitioning from the ACTIVE state into the INACTIVE state.  In other 
words, it doesn't affect the powerdomain power state at all.  And on OMAP4 
it's referred to as the ON-INACTIVE state, to clarify that it is simply a 
variant of the ON state.  I wish they had just added a separate bit for 
this; it would have avoided some frustration...

Anyway, my question is this: is there any point at all to defining the 
INACTIVE state for 3517/3505, given that it apparently cannot be read 
from, nor written to the PRCM hardware?

> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/powerdomain.h           |    1 +
>  arch/arm/mach-omap2/powerdomains3xxx_data.c |  134 ++++++++++++++++++++++++---
>  2 files changed, 123 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
> index 0d72a8a..561cb27 100644
> --- a/arch/arm/mach-omap2/powerdomain.h
> +++ b/arch/arm/mach-omap2/powerdomain.h
> @@ -43,6 +43,7 @@
>  #define PWRSTS_OFF_ON		(PWRSTS_OFF | PWRSTS_ON)
>  #define PWRSTS_OFF_RET		(PWRSTS_OFF | PWRSTS_RET)
>  #define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
> +#define PWRSTS_INACTIVE_ON	(PWRSTS_INACTIVE | PWRSTS_ON)
>  #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON)
>  
>  
> diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
> index b7ea468..fae6dea 100644
> --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
> +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
> @@ -71,6 +71,22 @@ static struct powerdomain mpu_3xxx_pwrdm = {
>  	.voltdm           = { .name = "mpu_iva" },
>  };
>  
> +static struct powerdomain mpu_am35x_pwrdm = {
> +	.name		  = "mpu_pwrdm",
> +	.prcm_offs	  = MPU_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.flags		  = PWRDM_HAS_MPU_QUIRK,
> +	.banks		  = 1,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE,
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_INACTIVE_ON,
> +	},
> +	.voltdm           = { .name = "mpu_iva" },
> +};
> +
>  /*
>   * The USBTLL Save-and-Restore mechanism is broken on
>   * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
> @@ -120,6 +136,23 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
>  	.voltdm           = { .name = "core" },
>  };
>  
> +static struct powerdomain core_am35x_pwrdm = {
> +	.name		  = "core_pwrdm",
> +	.prcm_offs	  = CORE_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.banks		  = 2,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE,	 /* MEM1RETSTATE */
> +		[1] = PWRSTS_INACTIVE,	 /* MEM2RETSTATE */
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_INACTIVE_ON, /* MEM1ONSTATE */
> +		[1] = PWRSTS_INACTIVE_ON, /* MEM2ONSTATE */
> +	},
> +	.voltdm           = { .name = "core" },
> +};
> +
>  static struct powerdomain dss_pwrdm = {
>  	.name		  = "dss_pwrdm",
>  	.prcm_offs	  = OMAP3430_DSS_MOD,
> @@ -135,6 +168,21 @@ static struct powerdomain dss_pwrdm = {
>  	.voltdm           = { .name = "core" },
>  };
>  
> +static struct powerdomain dss_am35x_pwrdm = {
> +	.name		  = "dss_pwrdm",
> +	.prcm_offs	  = OMAP3430_DSS_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.banks		  = 1,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_ON,  /* MEMONSTATE */
> +	},
> +	.voltdm           = { .name = "core" },
> +};
> +
>  /*
>   * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
>   * possible SGX powerstate, the SGX device itself does not support
> @@ -156,6 +204,21 @@ static struct powerdomain sgx_pwrdm = {
>  	.voltdm           = { .name = "core" },
>  };
>  
> +static struct powerdomain sgx_am35x_pwrdm = {
> +	.name		  = "sgx_pwrdm",
> +	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.banks		  = 1,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_ON,  /* MEMONSTATE */
> +	},
> +	.voltdm           = { .name = "core" },
> +};
> +
>  static struct powerdomain cam_pwrdm = {
>  	.name		  = "cam_pwrdm",
>  	.prcm_offs	  = OMAP3430_CAM_MOD,
> @@ -186,6 +249,21 @@ static struct powerdomain per_pwrdm = {
>  	.voltdm           = { .name = "core" },
>  };
>  
> +static struct powerdomain per_am35x_pwrdm = {
> +	.name		  = "per_pwrdm",
> +	.prcm_offs	  = OMAP3430_PER_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.banks		  = 1,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_ON,  /* MEMONSTATE */
> +	},
> +	.voltdm           = { .name = "core" },
> +};
> +
>  static struct powerdomain emu_pwrdm = {
>  	.name		= "emu_pwrdm",
>  	.prcm_offs	= OMAP3430_EMU_MOD,
> @@ -200,6 +278,14 @@ static struct powerdomain neon_pwrdm = {
>  	.voltdm           = { .name = "mpu_iva" },
>  };
>  
> +static struct powerdomain neon_am35x_pwrdm = {
> +	.name		  = "neon_pwrdm",
> +	.prcm_offs	  = OMAP3430_NEON_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.voltdm           = { .name = "mpu_iva" },
> +};
> +
>  static struct powerdomain usbhost_pwrdm = {
>  	.name		  = "usbhost_pwrdm",
>  	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
> @@ -293,6 +379,22 @@ static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
>  	NULL
>  };
>  
> +static struct powerdomain *powerdomains_am35x[] __initdata = {
> +	&wkup_omap2_pwrdm,
> +	&mpu_am35x_pwrdm,
> +	&neon_am35x_pwrdm,
> +	&core_am35x_pwrdm,
> +	&sgx_am35x_pwrdm,
> +	&dss_am35x_pwrdm,
> +	&per_am35x_pwrdm,
> +	&emu_pwrdm,
> +	&dpll1_pwrdm,
> +	&dpll3_pwrdm,
> +	&dpll4_pwrdm,
> +	&dpll5_pwrdm,
> +	NULL
> +};
> +
>  void __init omap3xxx_powerdomains_init(void)
>  {
>  	unsigned int rev;
> @@ -301,21 +403,29 @@ void __init omap3xxx_powerdomains_init(void)
>  		return;
>  
>  	pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
> -	pwrdm_register_pwrdms(powerdomains_omap3430_common);
>  
>  	rev = omap_rev();
>  
> -	if (rev == OMAP3430_REV_ES1_0)
> -		pwrdm_register_pwrdms(powerdomains_omap3430es1);
> -	else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
> -		 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
> -		pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
> -	else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
> -		 rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 ||
> -		 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
> -		pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
> -	else
> -		WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
> +	if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1)
> +		pwrdm_register_pwrdms(powerdomains_am35x);
> +	else {
> +		pwrdm_register_pwrdms(powerdomains_omap3430_common);
> +
> +		if (rev == OMAP3430_REV_ES1_0)
> +			pwrdm_register_pwrdms(powerdomains_omap3430es1);
> +		else if (rev == OMAP3430_REV_ES2_0 ||
> +			 rev == OMAP3430_REV_ES2_1 ||
> +			 rev == OMAP3430_REV_ES3_0 ||
> +			 rev == OMAP3630_REV_ES1_0)
> +			pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
> +		else if (rev == OMAP3430_REV_ES3_1 ||
> +			 rev == OMAP3430_REV_ES3_1_2 ||
> +			 rev == OMAP3630_REV_ES1_1 ||
> +			 rev == OMAP3630_REV_ES1_2)
> +			pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
> +		else
> +			WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
> +	}
>  
>  	pwrdm_complete_init();
>  }
> -- 
> 1.7.9.4
> 


- Paul

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

* [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
@ 2012-04-11 21:53     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 21:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The am35x family of SoCs only support PWRSTS_ON
> and PWRSTS_INACTIVE states so create a new set
> of powerdomain structures that ensure that only
> the ON and INACTIVE states are entered.

I'm still unsure what we should do about this INACTIVE state.  As far as I 
can tell, it does not actually represent a distinct powerdomain state on 
OMAP3.  We can't write it to the PM_PWSTCTRL_*.POWERSTATE bits, since that 
value is marked as "reserved".  And SPRUGR0B, the AM3517/3505 TRM, 
explicitly states "This register should not be programmed with reserved 
values of bit fields for proper functioning of power state control."
Of course SPRUGR0B also claims that AM3517/3505 supports RETENTION, so 
that is relatively confusing.

OMAP4 PRCM actually does seem to support powerdomain INACTIVE state, 
although it does not actually seem to represent a separate state.  As I 
understand it, it simply allows the clockdomains in the powerdomain to 
transitioning from the ACTIVE state into the INACTIVE state.  In other 
words, it doesn't affect the powerdomain power state at all.  And on OMAP4 
it's referred to as the ON-INACTIVE state, to clarify that it is simply a 
variant of the ON state.  I wish they had just added a separate bit for 
this; it would have avoided some frustration...

Anyway, my question is this: is there any point at all to defining the 
INACTIVE state for 3517/3505, given that it apparently cannot be read 
from, nor written to the PRCM hardware?

> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/powerdomain.h           |    1 +
>  arch/arm/mach-omap2/powerdomains3xxx_data.c |  134 ++++++++++++++++++++++++---
>  2 files changed, 123 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
> index 0d72a8a..561cb27 100644
> --- a/arch/arm/mach-omap2/powerdomain.h
> +++ b/arch/arm/mach-omap2/powerdomain.h
> @@ -43,6 +43,7 @@
>  #define PWRSTS_OFF_ON		(PWRSTS_OFF | PWRSTS_ON)
>  #define PWRSTS_OFF_RET		(PWRSTS_OFF | PWRSTS_RET)
>  #define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
> +#define PWRSTS_INACTIVE_ON	(PWRSTS_INACTIVE | PWRSTS_ON)
>  #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON)
>  
>  
> diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
> index b7ea468..fae6dea 100644
> --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
> +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
> @@ -71,6 +71,22 @@ static struct powerdomain mpu_3xxx_pwrdm = {
>  	.voltdm           = { .name = "mpu_iva" },
>  };
>  
> +static struct powerdomain mpu_am35x_pwrdm = {
> +	.name		  = "mpu_pwrdm",
> +	.prcm_offs	  = MPU_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.flags		  = PWRDM_HAS_MPU_QUIRK,
> +	.banks		  = 1,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE,
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_INACTIVE_ON,
> +	},
> +	.voltdm           = { .name = "mpu_iva" },
> +};
> +
>  /*
>   * The USBTLL Save-and-Restore mechanism is broken on
>   * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
> @@ -120,6 +136,23 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
>  	.voltdm           = { .name = "core" },
>  };
>  
> +static struct powerdomain core_am35x_pwrdm = {
> +	.name		  = "core_pwrdm",
> +	.prcm_offs	  = CORE_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.banks		  = 2,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE,	 /* MEM1RETSTATE */
> +		[1] = PWRSTS_INACTIVE,	 /* MEM2RETSTATE */
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_INACTIVE_ON, /* MEM1ONSTATE */
> +		[1] = PWRSTS_INACTIVE_ON, /* MEM2ONSTATE */
> +	},
> +	.voltdm           = { .name = "core" },
> +};
> +
>  static struct powerdomain dss_pwrdm = {
>  	.name		  = "dss_pwrdm",
>  	.prcm_offs	  = OMAP3430_DSS_MOD,
> @@ -135,6 +168,21 @@ static struct powerdomain dss_pwrdm = {
>  	.voltdm           = { .name = "core" },
>  };
>  
> +static struct powerdomain dss_am35x_pwrdm = {
> +	.name		  = "dss_pwrdm",
> +	.prcm_offs	  = OMAP3430_DSS_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.banks		  = 1,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_ON,  /* MEMONSTATE */
> +	},
> +	.voltdm           = { .name = "core" },
> +};
> +
>  /*
>   * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
>   * possible SGX powerstate, the SGX device itself does not support
> @@ -156,6 +204,21 @@ static struct powerdomain sgx_pwrdm = {
>  	.voltdm           = { .name = "core" },
>  };
>  
> +static struct powerdomain sgx_am35x_pwrdm = {
> +	.name		  = "sgx_pwrdm",
> +	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.banks		  = 1,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_ON,  /* MEMONSTATE */
> +	},
> +	.voltdm           = { .name = "core" },
> +};
> +
>  static struct powerdomain cam_pwrdm = {
>  	.name		  = "cam_pwrdm",
>  	.prcm_offs	  = OMAP3430_CAM_MOD,
> @@ -186,6 +249,21 @@ static struct powerdomain per_pwrdm = {
>  	.voltdm           = { .name = "core" },
>  };
>  
> +static struct powerdomain per_am35x_pwrdm = {
> +	.name		  = "per_pwrdm",
> +	.prcm_offs	  = OMAP3430_PER_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.banks		  = 1,
> +	.pwrsts_mem_ret	  = {
> +		[0] = PWRSTS_INACTIVE, /* MEMRETSTATE */
> +	},
> +	.pwrsts_mem_on	  = {
> +		[0] = PWRSTS_ON,  /* MEMONSTATE */
> +	},
> +	.voltdm           = { .name = "core" },
> +};
> +
>  static struct powerdomain emu_pwrdm = {
>  	.name		= "emu_pwrdm",
>  	.prcm_offs	= OMAP3430_EMU_MOD,
> @@ -200,6 +278,14 @@ static struct powerdomain neon_pwrdm = {
>  	.voltdm           = { .name = "mpu_iva" },
>  };
>  
> +static struct powerdomain neon_am35x_pwrdm = {
> +	.name		  = "neon_pwrdm",
> +	.prcm_offs	  = OMAP3430_NEON_MOD,
> +	.pwrsts		  = PWRSTS_INACTIVE_ON,
> +	.pwrsts_logic_ret = PWRSTS_INACTIVE,
> +	.voltdm           = { .name = "mpu_iva" },
> +};
> +
>  static struct powerdomain usbhost_pwrdm = {
>  	.name		  = "usbhost_pwrdm",
>  	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
> @@ -293,6 +379,22 @@ static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
>  	NULL
>  };
>  
> +static struct powerdomain *powerdomains_am35x[] __initdata = {
> +	&wkup_omap2_pwrdm,
> +	&mpu_am35x_pwrdm,
> +	&neon_am35x_pwrdm,
> +	&core_am35x_pwrdm,
> +	&sgx_am35x_pwrdm,
> +	&dss_am35x_pwrdm,
> +	&per_am35x_pwrdm,
> +	&emu_pwrdm,
> +	&dpll1_pwrdm,
> +	&dpll3_pwrdm,
> +	&dpll4_pwrdm,
> +	&dpll5_pwrdm,
> +	NULL
> +};
> +
>  void __init omap3xxx_powerdomains_init(void)
>  {
>  	unsigned int rev;
> @@ -301,21 +403,29 @@ void __init omap3xxx_powerdomains_init(void)
>  		return;
>  
>  	pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
> -	pwrdm_register_pwrdms(powerdomains_omap3430_common);
>  
>  	rev = omap_rev();
>  
> -	if (rev == OMAP3430_REV_ES1_0)
> -		pwrdm_register_pwrdms(powerdomains_omap3430es1);
> -	else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
> -		 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
> -		pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
> -	else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
> -		 rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 ||
> -		 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
> -		pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
> -	else
> -		WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
> +	if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1)
> +		pwrdm_register_pwrdms(powerdomains_am35x);
> +	else {
> +		pwrdm_register_pwrdms(powerdomains_omap3430_common);
> +
> +		if (rev == OMAP3430_REV_ES1_0)
> +			pwrdm_register_pwrdms(powerdomains_omap3430es1);
> +		else if (rev == OMAP3430_REV_ES2_0 ||
> +			 rev == OMAP3430_REV_ES2_1 ||
> +			 rev == OMAP3430_REV_ES3_0 ||
> +			 rev == OMAP3630_REV_ES1_0)
> +			pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
> +		else if (rev == OMAP3430_REV_ES3_1 ||
> +			 rev == OMAP3430_REV_ES3_1_2 ||
> +			 rev == OMAP3630_REV_ES1_1 ||
> +			 rev == OMAP3630_REV_ES1_2)
> +			pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
> +		else
> +			WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
> +	}
>  
>  	pwrdm_complete_init();
>  }
> -- 
> 1.7.9.4
> 


- Paul

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

* Re: [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-11 21:44     ` Paul Walmsley
@ 2012-04-11 21:55       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 21:55 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> Hi

Hello & thx for the feedback.

> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The am35x family of SoCs do not have an IVA so
> > a parallel set of clockdomain dependencies are
> > required that are simililar to OMAP3 but without
> > any IVA dependencies.
> > 
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> > ---

> > diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> > index b84e138..a05a8cb 100644
> > --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
> > +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> > @@ -59,6 +59,12 @@ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
> >  	{ NULL },
> >  };
> >  
> > +static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > +	{ .clkdm_name = "mpu_clkdm", },
> > +	{ .clkdm_name = "wkup_clkdm", },
> > +	{ NULL },
> > +};
> 
> Looks like there are an extra set of commas here, maybe just use:
> 
> static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> 	{ .clkdm_name = "mpu_clkdm" },
> 	{ .clkdm_name = "wkup_clkdm" },
> 	{ NULL },

Yes, there are extra commas but they come from the code I'm copying
and removing iva2_clkdm from.  I was keeping things consistent so I
kept the commas.  Given that, do you still want them removed?
(I'm indifferent.)

> > @@ -366,6 +473,26 @@ static struct clockdomain *clockdomains_omap3430_common[] __initdata = {
> >  	NULL
> >  };
> >  
> > +static struct clockdomain *clockdomains_am35x_common[] __initdata = {
> > +	&wkup_common_clkdm,
> > +	&cm_common_clkdm,
> > +	&prm_common_clkdm,
> > +	&mpu_am35x_clkdm,
> > +	&neon_clkdm,
> > +	&sgx_am35x_clkdm,
> > +	&core_l3_3xxx_clkdm,
> > +	&core_l4_3xxx_clkdm,
> > +	&dss_am35x_clkdm,
> > +	&per_am35x_clkdm,
> > +	&emu_clkdm,
> > +	&usbhost_am35x_clkdm,
> > +	&dpll1_clkdm,
> > +	&dpll3_clkdm,
> > +	&dpll4_clkdm,
> > +	&dpll5_clkdm,
> > +	NULL
> > +};
> 
> Looks like many of these clockdomains are shared with the rest of 
> OMAP3xxx.  Maybe move the shared ones into a common array, remove them 
> from clockdomains_omap3430_common, and in the init function below, first 
> register the shared ones?  That will avoid duplicate listings.

Okay.

Mark
--

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-11 21:55       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 21:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> Hi

Hello & thx for the feedback.

> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The am35x family of SoCs do not have an IVA so
> > a parallel set of clockdomain dependencies are
> > required that are simililar to OMAP3 but without
> > any IVA dependencies.
> > 
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> > ---

> > diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> > index b84e138..a05a8cb 100644
> > --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
> > +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> > @@ -59,6 +59,12 @@ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
> >  	{ NULL },
> >  };
> >  
> > +static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > +	{ .clkdm_name = "mpu_clkdm", },
> > +	{ .clkdm_name = "wkup_clkdm", },
> > +	{ NULL },
> > +};
> 
> Looks like there are an extra set of commas here, maybe just use:
> 
> static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> 	{ .clkdm_name = "mpu_clkdm" },
> 	{ .clkdm_name = "wkup_clkdm" },
> 	{ NULL },

Yes, there are extra commas but they come from the code I'm copying
and removing iva2_clkdm from.  I was keeping things consistent so I
kept the commas.  Given that, do you still want them removed?
(I'm indifferent.)

> > @@ -366,6 +473,26 @@ static struct clockdomain *clockdomains_omap3430_common[] __initdata = {
> >  	NULL
> >  };
> >  
> > +static struct clockdomain *clockdomains_am35x_common[] __initdata = {
> > +	&wkup_common_clkdm,
> > +	&cm_common_clkdm,
> > +	&prm_common_clkdm,
> > +	&mpu_am35x_clkdm,
> > +	&neon_clkdm,
> > +	&sgx_am35x_clkdm,
> > +	&core_l3_3xxx_clkdm,
> > +	&core_l4_3xxx_clkdm,
> > +	&dss_am35x_clkdm,
> > +	&per_am35x_clkdm,
> > +	&emu_clkdm,
> > +	&usbhost_am35x_clkdm,
> > +	&dpll1_clkdm,
> > +	&dpll3_clkdm,
> > +	&dpll4_clkdm,
> > +	&dpll5_clkdm,
> > +	NULL
> > +};
> 
> Looks like many of these clockdomains are shared with the rest of 
> OMAP3xxx.  Maybe move the shared ones into a common array, remove them 
> from clockdomains_omap3430_common, and in the init function below, first 
> register the shared ones?  That will avoid duplicate listings.

Okay.

Mark
--

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

* Re: [PATCH 12/12] arm: omap3: am35x: Register davinci_mdio before davinci_emac
  2012-04-11 21:24     ` Paul Walmsley
@ 2012-04-11 22:00       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:00 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman, Ilya Yanok

On Wed, Apr 11, 2012 at 03:24:05PM -0600, Paul Walmsley wrote:
> cc Ilya
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > Problem:
> > --------
> > When resuming from a Suspend-to-RAM event, the eth0 device
> > (davinci emac/mdio) on am35xx boards wouldn't work and the
> > following error message appeared on the console:
> > 
> > "net eth0: could not connect to phy davinci_mdio-0:00"
> 
> ...
> 
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> > ---
> >  arch/arm/mach-omap2/am35xx-emac.c |   11 ++++++-----
> >  1 file changed, 6 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
> > index 1f97e74..d23bd6c 100644
> > --- a/arch/arm/mach-omap2/am35xx-emac.c
> > +++ b/arch/arm/mach-omap2/am35xx-emac.c
> 
> This is a little off-topic from this patch, but we should get rid of this 
> arch/arm/mach-omap2/am35xx-emac.c file.  These on-chip devices should be 
> registered via the hwmod code.  Looking at 
> arch/arm/mach-omap2/omap_hwmod_3xxx_data.c, I don't see any trace of the 
> EMAC or MDIO in there.  That's where all of these IPSS IP blocks should be 
> declared...

Okay, I'll take a look and see what I can do.

Mark
--

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

* [PATCH 12/12] arm: omap3: am35x: Register davinci_mdio before davinci_emac
@ 2012-04-11 22:00       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:24:05PM -0600, Paul Walmsley wrote:
> cc Ilya
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > Problem:
> > --------
> > When resuming from a Suspend-to-RAM event, the eth0 device
> > (davinci emac/mdio) on am35xx boards wouldn't work and the
> > following error message appeared on the console:
> > 
> > "net eth0: could not connect to phy davinci_mdio-0:00"
> 
> ...
> 
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> > ---
> >  arch/arm/mach-omap2/am35xx-emac.c |   11 ++++++-----
> >  1 file changed, 6 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
> > index 1f97e74..d23bd6c 100644
> > --- a/arch/arm/mach-omap2/am35xx-emac.c
> > +++ b/arch/arm/mach-omap2/am35xx-emac.c
> 
> This is a little off-topic from this patch, but we should get rid of this 
> arch/arm/mach-omap2/am35xx-emac.c file.  These on-chip devices should be 
> registered via the hwmod code.  Looking at 
> arch/arm/mach-omap2/omap_hwmod_3xxx_data.c, I don't see any trace of the 
> EMAC or MDIO in there.  That's where all of these IPSS IP blocks should be 
> declared...

Okay, I'll take a look and see what I can do.

Mark
--

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

* Re: [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-11 21:55       ` Mark A. Greer
@ 2012-04-11 22:04         ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:04 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> 
> > Looks like there are an extra set of commas here, maybe just use:
> > 
> > static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > 	{ .clkdm_name = "mpu_clkdm" },
> > 	{ .clkdm_name = "wkup_clkdm" },
> > 	{ NULL },
> 
> Yes, there are extra commas but they come from the code I'm copying
> and removing iva2_clkdm from.  I was keeping things consistent so I
> kept the commas.  Given that, do you still want them removed?
> (I'm indifferent.)

Yes please.  I realize it's a minor issue, but I'd like to keep the format 
of these files internally consistent.


- Paul

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-11 22:04         ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> 
> > Looks like there are an extra set of commas here, maybe just use:
> > 
> > static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > 	{ .clkdm_name = "mpu_clkdm" },
> > 	{ .clkdm_name = "wkup_clkdm" },
> > 	{ NULL },
> 
> Yes, there are extra commas but they come from the code I'm copying
> and removing iva2_clkdm from.  I was keeping things consistent so I
> kept the commas.  Given that, do you still want them removed?
> (I'm indifferent.)

Yes please.  I realize it's a minor issue, but I'd like to keep the format 
of these files internally consistent.


- Paul

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

* Re: [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 22:17     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:17 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The am35x family of SoCs only support PWRDM_POWER_ON
> and PWRDM_POWER_INACTIVE power states. This causes
> an issue in some areas of the OMAP3 power-related
> code because of assumptions that PWRDM_POWER_RET
> and/or PWRDM_POWER_OFF are always valid states.
> 
> To get am35x SoCs to work properly, add missing support
> for PWRDM_POWER_INACTIVE and remove assumptions that
> PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

Same comments here as on "arm: omap3: am35x: Set proper powerdomain 
states" -- does it even make sense for us to separate out INACTIVE at all 
in this case?  Seems like AM3517/3505 supports powerdomains ON, and that's 
it.  Seems like we can't program INACTIVE to the POWERSTATE bits, nor can 
we read it from those bits?


- Paul

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

* [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support
@ 2012-04-11 22:17     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The am35x family of SoCs only support PWRDM_POWER_ON
> and PWRDM_POWER_INACTIVE power states. This causes
> an issue in some areas of the OMAP3 power-related
> code because of assumptions that PWRDM_POWER_RET
> and/or PWRDM_POWER_OFF are always valid states.
> 
> To get am35x SoCs to work properly, add missing support
> for PWRDM_POWER_INACTIVE and remove assumptions that
> PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
> 
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

Same comments here as on "arm: omap3: am35x: Set proper powerdomain 
states" -- does it even make sense for us to separate out INACTIVE at all 
in this case?  Seems like AM3517/3505 supports powerdomains ON, and that's 
it.  Seems like we can't program INACTIVE to the POWERSTATE bits, nor can 
we read it from those bits?


- Paul

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-11 21:37     ` Paul Walmsley
@ 2012-04-11 22:23       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:23 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
> > which calls omap_sram_idle().  omap_sram_idle() eventually
> > causes a 'wfi' instruction to be executed effectively putting
> > the system to sleep.  It is assumed that an I/O wake-up event
> > will occur to wake the system up again.  This doesn't work on
> > systems that don't support I/O wake-ups (indicated by
> > omap3_has_io_wakeup() returning false).
> > 
> > To handle this, follow the same path in omap3_enter_idle()
> > that would be followed if an interrupt were pending.
> 
> I don't quite understand this patch.  Are you saying that AM3517/3505 
> can't wake from WFI?  That would seem odd.

No, I'm saying that I/O doesn't seem to wake it up from the WFI.
I've learned to not trust the am35x TRM much so I'm pretty much
feeling my way along in the dark.  I do know that without this
patch, the system is extremely slow which I believe is from it
only returning from the WFI because of a timer expiration or
something like that.

> There are other sources of wakeup on the system other than I/O wakeup.  
> I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> RETENTION or OFF.  And as I understand it, neither of those apply to 
> AM3517/3505?

Hmm, its true that RETENTION and OFF aren't supported.  It does wake up
occasionally (as mentioned above) it just seems that I/O doesn't wake
it up.  I may be mistaken.  I'm only going from what I've seen since and
the TRM seems to have lots of errors so I'm not sure what to trust in it.

> Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> should be able to cause the ARM to exit WFI by asserting their 
> SWAKEUP lines and raising their interrupt lines.

Okay, but that doesn't seem to be working.  I'll look some more to see
why they aren't working.

> So this change doesn't seem quite right to me...
> 
> More broadly, if AM3517/3505 only supports powerdomains ON, then you 
> should probably use your own CPUIdle driver that doesn't touch the 
> powerdomain states at all.

Okay, I can do that.

Mark
--

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-11 22:23       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
> > which calls omap_sram_idle().  omap_sram_idle() eventually
> > causes a 'wfi' instruction to be executed effectively putting
> > the system to sleep.  It is assumed that an I/O wake-up event
> > will occur to wake the system up again.  This doesn't work on
> > systems that don't support I/O wake-ups (indicated by
> > omap3_has_io_wakeup() returning false).
> > 
> > To handle this, follow the same path in omap3_enter_idle()
> > that would be followed if an interrupt were pending.
> 
> I don't quite understand this patch.  Are you saying that AM3517/3505 
> can't wake from WFI?  That would seem odd.

No, I'm saying that I/O doesn't seem to wake it up from the WFI.
I've learned to not trust the am35x TRM much so I'm pretty much
feeling my way along in the dark.  I do know that without this
patch, the system is extremely slow which I believe is from it
only returning from the WFI because of a timer expiration or
something like that.

> There are other sources of wakeup on the system other than I/O wakeup.  
> I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> RETENTION or OFF.  And as I understand it, neither of those apply to 
> AM3517/3505?

Hmm, its true that RETENTION and OFF aren't supported.  It does wake up
occasionally (as mentioned above) it just seems that I/O doesn't wake
it up.  I may be mistaken.  I'm only going from what I've seen since and
the TRM seems to have lots of errors so I'm not sure what to trust in it.

> Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> should be able to cause the ARM to exit WFI by asserting their 
> SWAKEUP lines and raising their interrupt lines.

Okay, but that doesn't seem to be working.  I'll look some more to see
why they aren't working.

> So this change doesn't seem quite right to me...
> 
> More broadly, if AM3517/3505 only supports powerdomains ON, then you 
> should probably use your own CPUIdle driver that doesn't touch the 
> powerdomain states at all.

Okay, I can do that.

Mark
--

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

* Re: [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 22:35     ` Kevin Hilman
  -1 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-11 22:35 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, paul, Ranjith Lohithakshan

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
>
> The typical SDRAM Controller Subsystem module (SDRC)
> on TI OMAP3 devices has two submodules: the SDRAM Memory
> Scheduler (SMS) submodule, and the SDRC submodule--the
> 'SDRC' acronym/term is overloaded.  The am35x family of
> devices is different in that it has an EMIF4 submodule
> instead of an SDRC submodule.  The SMS submodules are
> similar, though.
>
> The difference in SDRC/EMIF4 submodules is important because
> omap34xx_cpu_suspend() will ultimately access the submodule's
> registers and the register sets are different.  To support
> the EMIF4 submodule, add the omap3_emif4_do_wfi() routine which
> roughly does for the EMIF4 submodule what omap3_do_wfi() does
> for the SDRC submodule.  This requires omap34xx_cpu_suspend()
> to use a pointer set up in omap_push_sram_idle() so that it
> jumps to the correct omap3*_do_wfi() routine in either SDRAM
> or SRAM.
>
> Credits: arch/arm/mach-omap2/sleep3517.S in TI's am35x SDK
> (05.03.02.00) which appears to be authored by Ranjith Lohithakshan
> <ranjithl@ti.com> was used as a reference.
>
> CC: Ranjith Lohithakshan <ranjithl@ti.com>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

Dumb Q: do you actually need to do the EMIF4 self-refresh control from
SRAM?

The reason I ask is because on OMAP3, we tried going down the path of
not running any of this from SRAM (run it from cache instead.)  However,
due to some errata (c.f. wait_sdrc*, wait_dll_* ...), we had to handle
these errata from SRAM.

Looking at your omap3_emif4_do_wfi, it looks like that's very minimal,
and can probably be prefetched/run from cache.

Kevin


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

* [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
@ 2012-04-11 22:35     ` Kevin Hilman
  0 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-11 22:35 UTC (permalink / raw)
  To: linux-arm-kernel

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
>
> The typical SDRAM Controller Subsystem module (SDRC)
> on TI OMAP3 devices has two submodules: the SDRAM Memory
> Scheduler (SMS) submodule, and the SDRC submodule--the
> 'SDRC' acronym/term is overloaded.  The am35x family of
> devices is different in that it has an EMIF4 submodule
> instead of an SDRC submodule.  The SMS submodules are
> similar, though.
>
> The difference in SDRC/EMIF4 submodules is important because
> omap34xx_cpu_suspend() will ultimately access the submodule's
> registers and the register sets are different.  To support
> the EMIF4 submodule, add the omap3_emif4_do_wfi() routine which
> roughly does for the EMIF4 submodule what omap3_do_wfi() does
> for the SDRC submodule.  This requires omap34xx_cpu_suspend()
> to use a pointer set up in omap_push_sram_idle() so that it
> jumps to the correct omap3*_do_wfi() routine in either SDRAM
> or SRAM.
>
> Credits: arch/arm/mach-omap2/sleep3517.S in TI's am35x SDK
> (05.03.02.00) which appears to be authored by Ranjith Lohithakshan
> <ranjithl@ti.com> was used as a reference.
>
> CC: Ranjith Lohithakshan <ranjithl@ti.com>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

Dumb Q: do you actually need to do the EMIF4 self-refresh control from
SRAM?

The reason I ask is because on OMAP3, we tried going down the path of
not running any of this from SRAM (run it from cache instead.)  However,
due to some errata (c.f. wait_sdrc*, wait_dll_* ...), we had to handle
these errata from SRAM.

Looking at your omap3_emif4_do_wfi, it looks like that's very minimal,
and can probably be prefetched/run from cache.

Kevin

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

* Re: [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 22:36     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:36 UTC (permalink / raw)
  To: Mark A. Greer, Ranjith Lohithakshan; +Cc: linux-omap, linux-arm-kernel, khilman

Hi

just a few comments based on a quick look

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> diff --git a/arch/arm/mach-omap2/emif4.h b/arch/arm/mach-omap2/emif4.h
> new file mode 100644
> index 0000000..0126af3
> --- /dev/null
> +++ b/arch/arm/mach-omap2/emif4.h
> @@ -0,0 +1,24 @@
> +/*
> + * SDRC Module, EMIF4 Submodule Definitions
> + *
> + * Author: Mark A. Greer <mgreer@animalcreek.com>
> + *
> + * Copyright (c) 2012 by Animal Creek Technologies, Inc.
> + *
> + * 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.
> + */
> +#ifndef ____ASM_ARCH_EMIF4_H
> +#define ____ASM_ARCH_EMIF4_H
> +
> +#ifdef __ASSEMBLER__
> +
> +#define OMAP34XX_EMIF4_REGADDR(reg) \
> +		OMAP2_L3_IO_ADDRESS(OMAP343X_EMIF4_BASE + (reg))
> +
> +#endif
> +
> +#define EMIF4_PWR_MGMT_CTRL	0x38
> +
> +#endif
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index 36fa90b..ab1262b 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -85,10 +85,13 @@ extern unsigned int omap24xx_cpu_suspend_sz;
>  /* 3xxx */
>  extern void omap34xx_cpu_suspend(int save_state);
>  
> -/* omap3_do_wfi function pointer and size, for copy to SRAM */
> +/* omap3*_do_wfi function pointers and sizes, for copy to SRAM */
>  extern void omap3_do_wfi(void);
>  extern unsigned int omap3_do_wfi_sz;
> -/* ... and its pointer from SRAM after copy */
> +extern void omap3_emif4_do_wfi(void);
> +extern unsigned int omap3_emif4_do_wfi_sz;
> +/* ... and pointers when in SDRAM and in SRAM after copy */
> +extern void (*omap3_do_wfi_sdram)(void);
>  extern void (*omap3_do_wfi_sram)(void);
>  
>  /* save_secure_ram_context function pointer and size, for copy to SRAM */
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index 00c4abe..c1dee25 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -66,6 +66,7 @@ struct power_state {
>  static LIST_HEAD(pwrst_list);
>  
>  static int (*_omap_save_secure_sram)(u32 *addr);
> +void (*omap3_do_wfi_sdram)(void);
>  void (*omap3_do_wfi_sram)(void);
>  
>  static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
> @@ -694,7 +695,15 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
>   */
>  void omap_push_sram_idle(void)
>  {
> -	omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
> +	if (omap3_has_sdrc_emif4()) {
> +		omap3_do_wfi_sdram = omap3_emif4_do_wfi;
> +		omap3_do_wfi_sram = omap_sram_push(omap3_emif4_do_wfi,
> +				omap3_emif4_do_wfi_sz);
> +	} else {
> +		omap3_do_wfi_sdram = omap3_do_wfi;
> +		omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi,
> +				omap3_do_wfi_sz);
> +	}
>  
>  	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
>  		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
> diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
> index 1f62f23..22aac4c 100644
> --- a/arch/arm/mach-omap2/sleep34xx.S
> +++ b/arch/arm/mach-omap2/sleep34xx.S
> @@ -33,6 +33,7 @@
>  #include "cm2xxx_3xxx.h"
>  #include "prm2xxx_3xxx.h"
>  #include "sdrc.h"
> +#include "emif4.h"
>  #include "control.h"
>  
>  /*
> @@ -67,6 +68,8 @@
>  #define SDRC_DLLA_STATUS_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
>  #define SDRC_DLLA_CTRL_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
>  
> +#define PWR_MGMT_CTRL_V		OMAP34XX_EMIF4_REGADDR(EMIF4_PWR_MGMT_CTRL)
> +
>  /*
>   * This file needs be built unconditionally as ARM to interoperate correctly
>   * with non-Thumb-2-capable firmware.
> @@ -163,8 +166,12 @@ ENTRY(omap34xx_cpu_suspend)
>  	 */
>  
>  	/*
> -	 * For OFF mode: save context and jump to WFI in SDRAM (omap3_do_wfi)
> -	 * For non-OFF modes: jump to the WFI code in SRAM (omap3_do_wfi_sram)
> +	 * For OFF mode: save context and jump to WFI in SDRAM
> +	 * (omap3_do_wfi_sdram). For non-OFF modes: jump to the WFI code
> +	 * in SRAM (omap3_do_wfi_sram).  Note that omap_push_sram_idle()
> +	 * will have set omap3_do_wfi_sdram and omap3_do_wfi_sram to the
> +	 * SDRAM and SRAM addresses of either omap3_do_wfi or
> +	 * omap3_emif4_do_wfi depending on the type of SDRC submodule.
>  	 */
>  	ldr	r4, omap3_do_wfi_sram_addr
>  	ldr	r5, [r4]
> @@ -216,11 +223,15 @@ save_context_wfi:
>   THUMB(	nop		)
>  	.arm
>  
> -	b	omap3_do_wfi
> +	ldr	r4, omap3_do_wfi_sdram_addr
> +	ldr	r5, [r4]
> +	bx	r5			@  jump to the WFI code in SRAM
>  
>  /*
>   * Local variables
>   */
> +omap3_do_wfi_sdram_addr:
> +	.word omap3_do_wfi_sdram
>  omap3_do_wfi_sram_addr:
>  	.word omap3_do_wfi_sram
>  kernel_flush:
> @@ -232,8 +243,7 @@ kernel_flush:
>   */
>  
>  /*
> - * Do WFI instruction
> - * Includes the resume path for non-OFF modes
> + * Do WFI instruction (SDRC module has SDRC submodule)
>   *
>   * This code gets copied to internal SRAM and is accessible
>   * from both SDRAM and SRAM:
> @@ -391,6 +401,52 @@ wait_dll_lock_counter:
>  ENTRY(omap3_do_wfi_sz)
>  	.word	. - omap3_do_wfi
>  
> +/*
> + * Do WFI instruction (SDRC module has EMIF4 submodule)
> + *
> + * This code gets copied to internal SRAM and is accessible
> + * from both SDRAM and SRAM:
> + * - executed from SRAM for non-off modes (omap3_emif4_do_wfi_sram),
> + * - executed from SDRAM for OFF mode (omap3_emif4_do_wfi).
> + */
> +	.align	3
> +ENTRY(omap3_emif4_do_wfi)
> +	/* Put EMIF in self-refresh */

Hmm, I guess this comment isn't quite right; it just tells it to go to 
self-refresh when it's "idle" ? (see below)

> +	ldr     r4, pwr_mgmt_ctrl
> +	ldr     r5, [r4]
> +	orr     r5, r5, #0x200

Maybe use a macro here in place of the #0x200 to indicate what it's trying 
to set...

Do you happen to know what "idle" means in the context of SPRUGR0B Section 
9.2.3.4.5.1 "SDRAM Self-Refresh Mode" ?  Is it referring to 
target module-level idle, e.g. SIdleReq; or is it referring to 
an internal definition of idle, e.g., something like "no reads or writes 
from/to the SDRAM" ?  Am wondering if this should just be set once during 
EMIF initialization.

> +	str     r5, [r4]

Might be good to do a readback after this to ensure that the store has 
made it to the EMIF.

Also, scanning SPRUGR0B, it looks like this setting is dependent partially 
on the REG_PM_TIM field in the same register.  Might be good to set 
REG_PM_TIM during EMIF init to avoid any bootloader dependency.

> +
> +	dsb
> +	dmb
> +
> +	wfi
> +
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop

Are these NOPs necessary?  Is the number of NOPs dependent on CPU or bus 
speed or some ARM parameter?

> +
> +	/* Take EMIF out of self-refresh */

Looks like the EMIF will take the RAM out of self-refresh automatically 
upon an access... so maybe this comment might be better put as "Prevent 
EMIF from entering self-refresh" or something similar?

> +	ldr     r4, pwr_mgmt_ctrl
> +	ldr     r5, [r4]
> +	bic     r5, r5, #0x200
> +	str     r5, [r4]
> +
> +	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
> +
> +pwr_mgmt_ctrl:
> +	.word   PWR_MGMT_CTRL_V
> +ENDPROC(omap3_emif4_do_wfi)
> +ENTRY(omap3_emif4_do_wfi_sz)
> +	.word	. - omap3_emif4_do_wfi
> +
>  
>  /*
>   * ==============================
> @@ -564,6 +620,9 @@ l2dis_3630:
>  /*
>   * This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0
>   * Copied to and run from SRAM in order to reconfigure the SDRC parameters.
> + *
> + * Note: Never call this routine when running on an am35x device since it
> + *  has an EMIF4 submodule instead of the standard SDRC submodule.
>   */
>  	.text
>  	.align	3
> diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
> index 0d818ac..3a84520 100644
> --- a/arch/arm/plat-omap/include/plat/omap34xx.h
> +++ b/arch/arm/plat-omap/include/plat/omap34xx.h
> @@ -42,6 +42,7 @@
>  #define OMAP3430_PRM_BASE	0x48306800
>  #define OMAP343X_SMS_BASE	0x6C000000
>  #define OMAP343X_SDRC_BASE	0x6D000000
> +#define OMAP343X_EMIF4_BASE	0x6D000000
>  #define OMAP34XX_GPMC_BASE	0x6E000000
>  #define OMAP343X_SCM_BASE	0x48002000
>  #define OMAP343X_CTRL_BASE	OMAP343X_SCM_BASE
> -- 
> 1.7.9.4
> 


- Paul

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

* [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
@ 2012-04-11 22:36     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

just a few comments based on a quick look

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> diff --git a/arch/arm/mach-omap2/emif4.h b/arch/arm/mach-omap2/emif4.h
> new file mode 100644
> index 0000000..0126af3
> --- /dev/null
> +++ b/arch/arm/mach-omap2/emif4.h
> @@ -0,0 +1,24 @@
> +/*
> + * SDRC Module, EMIF4 Submodule Definitions
> + *
> + * Author: Mark A. Greer <mgreer@animalcreek.com>
> + *
> + * Copyright (c) 2012 by Animal Creek Technologies, Inc.
> + *
> + * 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.
> + */
> +#ifndef ____ASM_ARCH_EMIF4_H
> +#define ____ASM_ARCH_EMIF4_H
> +
> +#ifdef __ASSEMBLER__
> +
> +#define OMAP34XX_EMIF4_REGADDR(reg) \
> +		OMAP2_L3_IO_ADDRESS(OMAP343X_EMIF4_BASE + (reg))
> +
> +#endif
> +
> +#define EMIF4_PWR_MGMT_CTRL	0x38
> +
> +#endif
> diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
> index 36fa90b..ab1262b 100644
> --- a/arch/arm/mach-omap2/pm.h
> +++ b/arch/arm/mach-omap2/pm.h
> @@ -85,10 +85,13 @@ extern unsigned int omap24xx_cpu_suspend_sz;
>  /* 3xxx */
>  extern void omap34xx_cpu_suspend(int save_state);
>  
> -/* omap3_do_wfi function pointer and size, for copy to SRAM */
> +/* omap3*_do_wfi function pointers and sizes, for copy to SRAM */
>  extern void omap3_do_wfi(void);
>  extern unsigned int omap3_do_wfi_sz;
> -/* ... and its pointer from SRAM after copy */
> +extern void omap3_emif4_do_wfi(void);
> +extern unsigned int omap3_emif4_do_wfi_sz;
> +/* ... and pointers when in SDRAM and in SRAM after copy */
> +extern void (*omap3_do_wfi_sdram)(void);
>  extern void (*omap3_do_wfi_sram)(void);
>  
>  /* save_secure_ram_context function pointer and size, for copy to SRAM */
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index 00c4abe..c1dee25 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -66,6 +66,7 @@ struct power_state {
>  static LIST_HEAD(pwrst_list);
>  
>  static int (*_omap_save_secure_sram)(u32 *addr);
> +void (*omap3_do_wfi_sdram)(void);
>  void (*omap3_do_wfi_sram)(void);
>  
>  static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
> @@ -694,7 +695,15 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
>   */
>  void omap_push_sram_idle(void)
>  {
> -	omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
> +	if (omap3_has_sdrc_emif4()) {
> +		omap3_do_wfi_sdram = omap3_emif4_do_wfi;
> +		omap3_do_wfi_sram = omap_sram_push(omap3_emif4_do_wfi,
> +				omap3_emif4_do_wfi_sz);
> +	} else {
> +		omap3_do_wfi_sdram = omap3_do_wfi;
> +		omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi,
> +				omap3_do_wfi_sz);
> +	}
>  
>  	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
>  		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
> diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
> index 1f62f23..22aac4c 100644
> --- a/arch/arm/mach-omap2/sleep34xx.S
> +++ b/arch/arm/mach-omap2/sleep34xx.S
> @@ -33,6 +33,7 @@
>  #include "cm2xxx_3xxx.h"
>  #include "prm2xxx_3xxx.h"
>  #include "sdrc.h"
> +#include "emif4.h"
>  #include "control.h"
>  
>  /*
> @@ -67,6 +68,8 @@
>  #define SDRC_DLLA_STATUS_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
>  #define SDRC_DLLA_CTRL_V	OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
>  
> +#define PWR_MGMT_CTRL_V		OMAP34XX_EMIF4_REGADDR(EMIF4_PWR_MGMT_CTRL)
> +
>  /*
>   * This file needs be built unconditionally as ARM to interoperate correctly
>   * with non-Thumb-2-capable firmware.
> @@ -163,8 +166,12 @@ ENTRY(omap34xx_cpu_suspend)
>  	 */
>  
>  	/*
> -	 * For OFF mode: save context and jump to WFI in SDRAM (omap3_do_wfi)
> -	 * For non-OFF modes: jump to the WFI code in SRAM (omap3_do_wfi_sram)
> +	 * For OFF mode: save context and jump to WFI in SDRAM
> +	 * (omap3_do_wfi_sdram). For non-OFF modes: jump to the WFI code
> +	 * in SRAM (omap3_do_wfi_sram).  Note that omap_push_sram_idle()
> +	 * will have set omap3_do_wfi_sdram and omap3_do_wfi_sram to the
> +	 * SDRAM and SRAM addresses of either omap3_do_wfi or
> +	 * omap3_emif4_do_wfi depending on the type of SDRC submodule.
>  	 */
>  	ldr	r4, omap3_do_wfi_sram_addr
>  	ldr	r5, [r4]
> @@ -216,11 +223,15 @@ save_context_wfi:
>   THUMB(	nop		)
>  	.arm
>  
> -	b	omap3_do_wfi
> +	ldr	r4, omap3_do_wfi_sdram_addr
> +	ldr	r5, [r4]
> +	bx	r5			@  jump to the WFI code in SRAM
>  
>  /*
>   * Local variables
>   */
> +omap3_do_wfi_sdram_addr:
> +	.word omap3_do_wfi_sdram
>  omap3_do_wfi_sram_addr:
>  	.word omap3_do_wfi_sram
>  kernel_flush:
> @@ -232,8 +243,7 @@ kernel_flush:
>   */
>  
>  /*
> - * Do WFI instruction
> - * Includes the resume path for non-OFF modes
> + * Do WFI instruction (SDRC module has SDRC submodule)
>   *
>   * This code gets copied to internal SRAM and is accessible
>   * from both SDRAM and SRAM:
> @@ -391,6 +401,52 @@ wait_dll_lock_counter:
>  ENTRY(omap3_do_wfi_sz)
>  	.word	. - omap3_do_wfi
>  
> +/*
> + * Do WFI instruction (SDRC module has EMIF4 submodule)
> + *
> + * This code gets copied to internal SRAM and is accessible
> + * from both SDRAM and SRAM:
> + * - executed from SRAM for non-off modes (omap3_emif4_do_wfi_sram),
> + * - executed from SDRAM for OFF mode (omap3_emif4_do_wfi).
> + */
> +	.align	3
> +ENTRY(omap3_emif4_do_wfi)
> +	/* Put EMIF in self-refresh */

Hmm, I guess this comment isn't quite right; it just tells it to go to 
self-refresh when it's "idle" ? (see below)

> +	ldr     r4, pwr_mgmt_ctrl
> +	ldr     r5, [r4]
> +	orr     r5, r5, #0x200

Maybe use a macro here in place of the #0x200 to indicate what it's trying 
to set...

Do you happen to know what "idle" means in the context of SPRUGR0B Section 
9.2.3.4.5.1 "SDRAM Self-Refresh Mode" ?  Is it referring to 
target module-level idle, e.g. SIdleReq; or is it referring to 
an internal definition of idle, e.g., something like "no reads or writes 
from/to the SDRAM" ?  Am wondering if this should just be set once during 
EMIF initialization.

> +	str     r5, [r4]

Might be good to do a readback after this to ensure that the store has 
made it to the EMIF.

Also, scanning SPRUGR0B, it looks like this setting is dependent partially 
on the REG_PM_TIM field in the same register.  Might be good to set 
REG_PM_TIM during EMIF init to avoid any bootloader dependency.

> +
> +	dsb
> +	dmb
> +
> +	wfi
> +
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop

Are these NOPs necessary?  Is the number of NOPs dependent on CPU or bus 
speed or some ARM parameter?

> +
> +	/* Take EMIF out of self-refresh */

Looks like the EMIF will take the RAM out of self-refresh automatically 
upon an access... so maybe this comment might be better put as "Prevent 
EMIF from entering self-refresh" or something similar?

> +	ldr     r4, pwr_mgmt_ctrl
> +	ldr     r5, [r4]
> +	bic     r5, r5, #0x200
> +	str     r5, [r4]
> +
> +	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
> +
> +pwr_mgmt_ctrl:
> +	.word   PWR_MGMT_CTRL_V
> +ENDPROC(omap3_emif4_do_wfi)
> +ENTRY(omap3_emif4_do_wfi_sz)
> +	.word	. - omap3_emif4_do_wfi
> +
>  
>  /*
>   * ==============================
> @@ -564,6 +620,9 @@ l2dis_3630:
>  /*
>   * This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0
>   * Copied to and run from SRAM in order to reconfigure the SDRC parameters.
> + *
> + * Note: Never call this routine when running on an am35x device since it
> + *  has an EMIF4 submodule instead of the standard SDRC submodule.
>   */
>  	.text
>  	.align	3
> diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
> index 0d818ac..3a84520 100644
> --- a/arch/arm/plat-omap/include/plat/omap34xx.h
> +++ b/arch/arm/plat-omap/include/plat/omap34xx.h
> @@ -42,6 +42,7 @@
>  #define OMAP3430_PRM_BASE	0x48306800
>  #define OMAP343X_SMS_BASE	0x6C000000
>  #define OMAP343X_SDRC_BASE	0x6D000000
> +#define OMAP343X_EMIF4_BASE	0x6D000000
>  #define OMAP34XX_GPMC_BASE	0x6E000000
>  #define OMAP343X_SCM_BASE	0x48002000
>  #define OMAP343X_CTRL_BASE	OMAP343X_SCM_BASE
> -- 
> 1.7.9.4
> 


- Paul

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

* Re: [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
  2012-04-11 21:53     ` Paul Walmsley
@ 2012-04-11 22:40       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:40 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 03:53:30PM -0600, Paul Walmsley wrote:
> Hi
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The am35x family of SoCs only support PWRSTS_ON
> > and PWRSTS_INACTIVE states so create a new set
> > of powerdomain structures that ensure that only
> > the ON and INACTIVE states are entered.
> 
> I'm still unsure what we should do about this INACTIVE state.  As far as I 
> can tell, it does not actually represent a distinct powerdomain state on 
> OMAP3.  We can't write it to the PM_PWSTCTRL_*.POWERSTATE bits, since that 
> value is marked as "reserved".  And SPRUGR0B, the AM3517/3505 TRM, 
> explicitly states "This register should not be programmed with reserved 
> values of bit fields for proper functioning of power state control."
> Of course SPRUGR0B also claims that AM3517/3505 supports RETENTION, so 
> that is relatively confusing.

Yep.  You read one section which tells you the device doesn't support
such-and-such then it goes on for pages describing how it works.  I play
with the hardware and the registers are there so it seems like it should
work.  Its been an "adventure". :)

> OMAP4 PRCM actually does seem to support powerdomain INACTIVE state, 
> although it does not actually seem to represent a separate state.  As I 
> understand it, it simply allows the clockdomains in the powerdomain to 
> transitioning from the ACTIVE state into the INACTIVE state.  In other 
> words, it doesn't affect the powerdomain power state at all.  And on OMAP4 
> it's referred to as the ON-INACTIVE state, to clarify that it is simply a 
> variant of the ON state.  I wish they had just added a separate bit for 
> this; it would have avoided some frustration...
> 
> Anyway, my question is this: is there any point at all to defining the 
> INACTIVE state for 3517/3505, given that it apparently cannot be read 
> from, nor written to the PRCM hardware?

Great question and I really don't know the answer--its too hard to know
what's for real and what isn't in the TRM.  Maybe it is best to get rid
of INACTIVE and just leave everything ON.

Mark
--

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

* [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
@ 2012-04-11 22:40       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:53:30PM -0600, Paul Walmsley wrote:
> Hi
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The am35x family of SoCs only support PWRSTS_ON
> > and PWRSTS_INACTIVE states so create a new set
> > of powerdomain structures that ensure that only
> > the ON and INACTIVE states are entered.
> 
> I'm still unsure what we should do about this INACTIVE state.  As far as I 
> can tell, it does not actually represent a distinct powerdomain state on 
> OMAP3.  We can't write it to the PM_PWSTCTRL_*.POWERSTATE bits, since that 
> value is marked as "reserved".  And SPRUGR0B, the AM3517/3505 TRM, 
> explicitly states "This register should not be programmed with reserved 
> values of bit fields for proper functioning of power state control."
> Of course SPRUGR0B also claims that AM3517/3505 supports RETENTION, so 
> that is relatively confusing.

Yep.  You read one section which tells you the device doesn't support
such-and-such then it goes on for pages describing how it works.  I play
with the hardware and the registers are there so it seems like it should
work.  Its been an "adventure". :)

> OMAP4 PRCM actually does seem to support powerdomain INACTIVE state, 
> although it does not actually seem to represent a separate state.  As I 
> understand it, it simply allows the clockdomains in the powerdomain to 
> transitioning from the ACTIVE state into the INACTIVE state.  In other 
> words, it doesn't affect the powerdomain power state at all.  And on OMAP4 
> it's referred to as the ON-INACTIVE state, to clarify that it is simply a 
> variant of the ON state.  I wish they had just added a separate bit for 
> this; it would have avoided some frustration...
> 
> Anyway, my question is this: is there any point at all to defining the 
> INACTIVE state for 3517/3505, given that it apparently cannot be read 
> from, nor written to the PRCM hardware?

Great question and I really don't know the answer--its too hard to know
what's for real and what isn't in the TRM.  Maybe it is best to get rid
of INACTIVE and just leave everything ON.

Mark
--

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

* Re: [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 22:46     ` Kevin Hilman
  -1 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-11 22:46 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, paul

Hi Mark,

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
>
> Typical OMAP3 SoCs have four power domain states: ON,
> INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
> has only two states: ON and INACTIVE.  To distinguish which
> set of states the current device has, add the 'OMAP3_HAS_PWROFF'
> feature.  When that feature/bit is set, the device supports the
> RETENTION and OFF states; otherwise, it doesn't.
>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

Paul has mentioned this already, but the same applies here: We shouldn't
be using SoC-global feature flag for this.   We already have per-pwrdm
flags that indicate what states a given powerdomain suports (see .pwrsts
field.)

Wherever we have blind writes to next powerstates that assume support
for RET/OFF is present, those should probably use a helper function from
the powerdomain code that checks if that state is even supported.

Jean's work on functional powerstates will probably help here if you
really need to support INACTIVE.  However, Paul may be right in that you
might just start with supporing ON only, and validate that module-level
wakups acutally work.

Kevin

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

* [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
@ 2012-04-11 22:46     ` Kevin Hilman
  0 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-11 22:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
>
> Typical OMAP3 SoCs have four power domain states: ON,
> INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
> has only two states: ON and INACTIVE.  To distinguish which
> set of states the current device has, add the 'OMAP3_HAS_PWROFF'
> feature.  When that feature/bit is set, the device supports the
> RETENTION and OFF states; otherwise, it doesn't.
>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

Paul has mentioned this already, but the same applies here: We shouldn't
be using SoC-global feature flag for this.   We already have per-pwrdm
flags that indicate what states a given powerdomain suports (see .pwrsts
field.)

Wherever we have blind writes to next powerstates that assume support
for RET/OFF is present, those should probably use a helper function from
the powerdomain code that checks if that state is even supported.

Jean's work on functional powerstates will probably help here if you
really need to support INACTIVE.  However, Paul may be right in that you
might just start with supporing ON only, and validate that module-level
wakups acutally work.

Kevin

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-11 22:23       ` Mark A. Greer
@ 2012-04-11 22:47         ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:47 UTC (permalink / raw)
  To: Mark A. Greer, govindraj.raja; +Cc: linux-omap, linux-arm-kernel, khilman

cc Govindraj

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
>
> > I don't quite understand this patch.  Are you saying that AM3517/3505 
> > can't wake from WFI?  That would seem odd.
> 
> No, I'm saying that I/O doesn't seem to wake it up from the WFI.
> I've learned to not trust the am35x TRM much so I'm pretty much
> feeling my way along in the dark.

Hehe, no worries, just curious.

> I do know that without this patch, the system is extremely slow which I 
> believe is from it only returning from the WFI because of a timer 
> expiration or something like that.

How are you trying to wake it up -- from an incoming character via 
the UART?

Does the system pause in the middle of UART transmits, or does it get the 
transmit buffers out cleanly and just not respond promptly to incoming 
characters?

> > There are other sources of wakeup on the system other than I/O wakeup.  
> > I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> > RETENTION or OFF.  And as I understand it, neither of those apply to 
> > AM3517/3505?
> 
> Hmm, its true that RETENTION and OFF aren't supported.  It does wake up
> occasionally (as mentioned above) it just seems that I/O doesn't wake
> it up.  I may be mistaken.  I'm only going from what I've seen since and
> the TRM seems to have lots of errors so I'm not sure what to trust in it.

OK no problem, just trying to understand what's going on.  Sounds like 
you've gotten tossed into the deep end :-)

> > Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> > should be able to cause the ARM to exit WFI by asserting their 
> > SWAKEUP lines and raising their interrupt lines.
> 
> Okay, but that doesn't seem to be working.  I'll look some more to see
> why they aren't working.

There could be a hidden dependency on I/O wakeup being present in the UART 
driver. We've been going through some UART driver angst recently...


- Paul

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-11 22:47         ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:47 UTC (permalink / raw)
  To: linux-arm-kernel

cc Govindraj

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
>
> > I don't quite understand this patch.  Are you saying that AM3517/3505 
> > can't wake from WFI?  That would seem odd.
> 
> No, I'm saying that I/O doesn't seem to wake it up from the WFI.
> I've learned to not trust the am35x TRM much so I'm pretty much
> feeling my way along in the dark.

Hehe, no worries, just curious.

> I do know that without this patch, the system is extremely slow which I 
> believe is from it only returning from the WFI because of a timer 
> expiration or something like that.

How are you trying to wake it up -- from an incoming character via 
the UART?

Does the system pause in the middle of UART transmits, or does it get the 
transmit buffers out cleanly and just not respond promptly to incoming 
characters?

> > There are other sources of wakeup on the system other than I/O wakeup.  
> > I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> > RETENTION or OFF.  And as I understand it, neither of those apply to 
> > AM3517/3505?
> 
> Hmm, its true that RETENTION and OFF aren't supported.  It does wake up
> occasionally (as mentioned above) it just seems that I/O doesn't wake
> it up.  I may be mistaken.  I'm only going from what I've seen since and
> the TRM seems to have lots of errors so I'm not sure what to trust in it.

OK no problem, just trying to understand what's going on.  Sounds like 
you've gotten tossed into the deep end :-)

> > Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> > should be able to cause the ARM to exit WFI by asserting their 
> > SWAKEUP lines and raising their interrupt lines.
> 
> Okay, but that doesn't seem to be working.  I'll look some more to see
> why they aren't working.

There could be a hidden dependency on I/O wakeup being present in the UART 
driver. We've been going through some UART driver angst recently...


- Paul

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

* Re: [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-11 22:04         ` Paul Walmsley
@ 2012-04-11 22:49           ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:49 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 04:04:44PM -0600, Paul Walmsley wrote:
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> > 
> > > Looks like there are an extra set of commas here, maybe just use:
> > > 
> > > static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > > 	{ .clkdm_name = "mpu_clkdm" },
> > > 	{ .clkdm_name = "wkup_clkdm" },
> > > 	{ NULL },
> > 
> > Yes, there are extra commas but they come from the code I'm copying
> > and removing iva2_clkdm from.  I was keeping things consistent so I
> > kept the commas.  Given that, do you still want them removed?
> > (I'm indifferent.)
> 
> Yes please.  I realize it's a minor issue, but I'd like to keep the format 
> of these files internally consistent.

Hrm, did you meant "No thanks"?  As in, leave the commas there since
that's what the code that is already there is like?

Mark
--

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-11 22:49           ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 04:04:44PM -0600, Paul Walmsley wrote:
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> > 
> > > Looks like there are an extra set of commas here, maybe just use:
> > > 
> > > static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > > 	{ .clkdm_name = "mpu_clkdm" },
> > > 	{ .clkdm_name = "wkup_clkdm" },
> > > 	{ NULL },
> > 
> > Yes, there are extra commas but they come from the code I'm copying
> > and removing iva2_clkdm from.  I was keeping things consistent so I
> > kept the commas.  Given that, do you still want them removed?
> > (I'm indifferent.)
> 
> Yes please.  I realize it's a minor issue, but I'd like to keep the format 
> of these files internally consistent.

Hrm, did you meant "No thanks"?  As in, leave the commas there since
that's what the code that is already there is like?

Mark
--

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

* Re: [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
  2012-04-11 21:29     ` Paul Walmsley
@ 2012-04-11 22:50       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:50 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 03:29:00PM -0600, Paul Walmsley wrote:
> Hi
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The typical SDRAM Controller Subsystem module (SDRC)
> > on TI OMAP3 devices has two submodules: the SDRAM Memory
> > Scheduler (SMS) submodule, and the SDRC submodule--the
> > 'SDRC' acronym/term is overloaded.  The am35x family of
> > devices is different in that it has an EMIF4 submodule
> > instead of an SDRC submodule.  The SMS submodules are
> > similar, though.
> > 
> > To allow code to determine whether the current device has an
> > SDRC submodule or and EMIF4 submodule, add the 'OMAP3_HAS_SDRC_EMIF4'
> > feature and set it when running on an am35x SoC.
> > 
> > So when:
> > - omap3_has_sdrc() returns true: the system has an SDRC module
> > 	consisting of an SMS submodule and either an SDRC submodule
> > 	or an EMIF4 submodule.
> > - omap3_has_sdrc_emif4() returns true: the system has an EMIF4
> > 	submodule.  It is assumed that this feature will only be
> > 	checked when there is an SDRC module present (i.e., when
> > 	omap3_has_sdrc() would return true).
> > 
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> We need to stop declaring these feature flags for IP blocks, and use the 
> hwmod code instead.  hwmod code provides omap_hwmod_lookup() which can be 
> used to determine whether a given IP block exists on a particular chip, so 
> I don't think there's any need for omap3_has_sdrc(), 
> omap3_has_sdrc_emif4(), omap3_has_iva(), omap3_has_isp(), etc.
> 
> So it would be best if you could simply add an EMIF hwmod data entry in 
> omap_hwmod_3xxx_data.c.

Okay.

Mark
--

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

* [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
@ 2012-04-11 22:50       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 22:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:29:00PM -0600, Paul Walmsley wrote:
> Hi
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The typical SDRAM Controller Subsystem module (SDRC)
> > on TI OMAP3 devices has two submodules: the SDRAM Memory
> > Scheduler (SMS) submodule, and the SDRC submodule--the
> > 'SDRC' acronym/term is overloaded.  The am35x family of
> > devices is different in that it has an EMIF4 submodule
> > instead of an SDRC submodule.  The SMS submodules are
> > similar, though.
> > 
> > To allow code to determine whether the current device has an
> > SDRC submodule or and EMIF4 submodule, add the 'OMAP3_HAS_SDRC_EMIF4'
> > feature and set it when running on an am35x SoC.
> > 
> > So when:
> > - omap3_has_sdrc() returns true: the system has an SDRC module
> > 	consisting of an SMS submodule and either an SDRC submodule
> > 	or an EMIF4 submodule.
> > - omap3_has_sdrc_emif4() returns true: the system has an EMIF4
> > 	submodule.  It is assumed that this feature will only be
> > 	checked when there is an SDRC module present (i.e., when
> > 	omap3_has_sdrc() would return true).
> > 
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> We need to stop declaring these feature flags for IP blocks, and use the 
> hwmod code instead.  hwmod code provides omap_hwmod_lookup() which can be 
> used to determine whether a given IP block exists on a particular chip, so 
> I don't think there's any need for omap3_has_sdrc(), 
> omap3_has_sdrc_emif4(), omap3_has_iva(), omap3_has_isp(), etc.
> 
> So it would be best if you could simply add an EMIF hwmod data entry in 
> omap_hwmod_3xxx_data.c.

Okay.

Mark
--

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

* Re: [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 22:54     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:54 UTC (permalink / raw)
  To: Mark A. Greer, Ranjith Lohithakshan; +Cc: linux-omap, linux-arm-kernel, khilman


One other minor thing I just noticed...

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> +ENTRY(omap3_emif4_do_wfi)
> +	/* Put EMIF in self-refresh */
> +	ldr     r4, pwr_mgmt_ctrl
> +	ldr     r5, [r4]
> +	orr     r5, r5, #0x200
> +	str     r5, [r4]
> +
> +	dsb
> +	dmb
> +
> +	wfi
> +
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +
> +	/* Take EMIF out of self-refresh */
> +	ldr     r4, pwr_mgmt_ctrl
> +	ldr     r5, [r4]

Looks like the above two instructions might not be needed -- they should 
be preserved across the WFI ?

> +	bic     r5, r5, #0x200
> +	str     r5, [r4]
> +
> +	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
> +
> +pwr_mgmt_ctrl:
> +	.word   PWR_MGMT_CTRL_V
> +ENDPROC(omap3_emif4_do_wfi)
> +ENTRY(omap3_emif4_do_wfi_sz)
> +	.word	. - omap3_emif4_do_wfi
> +


- Paul

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

* [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
@ 2012-04-11 22:54     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:54 UTC (permalink / raw)
  To: linux-arm-kernel


One other minor thing I just noticed...

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> +ENTRY(omap3_emif4_do_wfi)
> +	/* Put EMIF in self-refresh */
> +	ldr     r4, pwr_mgmt_ctrl
> +	ldr     r5, [r4]
> +	orr     r5, r5, #0x200
> +	str     r5, [r4]
> +
> +	dsb
> +	dmb
> +
> +	wfi
> +
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +	nop
> +
> +	/* Take EMIF out of self-refresh */
> +	ldr     r4, pwr_mgmt_ctrl
> +	ldr     r5, [r4]

Looks like the above two instructions might not be needed -- they should 
be preserved across the WFI ?

> +	bic     r5, r5, #0x200
> +	str     r5, [r4]
> +
> +	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
> +
> +pwr_mgmt_ctrl:
> +	.word   PWR_MGMT_CTRL_V
> +ENDPROC(omap3_emif4_do_wfi)
> +ENTRY(omap3_emif4_do_wfi_sz)
> +	.word	. - omap3_emif4_do_wfi
> +


- Paul

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

* Re: [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 22:56     ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:56 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The typical SDRAM Controller Subsystem module (SDRC)
> on TI OMAP3 devices has two submodules: the SDRAM Memory
> Scheduler (SMS) submodule, and the SDRC submodule--the
> 'SDRC' acronym/term is overloaded.  The am35x family of
> devices is different in that it has an EMIF4 submodule
> instead of an SDRC submodule.  The SMS submodules are
> similar, though.

By the way, thanks for the great patch descriptions; they are very 
helpful.


- Paul

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

* [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
@ 2012-04-11 22:56     ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 22:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> The typical SDRAM Controller Subsystem module (SDRC)
> on TI OMAP3 devices has two submodules: the SDRAM Memory
> Scheduler (SMS) submodule, and the SDRC submodule--the
> 'SDRC' acronym/term is overloaded.  The am35x family of
> devices is different in that it has an EMIF4 submodule
> instead of an SDRC submodule.  The SMS submodules are
> similar, though.

By the way, thanks for the great patch descriptions; they are very 
helpful.


- Paul

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-11 22:47         ` Paul Walmsley
@ 2012-04-11 23:08           ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:08 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: govindraj.raja, linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 04:47:31PM -0600, Paul Walmsley wrote:
> cc Govindraj
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
> >
> > > I don't quite understand this patch.  Are you saying that AM3517/3505 
> > > can't wake from WFI?  That would seem odd.
> > 
> > No, I'm saying that I/O doesn't seem to wake it up from the WFI.
> > I've learned to not trust the am35x TRM much so I'm pretty much
> > feeling my way along in the dark.
> 
> Hehe, no worries, just curious.
> 
> > I do know that without this patch, the system is extremely slow which I 
> > believe is from it only returning from the WFI because of a timer 
> > expiration or something like that.
> 
> How are you trying to wake it up -- from an incoming character via 
> the UART?
> 
> Does the system pause in the middle of UART transmits, or does it get the 
> transmit buffers out cleanly and just not respond promptly to incoming 
> characters?

Both cpu_idle/pm_idle thread (arch/arm/kernel/process.c:cpu_idle()) and
the cpu idle driver (arch/arm/mach-omap2/cpuidle34xx.c:omap3_enter_idle())
behave the same without the 2 patches I posted.  During boot, things
become extremely sluggish.  I took that to mean that the WFI wasn't being
woken up unless a timer expired.  I also believed that not having I/O
wake-ups would cause that so I made those patches.

There don't appear to be any missing or additional characters from the UART.
This is all during the boot-up so I'm not even trying to enter characters
via the UART.  That's all I did for "testing", if you can call it that.

For the emif4, etc. patches, I would do a suspend-to-RAM and hit a key
on the keyboard to wake it up again.  There are no dropped or added
characters in the [serial] console output.  It does complain that the
expected state wasn't entered (INACTIVE) and by looking at
/sys/kernel/debug/pm_debug/count, the CORE domain is the only one that
didn't increment its "INA" count.

> > > There are other sources of wakeup on the system other than I/O wakeup.  
> > > I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> > > RETENTION or OFF.  And as I understand it, neither of those apply to 
> > > AM3517/3505?
> > 
> > Hmm, its true that RETENTION and OFF aren't supported.  It does wake up
> > occasionally (as mentioned above) it just seems that I/O doesn't wake
> > it up.  I may be mistaken.  I'm only going from what I've seen since and
> > the TRM seems to have lots of errors so I'm not sure what to trust in it.
> 
> OK no problem, just trying to understand what's going on.  Sounds like 
> you've gotten tossed into the deep end :-)

:)

> > > Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> > > should be able to cause the ARM to exit WFI by asserting their 
> > > SWAKEUP lines and raising their interrupt lines.
> > 
> > Okay, but that doesn't seem to be working.  I'll look some more to see
> > why they aren't working.
> 
> There could be a hidden dependency on I/O wakeup being present in the UART 
> driver. We've been going through some UART driver angst recently...

OK.

Mark
--

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-11 23:08           ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 04:47:31PM -0600, Paul Walmsley wrote:
> cc Govindraj
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
> >
> > > I don't quite understand this patch.  Are you saying that AM3517/3505 
> > > can't wake from WFI?  That would seem odd.
> > 
> > No, I'm saying that I/O doesn't seem to wake it up from the WFI.
> > I've learned to not trust the am35x TRM much so I'm pretty much
> > feeling my way along in the dark.
> 
> Hehe, no worries, just curious.
> 
> > I do know that without this patch, the system is extremely slow which I 
> > believe is from it only returning from the WFI because of a timer 
> > expiration or something like that.
> 
> How are you trying to wake it up -- from an incoming character via 
> the UART?
> 
> Does the system pause in the middle of UART transmits, or does it get the 
> transmit buffers out cleanly and just not respond promptly to incoming 
> characters?

Both cpu_idle/pm_idle thread (arch/arm/kernel/process.c:cpu_idle()) and
the cpu idle driver (arch/arm/mach-omap2/cpuidle34xx.c:omap3_enter_idle())
behave the same without the 2 patches I posted.  During boot, things
become extremely sluggish.  I took that to mean that the WFI wasn't being
woken up unless a timer expired.  I also believed that not having I/O
wake-ups would cause that so I made those patches.

There don't appear to be any missing or additional characters from the UART.
This is all during the boot-up so I'm not even trying to enter characters
via the UART.  That's all I did for "testing", if you can call it that.

For the emif4, etc. patches, I would do a suspend-to-RAM and hit a key
on the keyboard to wake it up again.  There are no dropped or added
characters in the [serial] console output.  It does complain that the
expected state wasn't entered (INACTIVE) and by looking at
/sys/kernel/debug/pm_debug/count, the CORE domain is the only one that
didn't increment its "INA" count.

> > > There are other sources of wakeup on the system other than I/O wakeup.  
> > > I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> > > RETENTION or OFF.  And as I understand it, neither of those apply to 
> > > AM3517/3505?
> > 
> > Hmm, its true that RETENTION and OFF aren't supported.  It does wake up
> > occasionally (as mentioned above) it just seems that I/O doesn't wake
> > it up.  I may be mistaken.  I'm only going from what I've seen since and
> > the TRM seems to have lots of errors so I'm not sure what to trust in it.
> 
> OK no problem, just trying to understand what's going on.  Sounds like 
> you've gotten tossed into the deep end :-)

:)

> > > Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> > > should be able to cause the ARM to exit WFI by asserting their 
> > > SWAKEUP lines and raising their interrupt lines.
> > 
> > Okay, but that doesn't seem to be working.  I'll look some more to see
> > why they aren't working.
> 
> There could be a hidden dependency on I/O wakeup being present in the UART 
> driver. We've been going through some UART driver angst recently...

OK.

Mark
--

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

* Re: [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
  2012-04-11 22:46     ` Kevin Hilman
@ 2012-04-11 23:11       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:11 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: paul, linux-omap, linux-arm-kernel

On Wed, Apr 11, 2012 at 03:46:20PM -0700, Kevin Hilman wrote:
> Hi Mark,
> 
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > Typical OMAP3 SoCs have four power domain states: ON,
> > INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
> > has only two states: ON and INACTIVE.  To distinguish which
> > set of states the current device has, add the 'OMAP3_HAS_PWROFF'
> > feature.  When that feature/bit is set, the device supports the
> > RETENTION and OFF states; otherwise, it doesn't.
> >
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> Paul has mentioned this already, but the same applies here: We shouldn't
> be using SoC-global feature flag for this.   We already have per-pwrdm
> flags that indicate what states a given powerdomain suports (see .pwrsts
> field.)
> 
> Wherever we have blind writes to next powerstates that assume support
> for RET/OFF is present, those should probably use a helper function from
> the powerdomain code that checks if that state is even supported.

Okay, thanks Kevin.

> Jean's work on functional powerstates will probably help here if you
> really need to support INACTIVE.  However, Paul may be right in that you
> might just start with supporing ON only, and validate that module-level
> wakups acutally work.

Yeah, I'm going to do that as soon as I catch up the emails.  I thinking
more & more that Paul is right and that we should just scrap the INACTIVE
state and leave everything ON.

Mark
--

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

* [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
@ 2012-04-11 23:11       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:46:20PM -0700, Kevin Hilman wrote:
> Hi Mark,
> 
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > Typical OMAP3 SoCs have four power domain states: ON,
> > INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
> > has only two states: ON and INACTIVE.  To distinguish which
> > set of states the current device has, add the 'OMAP3_HAS_PWROFF'
> > feature.  When that feature/bit is set, the device supports the
> > RETENTION and OFF states; otherwise, it doesn't.
> >
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> Paul has mentioned this already, but the same applies here: We shouldn't
> be using SoC-global feature flag for this.   We already have per-pwrdm
> flags that indicate what states a given powerdomain suports (see .pwrsts
> field.)
> 
> Wherever we have blind writes to next powerstates that assume support
> for RET/OFF is present, those should probably use a helper function from
> the powerdomain code that checks if that state is even supported.

Okay, thanks Kevin.

> Jean's work on functional powerstates will probably help here if you
> really need to support INACTIVE.  However, Paul may be right in that you
> might just start with supporing ON only, and validate that module-level
> wakups acutally work.

Yeah, I'm going to do that as soon as I catch up the emails.  I thinking
more & more that Paul is right and that we should just scrap the INACTIVE
state and leave everything ON.

Mark
--

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

* Re: [PATCH 10/12] arm: omap3: am35x: Add minimal EMIF4 support
  2012-04-11 21:31     ` Paul Walmsley
@ 2012-04-11 23:22       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:22 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman, aneesh

On Wed, Apr 11, 2012 at 03:31:25PM -0600, Paul Walmsley wrote:
> cc Aneesh
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The typical SDRAM Controller Subsystem module (SDRC)
> > on TI OMAP3 devices has two submodules: the SDRAM Memory
> > Scheduler (SMS) submodule, and the SDRC submodule--the
> > 'SDRC' acronym/term is overloaded.  The am35x family of
> > devices is different in that it has an EMIF4 submodule
> > instead of an SDRC submodule.  The SMS submodules are
> > similar, though.
> 
> The best thing to do is to add an EMIF driver stub that is initialized 
> based on hwmod data, rather than hacking this into the existing SDRC.
> 
> I don't know what the current state of the EMIF driver is.  Aneesh, 
> do you know what the current status is?
> 
> If it's not going upstream for some reason, then I'd suggest adding 
> arch/arm/mach-omap2/emif.c for now.

Okay, thanks Paul.

Mark
--

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

* [PATCH 10/12] arm: omap3: am35x: Add minimal EMIF4 support
@ 2012-04-11 23:22       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:31:25PM -0600, Paul Walmsley wrote:
> cc Aneesh
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The typical SDRAM Controller Subsystem module (SDRC)
> > on TI OMAP3 devices has two submodules: the SDRAM Memory
> > Scheduler (SMS) submodule, and the SDRC submodule--the
> > 'SDRC' acronym/term is overloaded.  The am35x family of
> > devices is different in that it has an EMIF4 submodule
> > instead of an SDRC submodule.  The SMS submodules are
> > similar, though.
> 
> The best thing to do is to add an EMIF driver stub that is initialized 
> based on hwmod data, rather than hacking this into the existing SDRC.
> 
> I don't know what the current state of the EMIF driver is.  Aneesh, 
> do you know what the current status is?
> 
> If it's not going upstream for some reason, then I'd suggest adding 
> arch/arm/mach-omap2/emif.c for now.

Okay, thanks Paul.

Mark
--

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

* Re: [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
  2012-04-11 22:56     ` Paul Walmsley
@ 2012-04-11 23:23       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:23 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 04:56:05PM -0600, Paul Walmsley wrote:
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The typical SDRAM Controller Subsystem module (SDRC)
> > on TI OMAP3 devices has two submodules: the SDRAM Memory
> > Scheduler (SMS) submodule, and the SDRC submodule--the
> > 'SDRC' acronym/term is overloaded.  The am35x family of
> > devices is different in that it has an EMIF4 submodule
> > instead of an SDRC submodule.  The SMS submodules are
> > similar, though.
> 
> By the way, thanks for the great patch descriptions; they are very 
> helpful.

I should have left them short.  Maybe I'd have less homework to do then! ;)

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

* [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature
@ 2012-04-11 23:23       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 04:56:05PM -0600, Paul Walmsley wrote:
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > The typical SDRAM Controller Subsystem module (SDRC)
> > on TI OMAP3 devices has two submodules: the SDRAM Memory
> > Scheduler (SMS) submodule, and the SDRC submodule--the
> > 'SDRC' acronym/term is overloaded.  The am35x family of
> > devices is different in that it has an EMIF4 submodule
> > instead of an SDRC submodule.  The SMS submodules are
> > similar, though.
> 
> By the way, thanks for the great patch descriptions; they are very 
> helpful.

I should have left them short.  Maybe I'd have less homework to do then! ;)

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

* Re: [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
  2012-04-11 22:35     ` Kevin Hilman
@ 2012-04-11 23:26       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:26 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, linux-arm-kernel, paul, Ranjith Lohithakshan

On Wed, Apr 11, 2012 at 03:35:53PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > The typical SDRAM Controller Subsystem module (SDRC)
> > on TI OMAP3 devices has two submodules: the SDRAM Memory
> > Scheduler (SMS) submodule, and the SDRC submodule--the
> > 'SDRC' acronym/term is overloaded.  The am35x family of
> > devices is different in that it has an EMIF4 submodule
> > instead of an SDRC submodule.  The SMS submodules are
> > similar, though.
> >
> > The difference in SDRC/EMIF4 submodules is important because
> > omap34xx_cpu_suspend() will ultimately access the submodule's
> > registers and the register sets are different.  To support
> > the EMIF4 submodule, add the omap3_emif4_do_wfi() routine which
> > roughly does for the EMIF4 submodule what omap3_do_wfi() does
> > for the SDRC submodule.  This requires omap34xx_cpu_suspend()
> > to use a pointer set up in omap_push_sram_idle() so that it
> > jumps to the correct omap3*_do_wfi() routine in either SDRAM
> > or SRAM.
> >
> > Credits: arch/arm/mach-omap2/sleep3517.S in TI's am35x SDK
> > (05.03.02.00) which appears to be authored by Ranjith Lohithakshan
> > <ranjithl@ti.com> was used as a reference.
> >
> > CC: Ranjith Lohithakshan <ranjithl@ti.com>
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> Dumb Q: do you actually need to do the EMIF4 self-refresh control from
> SRAM?
> 
> The reason I ask is because on OMAP3, we tried going down the path of
> not running any of this from SRAM (run it from cache instead.)  However,
> due to some errata (c.f. wait_sdrc*, wait_dll_* ...), we had to handle
> these errata from SRAM.
> 
> Looking at your omap3_emif4_do_wfi, it looks like that's very minimal,
> and can probably be prefetched/run from cache.

I don't see why it wouldn't work but I haven't tried.  I did it the way
that I did hoping to fit in with the existing infrastructure as neatly
as possible.

I'll try out leaving it in cache.

Mark
--

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

* [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
@ 2012-04-11 23:26       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-11 23:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:35:53PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > The typical SDRAM Controller Subsystem module (SDRC)
> > on TI OMAP3 devices has two submodules: the SDRAM Memory
> > Scheduler (SMS) submodule, and the SDRC submodule--the
> > 'SDRC' acronym/term is overloaded.  The am35x family of
> > devices is different in that it has an EMIF4 submodule
> > instead of an SDRC submodule.  The SMS submodules are
> > similar, though.
> >
> > The difference in SDRC/EMIF4 submodules is important because
> > omap34xx_cpu_suspend() will ultimately access the submodule's
> > registers and the register sets are different.  To support
> > the EMIF4 submodule, add the omap3_emif4_do_wfi() routine which
> > roughly does for the EMIF4 submodule what omap3_do_wfi() does
> > for the SDRC submodule.  This requires omap34xx_cpu_suspend()
> > to use a pointer set up in omap_push_sram_idle() so that it
> > jumps to the correct omap3*_do_wfi() routine in either SDRAM
> > or SRAM.
> >
> > Credits: arch/arm/mach-omap2/sleep3517.S in TI's am35x SDK
> > (05.03.02.00) which appears to be authored by Ranjith Lohithakshan
> > <ranjithl@ti.com> was used as a reference.
> >
> > CC: Ranjith Lohithakshan <ranjithl@ti.com>
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> Dumb Q: do you actually need to do the EMIF4 self-refresh control from
> SRAM?
> 
> The reason I ask is because on OMAP3, we tried going down the path of
> not running any of this from SRAM (run it from cache instead.)  However,
> due to some errata (c.f. wait_sdrc*, wait_dll_* ...), we had to handle
> these errata from SRAM.
> 
> Looking at your omap3_emif4_do_wfi, it looks like that's very minimal,
> and can probably be prefetched/run from cache.

I don't see why it wouldn't work but I haven't tried.  I did it the way
that I did hoping to fit in with the existing infrastructure as neatly
as possible.

I'll try out leaving it in cache.

Mark
--

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

* Re: [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work
  2012-04-11 19:05   ` Mark A. Greer
@ 2012-04-11 23:42     ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-11 23:42 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman, paul

Hi Mark,

On 04/11/2012 02:05 PM, Mark A. Greer wrote:
> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> Currently in the OMAP3 code, cpu_idle() calls pm_idle(),
> which is a function pointer set to omap3_pm_idle()).
> omap3_pm_idle() calls omap_sram_idle() which eventually
> causes a 'wfi' instruction to be executed effectively
> putting the system to sleep.  It is assumed that an
> I/O wake-up event will occur to wake the system up again.
> This doesn't work on systems that don't support I/O wake-ups
> (indicated by omap3_has_io_wakeup() returning false).
> 
> Leaving pm_idle() pointing to default_idle() won't work
> either because the cpu_<processor>_do_idle() routine which
> is eventually called may also execute a 'wfi' instruction
> (e.g., cpu_v7_do_idle()).

So with this change you will never execute wfi?

I would have thought a timer or peripheral interrupt would be able to
bring you out of wfi. IO wake-ups would only be needed for very low
power states. At least that is how it is on OMAP devices. I am not sure
how the AMxxx devices differ.

Cheers
Jon

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

* [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work
@ 2012-04-11 23:42     ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-11 23:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

On 04/11/2012 02:05 PM, Mark A. Greer wrote:
> From: "Mark A. Greer" <mgreer@animalcreek.com>
> 
> Currently in the OMAP3 code, cpu_idle() calls pm_idle(),
> which is a function pointer set to omap3_pm_idle()).
> omap3_pm_idle() calls omap_sram_idle() which eventually
> causes a 'wfi' instruction to be executed effectively
> putting the system to sleep.  It is assumed that an
> I/O wake-up event will occur to wake the system up again.
> This doesn't work on systems that don't support I/O wake-ups
> (indicated by omap3_has_io_wakeup() returning false).
> 
> Leaving pm_idle() pointing to default_idle() won't work
> either because the cpu_<processor>_do_idle() routine which
> is eventually called may also execute a 'wfi' instruction
> (e.g., cpu_v7_do_idle()).

So with this change you will never execute wfi?

I would have thought a timer or peripheral interrupt would be able to
bring you out of wfi. IO wake-ups would only be needed for very low
power states. At least that is how it is on OMAP devices. I am not sure
how the AMxxx devices differ.

Cheers
Jon

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

* Re: [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-11 22:49           ` Mark A. Greer
@ 2012-04-11 23:49             ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 23:49 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> On Wed, Apr 11, 2012 at 04:04:44PM -0600, Paul Walmsley wrote:
> > On Wed, 11 Apr 2012, Mark A. Greer wrote:
> > 
> > > On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> > > 
> > > > Looks like there are an extra set of commas here, maybe just use:
> > > > 
> > > > static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > > > 	{ .clkdm_name = "mpu_clkdm" },
> > > > 	{ .clkdm_name = "wkup_clkdm" },
> > > > 	{ NULL },
> > > 
> > > Yes, there are extra commas but they come from the code I'm copying
> > > and removing iva2_clkdm from.  I was keeping things consistent so I
> > > kept the commas.  Given that, do you still want them removed?
> > > (I'm indifferent.)
> > 
> > Yes please.  I realize it's a minor issue, but I'd like to keep the format 
> > of these files internally consistent.
> 
> Hrm, did you meant "No thanks"?  As in, leave the commas there since
> that's what the code that is already there is like?

The current data is in this format:

/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
static struct clkdm_dep cam_wkdeps[] = {
	{ .clkdm_name = "iva2_clkdm" },
	{ .clkdm_name = "mpu_clkdm" },
	{ .clkdm_name = "wkup_clkdm" },
	{ NULL },
};

So if you can match that, it would be ideal.



- Paul

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-11 23:49             ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-11 23:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> On Wed, Apr 11, 2012 at 04:04:44PM -0600, Paul Walmsley wrote:
> > On Wed, 11 Apr 2012, Mark A. Greer wrote:
> > 
> > > On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> > > 
> > > > Looks like there are an extra set of commas here, maybe just use:
> > > > 
> > > > static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > > > 	{ .clkdm_name = "mpu_clkdm" },
> > > > 	{ .clkdm_name = "wkup_clkdm" },
> > > > 	{ NULL },
> > > 
> > > Yes, there are extra commas but they come from the code I'm copying
> > > and removing iva2_clkdm from.  I was keeping things consistent so I
> > > kept the commas.  Given that, do you still want them removed?
> > > (I'm indifferent.)
> > 
> > Yes please.  I realize it's a minor issue, but I'd like to keep the format 
> > of these files internally consistent.
> 
> Hrm, did you meant "No thanks"?  As in, leave the commas there since
> that's what the code that is already there is like?

The current data is in this format:

/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
static struct clkdm_dep cam_wkdeps[] = {
	{ .clkdm_name = "iva2_clkdm" },
	{ .clkdm_name = "mpu_clkdm" },
	{ .clkdm_name = "wkup_clkdm" },
	{ NULL },
};

So if you can match that, it would be ideal.



- Paul

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

* Re: [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
  2012-04-11 22:40       ` Mark A. Greer
@ 2012-04-12  0:24         ` Jon Hunter
  -1 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-12  0:24 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: Paul Walmsley, khilman, linux-omap, linux-arm-kernel


On 04/11/2012 05:40 PM, Mark A. Greer wrote:
> On Wed, Apr 11, 2012 at 03:53:30PM -0600, Paul Walmsley wrote:
>> Hi
>>
>> On Wed, 11 Apr 2012, Mark A. Greer wrote:
>>
>>> From: "Mark A. Greer" <mgreer@animalcreek.com>
>>>
>>> The am35x family of SoCs only support PWRSTS_ON
>>> and PWRSTS_INACTIVE states so create a new set
>>> of powerdomain structures that ensure that only
>>> the ON and INACTIVE states are entered.
>>
>> I'm still unsure what we should do about this INACTIVE state.  As far as I 
>> can tell, it does not actually represent a distinct powerdomain state on 
>> OMAP3.  We can't write it to the PM_PWSTCTRL_*.POWERSTATE bits, since that 
>> value is marked as "reserved".  And SPRUGR0B, the AM3517/3505 TRM, 
>> explicitly states "This register should not be programmed with reserved 
>> values of bit fields for proper functioning of power state control."
>> Of course SPRUGR0B also claims that AM3517/3505 supports RETENTION, so 
>> that is relatively confusing.
> 
> Yep.  You read one section which tells you the device doesn't support
> such-and-such then it goes on for pages describing how it works.  I play
> with the hardware and the registers are there so it seems like it should
> work.  Its been an "adventure". :)
> 
>> OMAP4 PRCM actually does seem to support powerdomain INACTIVE state, 
>> although it does not actually seem to represent a separate state.  As I 
>> understand it, it simply allows the clockdomains in the powerdomain to 
>> transitioning from the ACTIVE state into the INACTIVE state.  In other 
>> words, it doesn't affect the powerdomain power state at all.  And on OMAP4 
>> it's referred to as the ON-INACTIVE state, to clarify that it is simply a 
>> variant of the ON state.  I wish they had just added a separate bit for 
>> this; it would have avoided some frustration...
>>
>> Anyway, my question is this: is there any point at all to defining the 
>> INACTIVE state for 3517/3505, given that it apparently cannot be read 
>> from, nor written to the PRCM hardware?
> 
> Great question and I really don't know the answer--its too hard to know
> what's for real and what isn't in the TRM.  Maybe it is best to get rid
> of INACTIVE and just leave everything ON.

FWIW, for omap3 class device inactive is defined as ...

"Inactive: The same as power on but all clocks are cut. Logic is not
working, because no clock is running."

There is nothing explicit to program as far as the power domain goes.
For OMAP4 you can program the power domain to enter inactive and when
all power domains in a voltage domain are inactive the voltage domain
can enter the sleep state.

Cheers
Jon

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

* [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
@ 2012-04-12  0:24         ` Jon Hunter
  0 siblings, 0 replies; 126+ messages in thread
From: Jon Hunter @ 2012-04-12  0:24 UTC (permalink / raw)
  To: linux-arm-kernel


On 04/11/2012 05:40 PM, Mark A. Greer wrote:
> On Wed, Apr 11, 2012 at 03:53:30PM -0600, Paul Walmsley wrote:
>> Hi
>>
>> On Wed, 11 Apr 2012, Mark A. Greer wrote:
>>
>>> From: "Mark A. Greer" <mgreer@animalcreek.com>
>>>
>>> The am35x family of SoCs only support PWRSTS_ON
>>> and PWRSTS_INACTIVE states so create a new set
>>> of powerdomain structures that ensure that only
>>> the ON and INACTIVE states are entered.
>>
>> I'm still unsure what we should do about this INACTIVE state.  As far as I 
>> can tell, it does not actually represent a distinct powerdomain state on 
>> OMAP3.  We can't write it to the PM_PWSTCTRL_*.POWERSTATE bits, since that 
>> value is marked as "reserved".  And SPRUGR0B, the AM3517/3505 TRM, 
>> explicitly states "This register should not be programmed with reserved 
>> values of bit fields for proper functioning of power state control."
>> Of course SPRUGR0B also claims that AM3517/3505 supports RETENTION, so 
>> that is relatively confusing.
> 
> Yep.  You read one section which tells you the device doesn't support
> such-and-such then it goes on for pages describing how it works.  I play
> with the hardware and the registers are there so it seems like it should
> work.  Its been an "adventure". :)
> 
>> OMAP4 PRCM actually does seem to support powerdomain INACTIVE state, 
>> although it does not actually seem to represent a separate state.  As I 
>> understand it, it simply allows the clockdomains in the powerdomain to 
>> transitioning from the ACTIVE state into the INACTIVE state.  In other 
>> words, it doesn't affect the powerdomain power state at all.  And on OMAP4 
>> it's referred to as the ON-INACTIVE state, to clarify that it is simply a 
>> variant of the ON state.  I wish they had just added a separate bit for 
>> this; it would have avoided some frustration...
>>
>> Anyway, my question is this: is there any point at all to defining the 
>> INACTIVE state for 3517/3505, given that it apparently cannot be read 
>> from, nor written to the PRCM hardware?
> 
> Great question and I really don't know the answer--its too hard to know
> what's for real and what isn't in the TRM.  Maybe it is best to get rid
> of INACTIVE and just leave everything ON.

FWIW, for omap3 class device inactive is defined as ...

"Inactive: The same as power on but all clocks are cut. Logic is not
working, because no clock is running."

There is nothing explicit to program as far as the power domain goes.
For OMAP4 you can program the power domain to enter inactive and when
all power domains in a voltage domain are inactive the voltage domain
can enter the sleep state.

Cheers
Jon

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

* Re: [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
  2012-04-12  0:24         ` Jon Hunter
@ 2012-04-12  2:19           ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-12  2:19 UTC (permalink / raw)
  To: Jon Hunter; +Cc: Paul Walmsley, khilman, linux-omap, linux-arm-kernel

On Wed, Apr 11, 2012 at 07:24:29PM -0500, Jon Hunter wrote:
> 
> On 04/11/2012 05:40 PM, Mark A. Greer wrote:
> > On Wed, Apr 11, 2012 at 03:53:30PM -0600, Paul Walmsley wrote:
> >> Hi
> >>
> >> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> >>
> >>> From: "Mark A. Greer" <mgreer@animalcreek.com>

> >> OMAP4 PRCM actually does seem to support powerdomain INACTIVE state, 
> >> although it does not actually seem to represent a separate state.  As I 
> >> understand it, it simply allows the clockdomains in the powerdomain to 
> >> transitioning from the ACTIVE state into the INACTIVE state.  In other 
> >> words, it doesn't affect the powerdomain power state at all.  And on OMAP4 
> >> it's referred to as the ON-INACTIVE state, to clarify that it is simply a 
> >> variant of the ON state.  I wish they had just added a separate bit for 
> >> this; it would have avoided some frustration...
> >>
> >> Anyway, my question is this: is there any point at all to defining the 
> >> INACTIVE state for 3517/3505, given that it apparently cannot be read 
> >> from, nor written to the PRCM hardware?
> > 
> > Great question and I really don't know the answer--its too hard to know
> > what's for real and what isn't in the TRM.  Maybe it is best to get rid
> > of INACTIVE and just leave everything ON.
> 
> FWIW, for omap3 class device inactive is defined as ...
> 
> "Inactive: The same as power on but all clocks are cut. Logic is not
> working, because no clock is running."
> 
> There is nothing explicit to program as far as the power domain goes.
> For OMAP4 you can program the power domain to enter inactive and when
> all power domains in a voltage domain are inactive the voltage domain
> can enter the sleep state.

Thanks Jon.

Seems like getting rid of INACTIVE and staying ON is the right thing
to do.

Mark
--

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

* [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states
@ 2012-04-12  2:19           ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-12  2:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 07:24:29PM -0500, Jon Hunter wrote:
> 
> On 04/11/2012 05:40 PM, Mark A. Greer wrote:
> > On Wed, Apr 11, 2012 at 03:53:30PM -0600, Paul Walmsley wrote:
> >> Hi
> >>
> >> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> >>
> >>> From: "Mark A. Greer" <mgreer@animalcreek.com>

> >> OMAP4 PRCM actually does seem to support powerdomain INACTIVE state, 
> >> although it does not actually seem to represent a separate state.  As I 
> >> understand it, it simply allows the clockdomains in the powerdomain to 
> >> transitioning from the ACTIVE state into the INACTIVE state.  In other 
> >> words, it doesn't affect the powerdomain power state at all.  And on OMAP4 
> >> it's referred to as the ON-INACTIVE state, to clarify that it is simply a 
> >> variant of the ON state.  I wish they had just added a separate bit for 
> >> this; it would have avoided some frustration...
> >>
> >> Anyway, my question is this: is there any point at all to defining the 
> >> INACTIVE state for 3517/3505, given that it apparently cannot be read 
> >> from, nor written to the PRCM hardware?
> > 
> > Great question and I really don't know the answer--its too hard to know
> > what's for real and what isn't in the TRM.  Maybe it is best to get rid
> > of INACTIVE and just leave everything ON.
> 
> FWIW, for omap3 class device inactive is defined as ...
> 
> "Inactive: The same as power on but all clocks are cut. Logic is not
> working, because no clock is running."
> 
> There is nothing explicit to program as far as the power domain goes.
> For OMAP4 you can program the power domain to enter inactive and when
> all power domains in a voltage domain are inactive the voltage domain
> can enter the sleep state.

Thanks Jon.

Seems like getting rid of INACTIVE and staying ON is the right thing
to do.

Mark
--

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

* Re: [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-11 23:49             ` Paul Walmsley
@ 2012-04-12  2:23               ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-12  2:23 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 05:49:26PM -0600, Paul Walmsley wrote:
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > On Wed, Apr 11, 2012 at 04:04:44PM -0600, Paul Walmsley wrote:
> > > On Wed, 11 Apr 2012, Mark A. Greer wrote:
> > > 
> > > > On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> > > > 
> > > > > Looks like there are an extra set of commas here, maybe just use:
> > > > > 
> > > > > static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > > > > 	{ .clkdm_name = "mpu_clkdm" },
> > > > > 	{ .clkdm_name = "wkup_clkdm" },
> > > > > 	{ NULL },
> > > > 
> > > > Yes, there are extra commas but they come from the code I'm copying
> > > > and removing iva2_clkdm from.  I was keeping things consistent so I
> > > > kept the commas.  Given that, do you still want them removed?
> > > > (I'm indifferent.)
> > > 
> > > Yes please.  I realize it's a minor issue, but I'd like to keep the format 
> > > of these files internally consistent.
> > 
> > Hrm, did you meant "No thanks"?  As in, leave the commas there since
> > that's what the code that is already there is like?
> 
> The current data is in this format:
> 
> /* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
> static struct clkdm_dep cam_wkdeps[] = {
> 	{ .clkdm_name = "iva2_clkdm" },
> 	{ .clkdm_name = "mpu_clkdm" },
> 	{ .clkdm_name = "wkup_clkdm" },
> 	{ NULL },
> };
> 
> So if you can match that, it would be ideal.

Okay, I'll get rid of the commas (fwiw, gfx_sgx_3xxx_wkdeps[] has commas
in k.o, the others don't).

Mark
--

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-12  2:23               ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-12  2:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 05:49:26PM -0600, Paul Walmsley wrote:
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > On Wed, Apr 11, 2012 at 04:04:44PM -0600, Paul Walmsley wrote:
> > > On Wed, 11 Apr 2012, Mark A. Greer wrote:
> > > 
> > > > On Wed, Apr 11, 2012 at 03:44:38PM -0600, Paul Walmsley wrote:
> > > > 
> > > > > Looks like there are an extra set of commas here, maybe just use:
> > > > > 
> > > > > static struct clkdm_dep gfx_sgx_am35x_wkdeps[] = {
> > > > > 	{ .clkdm_name = "mpu_clkdm" },
> > > > > 	{ .clkdm_name = "wkup_clkdm" },
> > > > > 	{ NULL },
> > > > 
> > > > Yes, there are extra commas but they come from the code I'm copying
> > > > and removing iva2_clkdm from.  I was keeping things consistent so I
> > > > kept the commas.  Given that, do you still want them removed?
> > > > (I'm indifferent.)
> > > 
> > > Yes please.  I realize it's a minor issue, but I'd like to keep the format 
> > > of these files internally consistent.
> > 
> > Hrm, did you meant "No thanks"?  As in, leave the commas there since
> > that's what the code that is already there is like?
> 
> The current data is in this format:
> 
> /* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
> static struct clkdm_dep cam_wkdeps[] = {
> 	{ .clkdm_name = "iva2_clkdm" },
> 	{ .clkdm_name = "mpu_clkdm" },
> 	{ .clkdm_name = "wkup_clkdm" },
> 	{ NULL },
> };
> 
> So if you can match that, it would be ideal.

Okay, I'll get rid of the commas (fwiw, gfx_sgx_3xxx_wkdeps[] has commas
in k.o, the others don't).

Mark
--

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

* Re: [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-12  2:23               ` Mark A. Greer
@ 2012-04-12  2:29                 ` Paul Walmsley
  -1 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-12  2:29 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> Okay, I'll get rid of the commas (fwiw, gfx_sgx_3xxx_wkdeps[] has commas
> in k.o, the others don't).

Okay thanks, that's just an oversight in the mainline data.  If you're so 
inclined, feel free to clean that up in your patch...


- Paul

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-12  2:29                 ` Paul Walmsley
  0 siblings, 0 replies; 126+ messages in thread
From: Paul Walmsley @ 2012-04-12  2:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 11 Apr 2012, Mark A. Greer wrote:

> Okay, I'll get rid of the commas (fwiw, gfx_sgx_3xxx_wkdeps[] has commas
> in k.o, the others don't).

Okay thanks, that's just an oversight in the mainline data.  If you're so 
inclined, feel free to clean that up in your patch...


- Paul

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

* Re: [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
  2012-04-12  2:29                 ` Paul Walmsley
@ 2012-04-12 23:00                   ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-12 23:00 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 08:29:51PM -0600, Paul Walmsley wrote:
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > Okay, I'll get rid of the commas (fwiw, gfx_sgx_3xxx_wkdeps[] has commas
> > in k.o, the others don't).
> 
> Okay thanks, that's just an oversight in the mainline data.  If you're so 
> inclined, feel free to clean that up in your patch...

I am and I will. :)

Mark
--

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

* [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies
@ 2012-04-12 23:00                   ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-12 23:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 08:29:51PM -0600, Paul Walmsley wrote:
> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > Okay, I'll get rid of the commas (fwiw, gfx_sgx_3xxx_wkdeps[] has commas
> > in k.o, the others don't).
> 
> Okay thanks, that's just an oversight in the mainline data.  If you're so 
> inclined, feel free to clean that up in your patch...

I am and I will. :)

Mark
--

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

* Re: [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
  2012-04-11 22:36     ` Paul Walmsley
@ 2012-04-13  0:12       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-13  0:12 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: Ranjith Lohithakshan, linux-omap, linux-arm-kernel, khilman

On Wed, Apr 11, 2012 at 04:36:25PM -0600, Paul Walmsley wrote:
> Hi
> 
> just a few comments based on a quick look
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:

> > diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
> > index 1f62f23..22aac4c 100644
> > --- a/arch/arm/mach-omap2/sleep34xx.S
> > +++ b/arch/arm/mach-omap2/sleep34xx.S

> > @@ -391,6 +401,52 @@ wait_dll_lock_counter:
> >  ENTRY(omap3_do_wfi_sz)
> >  	.word	. - omap3_do_wfi
> >  
> > +/*
> > + * Do WFI instruction (SDRC module has EMIF4 submodule)
> > + *
> > + * This code gets copied to internal SRAM and is accessible
> > + * from both SDRAM and SRAM:
> > + * - executed from SRAM for non-off modes (omap3_emif4_do_wfi_sram),
> > + * - executed from SDRAM for OFF mode (omap3_emif4_do_wfi).
> > + */
> > +	.align	3
> > +ENTRY(omap3_emif4_do_wfi)
> > +	/* Put EMIF in self-refresh */
> 
> Hmm, I guess this comment isn't quite right; it just tells it to go to 
> self-refresh when it's "idle" ? (see below)
> 
> > +	ldr     r4, pwr_mgmt_ctrl
> > +	ldr     r5, [r4]
> > +	orr     r5, r5, #0x200
> 
> Maybe use a macro here in place of the #0x200 to indicate what it's trying 
> to set...
> 
> Do you happen to know what "idle" means in the context of SPRUGR0B Section 
> 9.2.3.4.5.1 "SDRAM Self-Refresh Mode" ?  Is it referring to 
> target module-level idle, e.g. SIdleReq; or is it referring to 
> an internal definition of idle, e.g., something like "no reads or writes 
> from/to the SDRAM" ?  Am wondering if this should just be set once during 
> EMIF initialization.

I can't tell from tne manual.  I assumed it meant the latter of the choices
you listed.  I just tested a kernel with it set up during EMIF init (value
of 0x80000200) and removed the related bits from omap3_emif4_do_wfi() and
it booted and returned from suspend-to-RAM just fine.  So, it seems that
it can be moved to EMIF init.

[I swear I tested this some time ago and discovered that it was needed
in omap3_emif4_do_wfi().  Oh well...]

> 
> > +	str     r5, [r4]
> 
> Might be good to do a readback after this to ensure that the store has 
> made it to the EMIF.
> 
> Also, scanning SPRUGR0B, it looks like this setting is dependent partially 
> on the REG_PM_TIM field in the same register.  Might be good to set 
> REG_PM_TIM during EMIF init to avoid any bootloader dependency.

True but moot now since I'll move the code to EMIF init.

> > +
> > +	dsb
> > +	dmb
> > +
> > +	wfi
> > +
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> 
> Are these NOPs necessary?  Is the number of NOPs dependent on CPU or bus 
> speed or some ARM parameter?

After looking through the am35x errata, I don't think so.  AFAICT,
they are there to work around--from omap3535 errata (sprz278f.pdf)--
Advisory 3.1.1.75, "IVA2: CAM/SGX Dependencies (OMAP3530/25 only)".
I don't see that or any other errata that requires a nop in the
am35x errata so I'll get rid of them.

[As I went through the errata again, I noticed talk about the device
going into RET state.  Sigh...]

Mark
--

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

* [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules
@ 2012-04-13  0:12       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-13  0:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 04:36:25PM -0600, Paul Walmsley wrote:
> Hi
> 
> just a few comments based on a quick look
> 
> On Wed, 11 Apr 2012, Mark A. Greer wrote:

> > diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
> > index 1f62f23..22aac4c 100644
> > --- a/arch/arm/mach-omap2/sleep34xx.S
> > +++ b/arch/arm/mach-omap2/sleep34xx.S

> > @@ -391,6 +401,52 @@ wait_dll_lock_counter:
> >  ENTRY(omap3_do_wfi_sz)
> >  	.word	. - omap3_do_wfi
> >  
> > +/*
> > + * Do WFI instruction (SDRC module has EMIF4 submodule)
> > + *
> > + * This code gets copied to internal SRAM and is accessible
> > + * from both SDRAM and SRAM:
> > + * - executed from SRAM for non-off modes (omap3_emif4_do_wfi_sram),
> > + * - executed from SDRAM for OFF mode (omap3_emif4_do_wfi).
> > + */
> > +	.align	3
> > +ENTRY(omap3_emif4_do_wfi)
> > +	/* Put EMIF in self-refresh */
> 
> Hmm, I guess this comment isn't quite right; it just tells it to go to 
> self-refresh when it's "idle" ? (see below)
> 
> > +	ldr     r4, pwr_mgmt_ctrl
> > +	ldr     r5, [r4]
> > +	orr     r5, r5, #0x200
> 
> Maybe use a macro here in place of the #0x200 to indicate what it's trying 
> to set...
> 
> Do you happen to know what "idle" means in the context of SPRUGR0B Section 
> 9.2.3.4.5.1 "SDRAM Self-Refresh Mode" ?  Is it referring to 
> target module-level idle, e.g. SIdleReq; or is it referring to 
> an internal definition of idle, e.g., something like "no reads or writes 
> from/to the SDRAM" ?  Am wondering if this should just be set once during 
> EMIF initialization.

I can't tell from tne manual.  I assumed it meant the latter of the choices
you listed.  I just tested a kernel with it set up during EMIF init (value
of 0x80000200) and removed the related bits from omap3_emif4_do_wfi() and
it booted and returned from suspend-to-RAM just fine.  So, it seems that
it can be moved to EMIF init.

[I swear I tested this some time ago and discovered that it was needed
in omap3_emif4_do_wfi().  Oh well...]

> 
> > +	str     r5, [r4]
> 
> Might be good to do a readback after this to ensure that the store has 
> made it to the EMIF.
> 
> Also, scanning SPRUGR0B, it looks like this setting is dependent partially 
> on the REG_PM_TIM field in the same register.  Might be good to set 
> REG_PM_TIM during EMIF init to avoid any bootloader dependency.

True but moot now since I'll move the code to EMIF init.

> > +
> > +	dsb
> > +	dmb
> > +
> > +	wfi
> > +
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> > +	nop
> 
> Are these NOPs necessary?  Is the number of NOPs dependent on CPU or bus 
> speed or some ARM parameter?

After looking through the am35x errata, I don't think so.  AFAICT,
they are there to work around--from omap3535 errata (sprz278f.pdf)--
Advisory 3.1.1.75, "IVA2: CAM/SGX Dependencies (OMAP3530/25 only)".
I don't see that or any other errata that requires a nop in the
am35x errata so I'll get rid of them.

[As I went through the errata again, I noticed talk about the device
going into RET state.  Sigh...]

Mark
--

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

* Re: [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work
  2012-04-11 23:42     ` Jon Hunter
@ 2012-04-13  0:13       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-13  0:13 UTC (permalink / raw)
  To: Jon Hunter; +Cc: linux-omap, linux-arm-kernel, khilman, paul

On Wed, Apr 11, 2012 at 06:42:44PM -0500, Jon Hunter wrote:
> Hi Mark,
> 
> On 04/11/2012 02:05 PM, Mark A. Greer wrote:
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > Currently in the OMAP3 code, cpu_idle() calls pm_idle(),
> > which is a function pointer set to omap3_pm_idle()).
> > omap3_pm_idle() calls omap_sram_idle() which eventually
> > causes a 'wfi' instruction to be executed effectively
> > putting the system to sleep.  It is assumed that an
> > I/O wake-up event will occur to wake the system up again.
> > This doesn't work on systems that don't support I/O wake-ups
> > (indicated by omap3_has_io_wakeup() returning false).
> > 
> > Leaving pm_idle() pointing to default_idle() won't work
> > either because the cpu_<processor>_do_idle() routine which
> > is eventually called may also execute a 'wfi' instruction
> > (e.g., cpu_v7_do_idle()).
> 
> So with this change you will never execute wfi?

Correct.

> I would have thought a timer or peripheral interrupt would be able to
> bring you out of wfi.

It occasionally wakes up so I'm guessing its a timer interrupt.
It seems that peripheral interrupts aren't waking it up.
Perhaps something isn't configured correctly but everything I've
looked at looks okay (AFAICT).

> IO wake-ups would only be needed for very low
> power states. At least that is how it is on OMAP devices. I am not sure
> how the AMxxx devices differ.

The am35x isn't supposed to have them so there's no real info on it
but I'm sure its the same as regular OMAP devices.

Mark
--

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

* [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work
@ 2012-04-13  0:13       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-13  0:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 06:42:44PM -0500, Jon Hunter wrote:
> Hi Mark,
> 
> On 04/11/2012 02:05 PM, Mark A. Greer wrote:
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > Currently in the OMAP3 code, cpu_idle() calls pm_idle(),
> > which is a function pointer set to omap3_pm_idle()).
> > omap3_pm_idle() calls omap_sram_idle() which eventually
> > causes a 'wfi' instruction to be executed effectively
> > putting the system to sleep.  It is assumed that an
> > I/O wake-up event will occur to wake the system up again.
> > This doesn't work on systems that don't support I/O wake-ups
> > (indicated by omap3_has_io_wakeup() returning false).
> > 
> > Leaving pm_idle() pointing to default_idle() won't work
> > either because the cpu_<processor>_do_idle() routine which
> > is eventually called may also execute a 'wfi' instruction
> > (e.g., cpu_v7_do_idle()).
> 
> So with this change you will never execute wfi?

Correct.

> I would have thought a timer or peripheral interrupt would be able to
> bring you out of wfi.

It occasionally wakes up so I'm guessing its a timer interrupt.
It seems that peripheral interrupts aren't waking it up.
Perhaps something isn't configured correctly but everything I've
looked at looks okay (AFAICT).

> IO wake-ups would only be needed for very low
> power states. At least that is how it is on OMAP devices. I am not sure
> how the AMxxx devices differ.

The am35x isn't supposed to have them so there's no real info on it
but I'm sure its the same as regular OMAP devices.

Mark
--

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

* Re: [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
  2012-04-11 22:46     ` Kevin Hilman
@ 2012-04-24  4:36       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-24  4:36 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, linux-arm-kernel, paul

On Wed, Apr 11, 2012 at 03:46:20PM -0700, Kevin Hilman wrote:
> Hi Mark,

Hi Kevin.

> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > Typical OMAP3 SoCs have four power domain states: ON,
> > INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
> > has only two states: ON and INACTIVE.  To distinguish which
> > set of states the current device has, add the 'OMAP3_HAS_PWROFF'
> > feature.  When that feature/bit is set, the device supports the
> > RETENTION and OFF states; otherwise, it doesn't.
> >
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> Paul has mentioned this already, but the same applies here: We shouldn't
> be using SoC-global feature flag for this.   We already have per-pwrdm
> flags that indicate what states a given powerdomain suports (see .pwrsts
> field.)
> 
> Wherever we have blind writes to next powerstates that assume support
> for RET/OFF is present, those should probably use a helper function from
> the powerdomain code that checks if that state is even supported.

How about something like the patch below?
Note: its not well tested; just RFC.

> Jean's work on functional powerstates will probably help here if you
> really need to support INACTIVE.  However, Paul may be right in that you
> might just start with supporing ON only, and validate that module-level
> wakups acutally work.

Yes, I think INACTIVE is a red herring so I'm going to stick with k.o
master branch for now (IOW, not base on Jean's patches).  If you still
want me to base on his patches, just let me know.

Mark
--

>From 32c54adb15c76396aeec809d38de4dde936b1e66 Mon Sep 17 00:00:00 2001
From: "Mark A. Greer" <mgreer@animalcreek.com>
Date: Mon, 23 Apr 2012 17:48:06 -0700
Subject: [PATCH] arm: omap: Use only valid power domain states

Some parts of the OMAP code assume that all power
domains support certain states (e.g., RET & OFF).
This isn't always true (e.g., the am35x family of
SoC's) so those assumptions need to be removed.

Remove those assumptions by looking up the deepest
state that a power domain can be in whereever its
being blindly set.  The 'max()' of the deepest
state and what the code formerly wanted to set it
to, is the correct state.  If the code formerly
wanted to set it to PWRDM_POWER_OFF, then the
deepest possible state will be used (i.e., no
need to perform the 'max()').

The code still assumes that ON is a valid state.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c |   14 ++++++++++----
 arch/arm/mach-omap2/pm34xx.c      |   15 +++++++++------
 arch/arm/mach-omap2/powerdomain.c |   25 +++++++++++++++++++++++++
 arch/arm/mach-omap2/powerdomain.h |    2 ++
 4 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 5358664..60aa0c3 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -175,19 +175,25 @@ static int next_valid_state(struct cpuidle_device *dev,
 	struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
 	struct cpuidle_state *curr = &drv->states[index];
 	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
-	u32 mpu_deepest_state = PWRDM_POWER_RET;
-	u32 core_deepest_state = PWRDM_POWER_RET;
+	u32 mpu_deepest_state, mpu_deepest_possible;
+	u32 core_deepest_state, core_deepest_possible;
 	int next_index = -1;
 
+	mpu_deepest_possible = pwrdm_get_deepest_state(mpu_pd);
+	mpu_deepest_state = max(mpu_deepest_possible, (u32)PWRDM_POWER_RET);
+
+	core_deepest_possible = pwrdm_get_deepest_state(core_pd);
+	core_deepest_state = max(core_deepest_possible, (u32)PWRDM_POWER_RET);
+
 	if (enable_off_mode) {
-		mpu_deepest_state = PWRDM_POWER_OFF;
+		mpu_deepest_state = mpu_deepest_possible;
 		/*
 		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
 		 * CORE OFF mode is not supported in a stable form, restrict
 		 * instead the CORE state to RET.
 		 */
 		if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
-			core_deepest_state = PWRDM_POWER_OFF;
+			core_deepest_state = core_deepest_possible;
 	}
 
 	/* Check if current state is valid */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ec92676..7737bfb 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -614,12 +614,11 @@ void omap3_pm_off_mode_enable(int enable)
 	struct power_state *pwrst;
 	u32 state;
 
-	if (enable)
-		state = PWRDM_POWER_OFF;
-	else
-		state = PWRDM_POWER_RET;
-
 	list_for_each_entry(pwrst, &pwrst_list, node) {
+		state = pwrdm_get_deepest_state(pwrst->pwrdm);
+		if (!enable)
+			state = max(state, (u32)PWRDM_POWER_RET);
+
 		if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
 				pwrst->pwrdm == core_pwrdm &&
 				state == PWRDM_POWER_OFF) {
@@ -660,6 +659,7 @@ int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state)
 static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 {
 	struct power_state *pwrst;
+	u32 state;
 
 	if (!pwrdm->pwrsts)
 		return 0;
@@ -668,7 +668,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+
+	state = pwrdm_get_deepest_state(pwrdm);
+	pwrst->next_state = max(state, (u32)PWRDM_POWER_RET);
+
 	list_add(&pwrst->node, &pwrst_list);
 
 	if (pwrdm_has_hdwr_sar(pwrdm))
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 96ad3dbe..9c80c19 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -1078,3 +1078,28 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
 
 	return 0;
 }
+
+/**
+ * pwrdm_get_deepest_state - Get deepest valid state domain can enter
+ * @pwrdm: struct powerdomain *
+ *
+ * Find and return the deepest valid state a power domain can be in.
+ * Returns the deepest state that @pwrdm can enter.
+ */
+u32 pwrdm_get_deepest_state(struct powerdomain *pwrdm)
+{
+	u32 valid_states, deepest_state;
+
+	valid_states = pwrdm->pwrsts;
+
+	if (valid_states & PWRSTS_OFF)
+		deepest_state = PWRDM_POWER_OFF;
+	else if (valid_states & PWRSTS_RET)
+		deepest_state = PWRDM_POWER_RET;
+	else if (valid_states & PWRSTS_INACTIVE)
+		deepest_state = PWRDM_POWER_INACTIVE;
+	else
+		deepest_state = PWRDM_POWER_ON;
+
+	return deepest_state;
+}
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 0d72a8a..9688ff1 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -220,6 +220,8 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
 int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
 bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
 
+u32 pwrdm_get_deepest_state(struct powerdomain *pwrdm);
+
 extern void omap242x_powerdomains_init(void);
 extern void omap243x_powerdomains_init(void);
 extern void omap3xxx_powerdomains_init(void);
-- 
1.7.9.4


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

* [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
@ 2012-04-24  4:36       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-24  4:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:46:20PM -0700, Kevin Hilman wrote:
> Hi Mark,

Hi Kevin.

> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >
> > Typical OMAP3 SoCs have four power domain states: ON,
> > INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
> > has only two states: ON and INACTIVE.  To distinguish which
> > set of states the current device has, add the 'OMAP3_HAS_PWROFF'
> > feature.  When that feature/bit is set, the device supports the
> > RETENTION and OFF states; otherwise, it doesn't.
> >
> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> 
> Paul has mentioned this already, but the same applies here: We shouldn't
> be using SoC-global feature flag for this.   We already have per-pwrdm
> flags that indicate what states a given powerdomain suports (see .pwrsts
> field.)
> 
> Wherever we have blind writes to next powerstates that assume support
> for RET/OFF is present, those should probably use a helper function from
> the powerdomain code that checks if that state is even supported.

How about something like the patch below?
Note: its not well tested; just RFC.

> Jean's work on functional powerstates will probably help here if you
> really need to support INACTIVE.  However, Paul may be right in that you
> might just start with supporing ON only, and validate that module-level
> wakups acutally work.

Yes, I think INACTIVE is a red herring so I'm going to stick with k.o
master branch for now (IOW, not base on Jean's patches).  If you still
want me to base on his patches, just let me know.

Mark
--

>From 32c54adb15c76396aeec809d38de4dde936b1e66 Mon Sep 17 00:00:00 2001
From: "Mark A. Greer" <mgreer@animalcreek.com>
Date: Mon, 23 Apr 2012 17:48:06 -0700
Subject: [PATCH] arm: omap: Use only valid power domain states

Some parts of the OMAP code assume that all power
domains support certain states (e.g., RET & OFF).
This isn't always true (e.g., the am35x family of
SoC's) so those assumptions need to be removed.

Remove those assumptions by looking up the deepest
state that a power domain can be in whereever its
being blindly set.  The 'max()' of the deepest
state and what the code formerly wanted to set it
to, is the correct state.  If the code formerly
wanted to set it to PWRDM_POWER_OFF, then the
deepest possible state will be used (i.e., no
need to perform the 'max()').

The code still assumes that ON is a valid state.

Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c |   14 ++++++++++----
 arch/arm/mach-omap2/pm34xx.c      |   15 +++++++++------
 arch/arm/mach-omap2/powerdomain.c |   25 +++++++++++++++++++++++++
 arch/arm/mach-omap2/powerdomain.h |    2 ++
 4 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 5358664..60aa0c3 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -175,19 +175,25 @@ static int next_valid_state(struct cpuidle_device *dev,
 	struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
 	struct cpuidle_state *curr = &drv->states[index];
 	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
-	u32 mpu_deepest_state = PWRDM_POWER_RET;
-	u32 core_deepest_state = PWRDM_POWER_RET;
+	u32 mpu_deepest_state, mpu_deepest_possible;
+	u32 core_deepest_state, core_deepest_possible;
 	int next_index = -1;
 
+	mpu_deepest_possible = pwrdm_get_deepest_state(mpu_pd);
+	mpu_deepest_state = max(mpu_deepest_possible, (u32)PWRDM_POWER_RET);
+
+	core_deepest_possible = pwrdm_get_deepest_state(core_pd);
+	core_deepest_state = max(core_deepest_possible, (u32)PWRDM_POWER_RET);
+
 	if (enable_off_mode) {
-		mpu_deepest_state = PWRDM_POWER_OFF;
+		mpu_deepest_state = mpu_deepest_possible;
 		/*
 		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
 		 * CORE OFF mode is not supported in a stable form, restrict
 		 * instead the CORE state to RET.
 		 */
 		if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
-			core_deepest_state = PWRDM_POWER_OFF;
+			core_deepest_state = core_deepest_possible;
 	}
 
 	/* Check if current state is valid */
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index ec92676..7737bfb 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -614,12 +614,11 @@ void omap3_pm_off_mode_enable(int enable)
 	struct power_state *pwrst;
 	u32 state;
 
-	if (enable)
-		state = PWRDM_POWER_OFF;
-	else
-		state = PWRDM_POWER_RET;
-
 	list_for_each_entry(pwrst, &pwrst_list, node) {
+		state = pwrdm_get_deepest_state(pwrst->pwrdm);
+		if (!enable)
+			state = max(state, (u32)PWRDM_POWER_RET);
+
 		if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
 				pwrst->pwrdm == core_pwrdm &&
 				state == PWRDM_POWER_OFF) {
@@ -660,6 +659,7 @@ int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state)
 static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 {
 	struct power_state *pwrst;
+	u32 state;
 
 	if (!pwrdm->pwrsts)
 		return 0;
@@ -668,7 +668,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+
+	state = pwrdm_get_deepest_state(pwrdm);
+	pwrst->next_state = max(state, (u32)PWRDM_POWER_RET);
+
 	list_add(&pwrst->node, &pwrst_list);
 
 	if (pwrdm_has_hdwr_sar(pwrdm))
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 96ad3dbe..9c80c19 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -1078,3 +1078,28 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
 
 	return 0;
 }
+
+/**
+ * pwrdm_get_deepest_state - Get deepest valid state domain can enter
+ * @pwrdm: struct powerdomain *
+ *
+ * Find and return the deepest valid state a power domain can be in.
+ * Returns the deepest state that @pwrdm can enter.
+ */
+u32 pwrdm_get_deepest_state(struct powerdomain *pwrdm)
+{
+	u32 valid_states, deepest_state;
+
+	valid_states = pwrdm->pwrsts;
+
+	if (valid_states & PWRSTS_OFF)
+		deepest_state = PWRDM_POWER_OFF;
+	else if (valid_states & PWRSTS_RET)
+		deepest_state = PWRDM_POWER_RET;
+	else if (valid_states & PWRSTS_INACTIVE)
+		deepest_state = PWRDM_POWER_INACTIVE;
+	else
+		deepest_state = PWRDM_POWER_ON;
+
+	return deepest_state;
+}
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 0d72a8a..9688ff1 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -220,6 +220,8 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
 int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
 bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
 
+u32 pwrdm_get_deepest_state(struct powerdomain *pwrdm);
+
 extern void omap242x_powerdomains_init(void);
 extern void omap243x_powerdomains_init(void);
 extern void omap3xxx_powerdomains_init(void);
-- 
1.7.9.4

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-11 21:37     ` Paul Walmsley
@ 2012-04-24 20:51       ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-24 20:51 UTC (permalink / raw)
  To: Paul Walmsley, khilman; +Cc: linux-omap, linux-arm-kernel

On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
> Hi

Hi Paul, Kevin.

> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
> > which calls omap_sram_idle().  omap_sram_idle() eventually
> > causes a 'wfi' instruction to be executed effectively putting
> > the system to sleep.  It is assumed that an I/O wake-up event
> > will occur to wake the system up again.  This doesn't work on
> > systems that don't support I/O wake-ups (indicated by
> > omap3_has_io_wakeup() returning false).
> > 
> > To handle this, follow the same path in omap3_enter_idle()
> > that would be followed if an interrupt were pending.
> 
> I don't quite understand this patch.  Are you saying that AM3517/3505 
> can't wake from WFI?  That would seem odd.
> 
> There are other sources of wakeup on the system other than I/O wakeup.  
> I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> RETENTION or OFF.  And as I understand it, neither of those apply to 
> AM3517/3505?
> 
> Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> should be able to cause the ARM to exit WFI by asserting their 
> SWAKEUP lines and raising their interrupt lines.

I have changed the code to keep everything in the ON state and use
cpu_do_idle()--basically a wfi, cpu_v7_do_idle() in this case--and everything
works well (except networking, see below) when using an mmc-based rootfs.

The issue is with the emac--it can't wake the system up unless there
is an irq from the PHY to a wakeup-enabled GPIO (confirmed by h/w engr).
So, when using networking or using an nfs-based rootfs, there are all
kinds of timeouts, etc.  Basically, doing a wfi (i.e., pm_idle or cpuidle)
and expecting the emac to wake the system back up won't work.

How would you like me to proceed (to avoid the wfi in pm_idle & cpuidle)?

Thanks,

Mark

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-24 20:51       ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-24 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
> Hi

Hi Paul, Kevin.

> On Wed, 11 Apr 2012, Mark A. Greer wrote:
> 
> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > 
> > Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
> > which calls omap_sram_idle().  omap_sram_idle() eventually
> > causes a 'wfi' instruction to be executed effectively putting
> > the system to sleep.  It is assumed that an I/O wake-up event
> > will occur to wake the system up again.  This doesn't work on
> > systems that don't support I/O wake-ups (indicated by
> > omap3_has_io_wakeup() returning false).
> > 
> > To handle this, follow the same path in omap3_enter_idle()
> > that would be followed if an interrupt were pending.
> 
> I don't quite understand this patch.  Are you saying that AM3517/3505 
> can't wake from WFI?  That would seem odd.
> 
> There are other sources of wakeup on the system other than I/O wakeup.  
> I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> RETENTION or OFF.  And as I understand it, neither of those apply to 
> AM3517/3505?
> 
> Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> should be able to cause the ARM to exit WFI by asserting their 
> SWAKEUP lines and raising their interrupt lines.

I have changed the code to keep everything in the ON state and use
cpu_do_idle()--basically a wfi, cpu_v7_do_idle() in this case--and everything
works well (except networking, see below) when using an mmc-based rootfs.

The issue is with the emac--it can't wake the system up unless there
is an irq from the PHY to a wakeup-enabled GPIO (confirmed by h/w engr).
So, when using networking or using an nfs-based rootfs, there are all
kinds of timeouts, etc.  Basically, doing a wfi (i.e., pm_idle or cpuidle)
and expecting the emac to wake the system back up won't work.

How would you like me to proceed (to avoid the wfi in pm_idle & cpuidle)?

Thanks,

Mark

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-24 20:51       ` Mark A. Greer
@ 2012-04-24 23:25         ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-24 23:25 UTC (permalink / raw)
  To: Paul Walmsley, khilman; +Cc: linux-omap, linux-arm-kernel

On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:
> On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
> > Hi
> 
> Hi Paul, Kevin.
> 
> > On Wed, 11 Apr 2012, Mark A. Greer wrote:
> > 
> > > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > > 
> > > Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
> > > which calls omap_sram_idle().  omap_sram_idle() eventually
> > > causes a 'wfi' instruction to be executed effectively putting
> > > the system to sleep.  It is assumed that an I/O wake-up event
> > > will occur to wake the system up again.  This doesn't work on
> > > systems that don't support I/O wake-ups (indicated by
> > > omap3_has_io_wakeup() returning false).
> > > 
> > > To handle this, follow the same path in omap3_enter_idle()
> > > that would be followed if an interrupt were pending.
> > 
> > I don't quite understand this patch.  Are you saying that AM3517/3505 
> > can't wake from WFI?  That would seem odd.
> > 
> > There are other sources of wakeup on the system other than I/O wakeup.  
> > I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> > RETENTION or OFF.  And as I understand it, neither of those apply to 
> > AM3517/3505?
> > 
> > Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> > should be able to cause the ARM to exit WFI by asserting their 
> > SWAKEUP lines and raising their interrupt lines.
> 
> I have changed the code to keep everything in the ON state and use
> cpu_do_idle()--basically a wfi, cpu_v7_do_idle() in this case--and everything
> works well (except networking, see below) when using an mmc-based rootfs.
> 
> The issue is with the emac--it can't wake the system up unless there
> is an irq from the PHY to a wakeup-enabled GPIO (confirmed by h/w engr).
> So, when using networking or using an nfs-based rootfs, there are all
> kinds of timeouts, etc.  Basically, doing a wfi (i.e., pm_idle or cpuidle)
> and expecting the emac to wake the system back up won't work.
> 
> How would you like me to proceed (to avoid the wfi in pm_idle & cpuidle)?

Just thinking out loud...

We could chose whether pm_idle & cpuidle issue a wfi based on
whether there is a davinci-emac present.  The issue with that is
that someday there may be another SoC that has a davinci-emac that
can wake up the system.  I know cpu_is_xxx() is frowned upon but
this does seem like a proper usage of it--the deciding factor
really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
is enabled).

Mark
--

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-24 23:25         ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-24 23:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:
> On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
> > Hi
> 
> Hi Paul, Kevin.
> 
> > On Wed, 11 Apr 2012, Mark A. Greer wrote:
> > 
> > > From: "Mark A. Greer" <mgreer@animalcreek.com>
> > > 
> > > Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
> > > which calls omap_sram_idle().  omap_sram_idle() eventually
> > > causes a 'wfi' instruction to be executed effectively putting
> > > the system to sleep.  It is assumed that an I/O wake-up event
> > > will occur to wake the system up again.  This doesn't work on
> > > systems that don't support I/O wake-ups (indicated by
> > > omap3_has_io_wakeup() returning false).
> > > 
> > > To handle this, follow the same path in omap3_enter_idle()
> > > that would be followed if an interrupt were pending.
> > 
> > I don't quite understand this patch.  Are you saying that AM3517/3505 
> > can't wake from WFI?  That would seem odd.
> > 
> > There are other sources of wakeup on the system other than I/O wakeup.  
> > I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
> > RETENTION or OFF.  And as I understand it, neither of those apply to 
> > AM3517/3505?
> > 
> > Even if I/O wakeups aren't supported, many of the IP blocks on the system 
> > should be able to cause the ARM to exit WFI by asserting their 
> > SWAKEUP lines and raising their interrupt lines.
> 
> I have changed the code to keep everything in the ON state and use
> cpu_do_idle()--basically a wfi, cpu_v7_do_idle() in this case--and everything
> works well (except networking, see below) when using an mmc-based rootfs.
> 
> The issue is with the emac--it can't wake the system up unless there
> is an irq from the PHY to a wakeup-enabled GPIO (confirmed by h/w engr).
> So, when using networking or using an nfs-based rootfs, there are all
> kinds of timeouts, etc.  Basically, doing a wfi (i.e., pm_idle or cpuidle)
> and expecting the emac to wake the system back up won't work.
> 
> How would you like me to proceed (to avoid the wfi in pm_idle & cpuidle)?

Just thinking out loud...

We could chose whether pm_idle & cpuidle issue a wfi based on
whether there is a davinci-emac present.  The issue with that is
that someday there may be another SoC that has a davinci-emac that
can wake up the system.  I know cpu_is_xxx() is frowned upon but
this does seem like a proper usage of it--the deciding factor
really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
is enabled).

Mark
--

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

* Re: [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
  2012-04-24  4:36       ` Mark A. Greer
@ 2012-04-27 21:07         ` Kevin Hilman
  -1 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-27 21:07 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linux-omap, linux-arm-kernel, paul

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> On Wed, Apr 11, 2012 at 03:46:20PM -0700, Kevin Hilman wrote:
>> Hi Mark,
>
> Hi Kevin.
>
>> "Mark A. Greer" <mgreer@animalcreek.com> writes:
>> 
>> > From: "Mark A. Greer" <mgreer@animalcreek.com>
>> >
>> > Typical OMAP3 SoCs have four power domain states: ON,
>> > INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
>> > has only two states: ON and INACTIVE.  To distinguish which
>> > set of states the current device has, add the 'OMAP3_HAS_PWROFF'
>> > feature.  When that feature/bit is set, the device supports the
>> > RETENTION and OFF states; otherwise, it doesn't.
>> >
>> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
>> 
>> Paul has mentioned this already, but the same applies here: We shouldn't
>> be using SoC-global feature flag for this.   We already have per-pwrdm
>> flags that indicate what states a given powerdomain suports (see .pwrsts
>> field.)
>> 
>> Wherever we have blind writes to next powerstates that assume support
>> for RET/OFF is present, those should probably use a helper function from
>> the powerdomain code that checks if that state is even supported.
>
> How about something like the patch below?
> Note: its not well tested; just RFC.

Yes, your proposed patch looks right to me.

I guess it's up to Paul & Jean to see if they'd rather see this build on
top of the Jean's functional power state work, or take this as a
standalone fix.

Kevin

>> Jean's work on functional powerstates will probably help here if you
>> really need to support INACTIVE.  However, Paul may be right in that you
>> might just start with supporing ON only, and validate that module-level
>> wakups acutally work.
>
> Yes, I think INACTIVE is a red herring so I'm going to stick with k.o
> master branch for now (IOW, not base on Jean's patches).  If you still
> want me to base on his patches, just let me know.
>
> Mark
> --
>
> From 32c54adb15c76396aeec809d38de4dde936b1e66 Mon Sep 17 00:00:00 2001
> From: "Mark A. Greer" <mgreer@animalcreek.com>
> Date: Mon, 23 Apr 2012 17:48:06 -0700
> Subject: [PATCH] arm: omap: Use only valid power domain states
>
> Some parts of the OMAP code assume that all power
> domains support certain states (e.g., RET & OFF).
> This isn't always true (e.g., the am35x family of
> SoC's) so those assumptions need to be removed.
>
> Remove those assumptions by looking up the deepest
> state that a power domain can be in whereever its
> being blindly set.  The 'max()' of the deepest
> state and what the code formerly wanted to set it
> to, is the correct state.  If the code formerly
> wanted to set it to PWRDM_POWER_OFF, then the
> deepest possible state will be used (i.e., no
> need to perform the 'max()').
>
> The code still assumes that ON is a valid state.
>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/cpuidle34xx.c |   14 ++++++++++----
>  arch/arm/mach-omap2/pm34xx.c      |   15 +++++++++------
>  arch/arm/mach-omap2/powerdomain.c |   25 +++++++++++++++++++++++++
>  arch/arm/mach-omap2/powerdomain.h |    2 ++
>  4 files changed, 46 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 5358664..60aa0c3 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -175,19 +175,25 @@ static int next_valid_state(struct cpuidle_device *dev,
>  	struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
>  	struct cpuidle_state *curr = &drv->states[index];
>  	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
> -	u32 mpu_deepest_state = PWRDM_POWER_RET;
> -	u32 core_deepest_state = PWRDM_POWER_RET;
> +	u32 mpu_deepest_state, mpu_deepest_possible;
> +	u32 core_deepest_state, core_deepest_possible;
>  	int next_index = -1;
>  
> +	mpu_deepest_possible = pwrdm_get_deepest_state(mpu_pd);
> +	mpu_deepest_state = max(mpu_deepest_possible, (u32)PWRDM_POWER_RET);
> +
> +	core_deepest_possible = pwrdm_get_deepest_state(core_pd);
> +	core_deepest_state = max(core_deepest_possible, (u32)PWRDM_POWER_RET);
> +
>  	if (enable_off_mode) {
> -		mpu_deepest_state = PWRDM_POWER_OFF;
> +		mpu_deepest_state = mpu_deepest_possible;
>  		/*
>  		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
>  		 * CORE OFF mode is not supported in a stable form, restrict
>  		 * instead the CORE state to RET.
>  		 */
>  		if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
> -			core_deepest_state = PWRDM_POWER_OFF;
> +			core_deepest_state = core_deepest_possible;
>  	}
>  
>  	/* Check if current state is valid */
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index ec92676..7737bfb 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -614,12 +614,11 @@ void omap3_pm_off_mode_enable(int enable)
>  	struct power_state *pwrst;
>  	u32 state;
>  
> -	if (enable)
> -		state = PWRDM_POWER_OFF;
> -	else
> -		state = PWRDM_POWER_RET;
> -
>  	list_for_each_entry(pwrst, &pwrst_list, node) {
> +		state = pwrdm_get_deepest_state(pwrst->pwrdm);
> +		if (!enable)
> +			state = max(state, (u32)PWRDM_POWER_RET);
> +
>  		if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
>  				pwrst->pwrdm == core_pwrdm &&
>  				state == PWRDM_POWER_OFF) {
> @@ -660,6 +659,7 @@ int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state)
>  static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
>  {
>  	struct power_state *pwrst;
> +	u32 state;
>  
>  	if (!pwrdm->pwrsts)
>  		return 0;
> @@ -668,7 +668,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
>  	if (!pwrst)
>  		return -ENOMEM;
>  	pwrst->pwrdm = pwrdm;
> -	pwrst->next_state = PWRDM_POWER_RET;
> +
> +	state = pwrdm_get_deepest_state(pwrdm);
> +	pwrst->next_state = max(state, (u32)PWRDM_POWER_RET);
> +
>  	list_add(&pwrst->node, &pwrst_list);
>  
>  	if (pwrdm_has_hdwr_sar(pwrdm))
> diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
> index 96ad3dbe..9c80c19 100644
> --- a/arch/arm/mach-omap2/powerdomain.c
> +++ b/arch/arm/mach-omap2/powerdomain.c
> @@ -1078,3 +1078,28 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
>  
>  	return 0;
>  }
> +
> +/**
> + * pwrdm_get_deepest_state - Get deepest valid state domain can enter
> + * @pwrdm: struct powerdomain *
> + *
> + * Find and return the deepest valid state a power domain can be in.
> + * Returns the deepest state that @pwrdm can enter.
> + */
> +u32 pwrdm_get_deepest_state(struct powerdomain *pwrdm)
> +{
> +	u32 valid_states, deepest_state;
> +
> +	valid_states = pwrdm->pwrsts;
> +
> +	if (valid_states & PWRSTS_OFF)
> +		deepest_state = PWRDM_POWER_OFF;
> +	else if (valid_states & PWRSTS_RET)
> +		deepest_state = PWRDM_POWER_RET;
> +	else if (valid_states & PWRSTS_INACTIVE)
> +		deepest_state = PWRDM_POWER_INACTIVE;
> +	else
> +		deepest_state = PWRDM_POWER_ON;
> +
> +	return deepest_state;
> +}
> diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
> index 0d72a8a..9688ff1 100644
> --- a/arch/arm/mach-omap2/powerdomain.h
> +++ b/arch/arm/mach-omap2/powerdomain.h
> @@ -220,6 +220,8 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
>  int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
>  bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
>  
> +u32 pwrdm_get_deepest_state(struct powerdomain *pwrdm);
> +
>  extern void omap242x_powerdomains_init(void);
>  extern void omap243x_powerdomains_init(void);
>  extern void omap3xxx_powerdomains_init(void);

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

* [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
@ 2012-04-27 21:07         ` Kevin Hilman
  0 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-27 21:07 UTC (permalink / raw)
  To: linux-arm-kernel

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> On Wed, Apr 11, 2012 at 03:46:20PM -0700, Kevin Hilman wrote:
>> Hi Mark,
>
> Hi Kevin.
>
>> "Mark A. Greer" <mgreer@animalcreek.com> writes:
>> 
>> > From: "Mark A. Greer" <mgreer@animalcreek.com>
>> >
>> > Typical OMAP3 SoCs have four power domain states: ON,
>> > INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
>> > has only two states: ON and INACTIVE.  To distinguish which
>> > set of states the current device has, add the 'OMAP3_HAS_PWROFF'
>> > feature.  When that feature/bit is set, the device supports the
>> > RETENTION and OFF states; otherwise, it doesn't.
>> >
>> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
>> 
>> Paul has mentioned this already, but the same applies here: We shouldn't
>> be using SoC-global feature flag for this.   We already have per-pwrdm
>> flags that indicate what states a given powerdomain suports (see .pwrsts
>> field.)
>> 
>> Wherever we have blind writes to next powerstates that assume support
>> for RET/OFF is present, those should probably use a helper function from
>> the powerdomain code that checks if that state is even supported.
>
> How about something like the patch below?
> Note: its not well tested; just RFC.

Yes, your proposed patch looks right to me.

I guess it's up to Paul & Jean to see if they'd rather see this build on
top of the Jean's functional power state work, or take this as a
standalone fix.

Kevin

>> Jean's work on functional powerstates will probably help here if you
>> really need to support INACTIVE.  However, Paul may be right in that you
>> might just start with supporing ON only, and validate that module-level
>> wakups acutally work.
>
> Yes, I think INACTIVE is a red herring so I'm going to stick with k.o
> master branch for now (IOW, not base on Jean's patches).  If you still
> want me to base on his patches, just let me know.
>
> Mark
> --
>
> From 32c54adb15c76396aeec809d38de4dde936b1e66 Mon Sep 17 00:00:00 2001
> From: "Mark A. Greer" <mgreer@animalcreek.com>
> Date: Mon, 23 Apr 2012 17:48:06 -0700
> Subject: [PATCH] arm: omap: Use only valid power domain states
>
> Some parts of the OMAP code assume that all power
> domains support certain states (e.g., RET & OFF).
> This isn't always true (e.g., the am35x family of
> SoC's) so those assumptions need to be removed.
>
> Remove those assumptions by looking up the deepest
> state that a power domain can be in whereever its
> being blindly set.  The 'max()' of the deepest
> state and what the code formerly wanted to set it
> to, is the correct state.  If the code formerly
> wanted to set it to PWRDM_POWER_OFF, then the
> deepest possible state will be used (i.e., no
> need to perform the 'max()').
>
> The code still assumes that ON is a valid state.
>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> ---
>  arch/arm/mach-omap2/cpuidle34xx.c |   14 ++++++++++----
>  arch/arm/mach-omap2/pm34xx.c      |   15 +++++++++------
>  arch/arm/mach-omap2/powerdomain.c |   25 +++++++++++++++++++++++++
>  arch/arm/mach-omap2/powerdomain.h |    2 ++
>  4 files changed, 46 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 5358664..60aa0c3 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -175,19 +175,25 @@ static int next_valid_state(struct cpuidle_device *dev,
>  	struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
>  	struct cpuidle_state *curr = &drv->states[index];
>  	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
> -	u32 mpu_deepest_state = PWRDM_POWER_RET;
> -	u32 core_deepest_state = PWRDM_POWER_RET;
> +	u32 mpu_deepest_state, mpu_deepest_possible;
> +	u32 core_deepest_state, core_deepest_possible;
>  	int next_index = -1;
>  
> +	mpu_deepest_possible = pwrdm_get_deepest_state(mpu_pd);
> +	mpu_deepest_state = max(mpu_deepest_possible, (u32)PWRDM_POWER_RET);
> +
> +	core_deepest_possible = pwrdm_get_deepest_state(core_pd);
> +	core_deepest_state = max(core_deepest_possible, (u32)PWRDM_POWER_RET);
> +
>  	if (enable_off_mode) {
> -		mpu_deepest_state = PWRDM_POWER_OFF;
> +		mpu_deepest_state = mpu_deepest_possible;
>  		/*
>  		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
>  		 * CORE OFF mode is not supported in a stable form, restrict
>  		 * instead the CORE state to RET.
>  		 */
>  		if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
> -			core_deepest_state = PWRDM_POWER_OFF;
> +			core_deepest_state = core_deepest_possible;
>  	}
>  
>  	/* Check if current state is valid */
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index ec92676..7737bfb 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -614,12 +614,11 @@ void omap3_pm_off_mode_enable(int enable)
>  	struct power_state *pwrst;
>  	u32 state;
>  
> -	if (enable)
> -		state = PWRDM_POWER_OFF;
> -	else
> -		state = PWRDM_POWER_RET;
> -
>  	list_for_each_entry(pwrst, &pwrst_list, node) {
> +		state = pwrdm_get_deepest_state(pwrst->pwrdm);
> +		if (!enable)
> +			state = max(state, (u32)PWRDM_POWER_RET);
> +
>  		if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
>  				pwrst->pwrdm == core_pwrdm &&
>  				state == PWRDM_POWER_OFF) {
> @@ -660,6 +659,7 @@ int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state)
>  static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
>  {
>  	struct power_state *pwrst;
> +	u32 state;
>  
>  	if (!pwrdm->pwrsts)
>  		return 0;
> @@ -668,7 +668,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
>  	if (!pwrst)
>  		return -ENOMEM;
>  	pwrst->pwrdm = pwrdm;
> -	pwrst->next_state = PWRDM_POWER_RET;
> +
> +	state = pwrdm_get_deepest_state(pwrdm);
> +	pwrst->next_state = max(state, (u32)PWRDM_POWER_RET);
> +
>  	list_add(&pwrst->node, &pwrst_list);
>  
>  	if (pwrdm_has_hdwr_sar(pwrdm))
> diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
> index 96ad3dbe..9c80c19 100644
> --- a/arch/arm/mach-omap2/powerdomain.c
> +++ b/arch/arm/mach-omap2/powerdomain.c
> @@ -1078,3 +1078,28 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
>  
>  	return 0;
>  }
> +
> +/**
> + * pwrdm_get_deepest_state - Get deepest valid state domain can enter
> + * @pwrdm: struct powerdomain *
> + *
> + * Find and return the deepest valid state a power domain can be in.
> + * Returns the deepest state that @pwrdm can enter.
> + */
> +u32 pwrdm_get_deepest_state(struct powerdomain *pwrdm)
> +{
> +	u32 valid_states, deepest_state;
> +
> +	valid_states = pwrdm->pwrsts;
> +
> +	if (valid_states & PWRSTS_OFF)
> +		deepest_state = PWRDM_POWER_OFF;
> +	else if (valid_states & PWRSTS_RET)
> +		deepest_state = PWRDM_POWER_RET;
> +	else if (valid_states & PWRSTS_INACTIVE)
> +		deepest_state = PWRDM_POWER_INACTIVE;
> +	else
> +		deepest_state = PWRDM_POWER_ON;
> +
> +	return deepest_state;
> +}
> diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
> index 0d72a8a..9688ff1 100644
> --- a/arch/arm/mach-omap2/powerdomain.h
> +++ b/arch/arm/mach-omap2/powerdomain.h
> @@ -220,6 +220,8 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
>  int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
>  bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
>  
> +u32 pwrdm_get_deepest_state(struct powerdomain *pwrdm);
> +
>  extern void omap242x_powerdomains_init(void);
>  extern void omap243x_powerdomains_init(void);
>  extern void omap3xxx_powerdomains_init(void);

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-24 23:25         ` Mark A. Greer
@ 2012-04-27 21:12           ` Kevin Hilman
  -1 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-27 21:12 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: Paul Walmsley, linux-omap, linux-arm-kernel

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:
>> On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
>> > Hi
>> 
>> Hi Paul, Kevin.
>> 
>> > On Wed, 11 Apr 2012, Mark A. Greer wrote:
>> > 
>> > > From: "Mark A. Greer" <mgreer@animalcreek.com>
>> > > 
>> > > Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
>> > > which calls omap_sram_idle().  omap_sram_idle() eventually
>> > > causes a 'wfi' instruction to be executed effectively putting
>> > > the system to sleep.  It is assumed that an I/O wake-up event
>> > > will occur to wake the system up again.  This doesn't work on
>> > > systems that don't support I/O wake-ups (indicated by
>> > > omap3_has_io_wakeup() returning false).
>> > > 
>> > > To handle this, follow the same path in omap3_enter_idle()
>> > > that would be followed if an interrupt were pending.
>> > 
>> > I don't quite understand this patch.  Are you saying that AM3517/3505 
>> > can't wake from WFI?  That would seem odd.
>> > 
>> > There are other sources of wakeup on the system other than I/O wakeup.  
>> > I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
>> > RETENTION or OFF.  And as I understand it, neither of those apply to 
>> > AM3517/3505?
>> > 
>> > Even if I/O wakeups aren't supported, many of the IP blocks on the system 
>> > should be able to cause the ARM to exit WFI by asserting their 
>> > SWAKEUP lines and raising their interrupt lines.
>> 
>> I have changed the code to keep everything in the ON state and use
>> cpu_do_idle()--basically a wfi, cpu_v7_do_idle() in this case--and everything
>> works well (except networking, see below) when using an mmc-based rootfs.
>> 
>> The issue is with the emac--it can't wake the system up unless there
>> is an irq from the PHY to a wakeup-enabled GPIO (confirmed by h/w engr).
>> So, when using networking or using an nfs-based rootfs, there are all
>> kinds of timeouts, etc.  Basically, doing a wfi (i.e., pm_idle or cpuidle)
>> and expecting the emac to wake the system back up won't work.
>> 
>> How would you like me to proceed (to avoid the wfi in pm_idle & cpuidle)?
>
> Just thinking out loud...
>
> We could chose whether pm_idle & cpuidle issue a wfi based on
> whether there is a davinci-emac present.  The issue with that is
> that someday there may be another SoC that has a davinci-emac that
> can wake up the system.  I know cpu_is_xxx() is frowned upon but
> this does seem like a proper usage of it--the deciding factor
> really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
> is enabled).

The presence of the davinci_emac is probably overkill, avoiding WFI
should really only be done when the davinci_emac is *active*.
e.g. using an am35x with an EMAC *present*, but not in use because
there's an MMC rootfs for example.

If there's a good way to detect an in-use davinci_emac, then
disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
use (e.g. module unloaded etc.) then enable_hlt() can be used to
(re)allow WFI.

Kevin



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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-27 21:12           ` Kevin Hilman
  0 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-27 21:12 UTC (permalink / raw)
  To: linux-arm-kernel

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:
>> On Wed, Apr 11, 2012 at 03:37:47PM -0600, Paul Walmsley wrote:
>> > Hi
>> 
>> Hi Paul, Kevin.
>> 
>> > On Wed, 11 Apr 2012, Mark A. Greer wrote:
>> > 
>> > > From: "Mark A. Greer" <mgreer@animalcreek.com>
>> > > 
>> > > Currently, the OMAP3 cpuidle driver calls omap3_enter_idle()
>> > > which calls omap_sram_idle().  omap_sram_idle() eventually
>> > > causes a 'wfi' instruction to be executed effectively putting
>> > > the system to sleep.  It is assumed that an I/O wake-up event
>> > > will occur to wake the system up again.  This doesn't work on
>> > > systems that don't support I/O wake-ups (indicated by
>> > > omap3_has_io_wakeup() returning false).
>> > > 
>> > > To handle this, follow the same path in omap3_enter_idle()
>> > > that would be followed if an interrupt were pending.
>> > 
>> > I don't quite understand this patch.  Are you saying that AM3517/3505 
>> > can't wake from WFI?  That would seem odd.
>> > 
>> > There are other sources of wakeup on the system other than I/O wakeup.  
>> > I/O wakeup only applies to wakeups from the I/O pads when the chip is in 
>> > RETENTION or OFF.  And as I understand it, neither of those apply to 
>> > AM3517/3505?
>> > 
>> > Even if I/O wakeups aren't supported, many of the IP blocks on the system 
>> > should be able to cause the ARM to exit WFI by asserting their 
>> > SWAKEUP lines and raising their interrupt lines.
>> 
>> I have changed the code to keep everything in the ON state and use
>> cpu_do_idle()--basically a wfi, cpu_v7_do_idle() in this case--and everything
>> works well (except networking, see below) when using an mmc-based rootfs.
>> 
>> The issue is with the emac--it can't wake the system up unless there
>> is an irq from the PHY to a wakeup-enabled GPIO (confirmed by h/w engr).
>> So, when using networking or using an nfs-based rootfs, there are all
>> kinds of timeouts, etc.  Basically, doing a wfi (i.e., pm_idle or cpuidle)
>> and expecting the emac to wake the system back up won't work.
>> 
>> How would you like me to proceed (to avoid the wfi in pm_idle & cpuidle)?
>
> Just thinking out loud...
>
> We could chose whether pm_idle & cpuidle issue a wfi based on
> whether there is a davinci-emac present.  The issue with that is
> that someday there may be another SoC that has a davinci-emac that
> can wake up the system.  I know cpu_is_xxx() is frowned upon but
> this does seem like a proper usage of it--the deciding factor
> really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
> is enabled).

The presence of the davinci_emac is probably overkill, avoiding WFI
should really only be done when the davinci_emac is *active*.
e.g. using an am35x with an EMAC *present*, but not in use because
there's an MMC rootfs for example.

If there's a good way to detect an in-use davinci_emac, then
disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
use (e.g. module unloaded etc.) then enable_hlt() can be used to
(re)allow WFI.

Kevin

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-27 21:12           ` Kevin Hilman
@ 2012-04-27 21:55             ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-27 21:55 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Paul Walmsley, linux-omap, linux-arm-kernel

On Fri, Apr 27, 2012 at 02:12:12PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:

> > We could chose whether pm_idle & cpuidle issue a wfi based on
> > whether there is a davinci-emac present.  The issue with that is
> > that someday there may be another SoC that has a davinci-emac that
> > can wake up the system.  I know cpu_is_xxx() is frowned upon but
> > this does seem like a proper usage of it--the deciding factor
> > really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
> > is enabled).
> 
> The presence of the davinci_emac is probably overkill, avoiding WFI
> should really only be done when the davinci_emac is *active*.
> e.g. using an am35x with an EMAC *present*, but not in use because
> there's an MMC rootfs for example.
> 
> If there's a good way to detect an in-use davinci_emac, then
> disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
> use (e.g. module unloaded etc.) then enable_hlt() can be used to
> (re)allow WFI.

Good idea.  I'll see what I can do.

Mark

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-27 21:55             ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-27 21:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 27, 2012 at 02:12:12PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:

> > We could chose whether pm_idle & cpuidle issue a wfi based on
> > whether there is a davinci-emac present.  The issue with that is
> > that someday there may be another SoC that has a davinci-emac that
> > can wake up the system.  I know cpu_is_xxx() is frowned upon but
> > this does seem like a proper usage of it--the deciding factor
> > really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
> > is enabled).
> 
> The presence of the davinci_emac is probably overkill, avoiding WFI
> should really only be done when the davinci_emac is *active*.
> e.g. using an am35x with an EMAC *present*, but not in use because
> there's an MMC rootfs for example.
> 
> If there's a good way to detect an in-use davinci_emac, then
> disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
> use (e.g. module unloaded etc.) then enable_hlt() can be used to
> (re)allow WFI.

Good idea.  I'll see what I can do.

Mark

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-27 21:12           ` Kevin Hilman
@ 2012-04-30 21:34             ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-30 21:34 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Paul Walmsley, linux-omap, linux-arm-kernel

On Fri, Apr 27, 2012 at 02:12:12PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:

> > Just thinking out loud...
> >
> > We could chose whether pm_idle & cpuidle issue a wfi based on
> > whether there is a davinci-emac present.  The issue with that is
> > that someday there may be another SoC that has a davinci-emac that
> > can wake up the system.  I know cpu_is_xxx() is frowned upon but
> > this does seem like a proper usage of it--the deciding factor
> > really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
> > is enabled).
> 
> The presence of the davinci_emac is probably overkill, avoiding WFI
> should really only be done when the davinci_emac is *active*.
> e.g. using an am35x with an EMAC *present*, but not in use because
> there's an MMC rootfs for example.
> 
> If there's a good way to detect an in-use davinci_emac, then
> disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
> use (e.g. module unloaded etc.) then enable_hlt() can be used to
> (re)allow WFI.

This can work for pm_idle but what should be done for cpu_idle
(as in, omap3_enter_idle[_bm])?  We should have some sort of
solution for that so users can safely enable CONFIG_CPU_IDLE
and not have the am3517 fall apart.

Mark

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-30 21:34             ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-30 21:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 27, 2012 at 02:12:12PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:

> > Just thinking out loud...
> >
> > We could chose whether pm_idle & cpuidle issue a wfi based on
> > whether there is a davinci-emac present.  The issue with that is
> > that someday there may be another SoC that has a davinci-emac that
> > can wake up the system.  I know cpu_is_xxx() is frowned upon but
> > this does seem like a proper usage of it--the deciding factor
> > really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
> > is enabled).
> 
> The presence of the davinci_emac is probably overkill, avoiding WFI
> should really only be done when the davinci_emac is *active*.
> e.g. using an am35x with an EMAC *present*, but not in use because
> there's an MMC rootfs for example.
> 
> If there's a good way to detect an in-use davinci_emac, then
> disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
> use (e.g. module unloaded etc.) then enable_hlt() can be used to
> (re)allow WFI.

This can work for pm_idle but what should be done for cpu_idle
(as in, omap3_enter_idle[_bm])?  We should have some sort of
solution for that so users can safely enable CONFIG_CPU_IDLE
and not have the am3517 fall apart.

Mark

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-30 21:34             ` Mark A. Greer
@ 2012-04-30 22:00               ` Kevin Hilman
  -1 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-30 22:00 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: Paul Walmsley, linux-omap, linux-arm-kernel

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> On Fri, Apr 27, 2012 at 02:12:12PM -0700, Kevin Hilman wrote:
>> "Mark A. Greer" <mgreer@animalcreek.com> writes:
>> 
>> > On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:
>
>> > Just thinking out loud...
>> >
>> > We could chose whether pm_idle & cpuidle issue a wfi based on
>> > whether there is a davinci-emac present.  The issue with that is
>> > that someday there may be another SoC that has a davinci-emac that
>> > can wake up the system.  I know cpu_is_xxx() is frowned upon but
>> > this does seem like a proper usage of it--the deciding factor
>> > really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
>> > is enabled).
>> 
>> The presence of the davinci_emac is probably overkill, avoiding WFI
>> should really only be done when the davinci_emac is *active*.
>> e.g. using an am35x with an EMAC *present*, but not in use because
>> there's an MMC rootfs for example.
>> 
>> If there's a good way to detect an in-use davinci_emac, then
>> disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
>> use (e.g. module unloaded etc.) then enable_hlt() can be used to
>> (re)allow WFI.
>
> This can work for pm_idle but what should be done for cpu_idle
> (as in, omap3_enter_idle[_bm])?  We should have some sort of
> solution for that so users can safely enable CONFIG_CPU_IDLE
> and not have the am3517 fall apart.

disable_hlt() will prevent either the default idle *or* CPUidle from
being called.

It will simply call cpu_relax() instead of calling any idle
function. (c.f. cpu_idle() in arch/arm/kernel/process.c)

Kevin

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-30 22:00               ` Kevin Hilman
  0 siblings, 0 replies; 126+ messages in thread
From: Kevin Hilman @ 2012-04-30 22:00 UTC (permalink / raw)
  To: linux-arm-kernel

"Mark A. Greer" <mgreer@animalcreek.com> writes:

> On Fri, Apr 27, 2012 at 02:12:12PM -0700, Kevin Hilman wrote:
>> "Mark A. Greer" <mgreer@animalcreek.com> writes:
>> 
>> > On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:
>
>> > Just thinking out loud...
>> >
>> > We could chose whether pm_idle & cpuidle issue a wfi based on
>> > whether there is a davinci-emac present.  The issue with that is
>> > that someday there may be another SoC that has a davinci-emac that
>> > can wake up the system.  I know cpu_is_xxx() is frowned upon but
>> > this does seem like a proper usage of it--the deciding factor
>> > really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
>> > is enabled).
>> 
>> The presence of the davinci_emac is probably overkill, avoiding WFI
>> should really only be done when the davinci_emac is *active*.
>> e.g. using an am35x with an EMAC *present*, but not in use because
>> there's an MMC rootfs for example.
>> 
>> If there's a good way to detect an in-use davinci_emac, then
>> disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
>> use (e.g. module unloaded etc.) then enable_hlt() can be used to
>> (re)allow WFI.
>
> This can work for pm_idle but what should be done for cpu_idle
> (as in, omap3_enter_idle[_bm])?  We should have some sort of
> solution for that so users can safely enable CONFIG_CPU_IDLE
> and not have the am3517 fall apart.

disable_hlt() will prevent either the default idle *or* CPUidle from
being called.

It will simply call cpu_relax() instead of calling any idle
function. (c.f. cpu_idle() in arch/arm/kernel/process.c)

Kevin

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

* Re: [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
  2012-04-27 21:07         ` Kevin Hilman
@ 2012-04-30 22:08           ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-30 22:08 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, linux-arm-kernel, paul

On Fri, Apr 27, 2012 at 02:07:13PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > On Wed, Apr 11, 2012 at 03:46:20PM -0700, Kevin Hilman wrote:
> >> Hi Mark,
> >
> > Hi Kevin.
> >
> >> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> >> 
> >> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >> >
> >> > Typical OMAP3 SoCs have four power domain states: ON,
> >> > INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
> >> > has only two states: ON and INACTIVE.  To distinguish which
> >> > set of states the current device has, add the 'OMAP3_HAS_PWROFF'
> >> > feature.  When that feature/bit is set, the device supports the
> >> > RETENTION and OFF states; otherwise, it doesn't.
> >> >
> >> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> >> 
> >> Paul has mentioned this already, but the same applies here: We shouldn't
> >> be using SoC-global feature flag for this.   We already have per-pwrdm
> >> flags that indicate what states a given powerdomain suports (see .pwrsts
> >> field.)
> >> 
> >> Wherever we have blind writes to next powerstates that assume support
> >> for RET/OFF is present, those should probably use a helper function from
> >> the powerdomain code that checks if that state is even supported.
> >
> > How about something like the patch below?
> > Note: its not well tested; just RFC.
> 
> Yes, your proposed patch looks right to me.
> 
> I guess it's up to Paul & Jean to see if they'd rather see this build on
> top of the Jean's functional power state work, or take this as a
> standalone fix.
> 
> Kevin

FYI, I just submitted the patch,
	http://www.spinics.net/lists/linux-omap/msg69066.html

Mark

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

* [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature
@ 2012-04-30 22:08           ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-30 22:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 27, 2012 at 02:07:13PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > On Wed, Apr 11, 2012 at 03:46:20PM -0700, Kevin Hilman wrote:
> >> Hi Mark,
> >
> > Hi Kevin.
> >
> >> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> >> 
> >> > From: "Mark A. Greer" <mgreer@animalcreek.com>
> >> >
> >> > Typical OMAP3 SoCs have four power domain states: ON,
> >> > INACTIVE, RETENTION, and OFF.  The am35x family of SoCs
> >> > has only two states: ON and INACTIVE.  To distinguish which
> >> > set of states the current device has, add the 'OMAP3_HAS_PWROFF'
> >> > feature.  When that feature/bit is set, the device supports the
> >> > RETENTION and OFF states; otherwise, it doesn't.
> >> >
> >> > Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
> >> 
> >> Paul has mentioned this already, but the same applies here: We shouldn't
> >> be using SoC-global feature flag for this.   We already have per-pwrdm
> >> flags that indicate what states a given powerdomain suports (see .pwrsts
> >> field.)
> >> 
> >> Wherever we have blind writes to next powerstates that assume support
> >> for RET/OFF is present, those should probably use a helper function from
> >> the powerdomain code that checks if that state is even supported.
> >
> > How about something like the patch below?
> > Note: its not well tested; just RFC.
> 
> Yes, your proposed patch looks right to me.
> 
> I guess it's up to Paul & Jean to see if they'd rather see this build on
> top of the Jean's functional power state work, or take this as a
> standalone fix.
> 
> Kevin

FYI, I just submitted the patch,
	http://www.spinics.net/lists/linux-omap/msg69066.html

Mark

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

* Re: [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
  2012-04-30 22:00               ` Kevin Hilman
@ 2012-04-30 22:18                 ` Mark A. Greer
  -1 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-30 22:18 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Paul Walmsley, linux-omap, linux-arm-kernel

On Mon, Apr 30, 2012 at 03:00:56PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > On Fri, Apr 27, 2012 at 02:12:12PM -0700, Kevin Hilman wrote:
> >> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> >> 
> >> > On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:
> >
> >> > Just thinking out loud...
> >> >
> >> > We could chose whether pm_idle & cpuidle issue a wfi based on
> >> > whether there is a davinci-emac present.  The issue with that is
> >> > that someday there may be another SoC that has a davinci-emac that
> >> > can wake up the system.  I know cpu_is_xxx() is frowned upon but
> >> > this does seem like a proper usage of it--the deciding factor
> >> > really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
> >> > is enabled).
> >> 
> >> The presence of the davinci_emac is probably overkill, avoiding WFI
> >> should really only be done when the davinci_emac is *active*.
> >> e.g. using an am35x with an EMAC *present*, but not in use because
> >> there's an MMC rootfs for example.
> >> 
> >> If there's a good way to detect an in-use davinci_emac, then
> >> disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
> >> use (e.g. module unloaded etc.) then enable_hlt() can be used to
> >> (re)allow WFI.
> >
> > This can work for pm_idle but what should be done for cpu_idle
> > (as in, omap3_enter_idle[_bm])?  We should have some sort of
> > solution for that so users can safely enable CONFIG_CPU_IDLE
> > and not have the am3517 fall apart.
> 
> disable_hlt() will prevent either the default idle *or* CPUidle from
> being called.
> 
> It will simply call cpu_relax() instead of calling any idle
> function. (c.f. cpu_idle() in arch/arm/kernel/process.c)

Yep, you're right.  Sorry.

Mark

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

* [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver if I/O wake-ups work
@ 2012-04-30 22:18                 ` Mark A. Greer
  0 siblings, 0 replies; 126+ messages in thread
From: Mark A. Greer @ 2012-04-30 22:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 30, 2012 at 03:00:56PM -0700, Kevin Hilman wrote:
> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> 
> > On Fri, Apr 27, 2012 at 02:12:12PM -0700, Kevin Hilman wrote:
> >> "Mark A. Greer" <mgreer@animalcreek.com> writes:
> >> 
> >> > On Tue, Apr 24, 2012 at 01:51:05PM -0700, Mark A. Greer wrote:
> >
> >> > Just thinking out loud...
> >> >
> >> > We could chose whether pm_idle & cpuidle issue a wfi based on
> >> > whether there is a davinci-emac present.  The issue with that is
> >> > that someday there may be another SoC that has a davinci-emac that
> >> > can wake up the system.  I know cpu_is_xxx() is frowned upon but
> >> > this does seem like a proper usage of it--the deciding factor
> >> > really is whether its an am35x or not (and CONFIG_TI_DAVINCI_EMAC
> >> > is enabled).
> >> 
> >> The presence of the davinci_emac is probably overkill, avoiding WFI
> >> should really only be done when the davinci_emac is *active*.
> >> e.g. using an am35x with an EMAC *present*, but not in use because
> >> there's an MMC rootfs for example.
> >> 
> >> If there's a good way to detect an in-use davinci_emac, then
> >> disable_hlt() can be used to avoid WFI.  When the davinci_emac is not in
> >> use (e.g. module unloaded etc.) then enable_hlt() can be used to
> >> (re)allow WFI.
> >
> > This can work for pm_idle but what should be done for cpu_idle
> > (as in, omap3_enter_idle[_bm])?  We should have some sort of
> > solution for that so users can safely enable CONFIG_CPU_IDLE
> > and not have the am3517 fall apart.
> 
> disable_hlt() will prevent either the default idle *or* CPUidle from
> being called.
> 
> It will simply call cpu_relax() instead of calling any idle
> function. (c.f. cpu_idle() in arch/arm/kernel/process.c)

Yep, you're right.  Sorry.

Mark

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

end of thread, other threads:[~2012-04-30 22:19 UTC | newest]

Thread overview: 126+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-11 19:05 arm: omap3: am35x: Powerdomain, EMIF4, etc. fixups Mark A. Greer
2012-04-11 19:05 ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 01/12] arm: omap3: Only access IVA if one exists Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 02/12] arm: omap3: Only sleep during cpu_idle if I/O wake-ups work Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 21:38   ` Paul Walmsley
2012-04-11 21:38     ` Paul Walmsley
2012-04-11 23:42   ` Jon Hunter
2012-04-11 23:42     ` Jon Hunter
2012-04-13  0:13     ` Mark A. Greer
2012-04-13  0:13       ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 03/12] arm: omap3: Only sleep in cpuidle driver " Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 21:37   ` Paul Walmsley
2012-04-11 21:37     ` Paul Walmsley
2012-04-11 22:23     ` Mark A. Greer
2012-04-11 22:23       ` Mark A. Greer
2012-04-11 22:47       ` Paul Walmsley
2012-04-11 22:47         ` Paul Walmsley
2012-04-11 23:08         ` Mark A. Greer
2012-04-11 23:08           ` Mark A. Greer
2012-04-24 20:51     ` Mark A. Greer
2012-04-24 20:51       ` Mark A. Greer
2012-04-24 23:25       ` Mark A. Greer
2012-04-24 23:25         ` Mark A. Greer
2012-04-27 21:12         ` Kevin Hilman
2012-04-27 21:12           ` Kevin Hilman
2012-04-27 21:55           ` Mark A. Greer
2012-04-27 21:55             ` Mark A. Greer
2012-04-30 21:34           ` Mark A. Greer
2012-04-30 21:34             ` Mark A. Greer
2012-04-30 22:00             ` Kevin Hilman
2012-04-30 22:00               ` Kevin Hilman
2012-04-30 22:18               ` Mark A. Greer
2012-04-30 22:18                 ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 04/12] arm: omap3: am35x: Don't mark missing features as present Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 05/12] arm: omap3: am35x: Add PWROFF feature Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 22:46   ` Kevin Hilman
2012-04-11 22:46     ` Kevin Hilman
2012-04-11 23:11     ` Mark A. Greer
2012-04-11 23:11       ` Mark A. Greer
2012-04-24  4:36     ` Mark A. Greer
2012-04-24  4:36       ` Mark A. Greer
2012-04-27 21:07       ` Kevin Hilman
2012-04-27 21:07         ` Kevin Hilman
2012-04-30 22:08         ` Mark A. Greer
2012-04-30 22:08           ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 20:56   ` Jean Pihet
2012-04-11 20:56     ` Jean Pihet
2012-04-11 21:08     ` Paul Walmsley
2012-04-11 21:08       ` Paul Walmsley
2012-04-11 21:14       ` Mark A. Greer
2012-04-11 21:14         ` Mark A. Greer
2012-04-11 21:15         ` Jean Pihet
2012-04-11 21:15           ` Jean Pihet
2012-04-11 21:12     ` Mark A. Greer
2012-04-11 21:12       ` Mark A. Greer
2012-04-11 22:17   ` Paul Walmsley
2012-04-11 22:17     ` Paul Walmsley
2012-04-11 19:05 ` [PATCH 07/12] arm: omap3: am35x: Set proper powerdomain states Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 21:53   ` Paul Walmsley
2012-04-11 21:53     ` Paul Walmsley
2012-04-11 22:40     ` Mark A. Greer
2012-04-11 22:40       ` Mark A. Greer
2012-04-12  0:24       ` Jon Hunter
2012-04-12  0:24         ` Jon Hunter
2012-04-12  2:19         ` Mark A. Greer
2012-04-12  2:19           ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 08/12] arm: omap3: am35x: Fix clockdomain dependencies Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 21:44   ` Paul Walmsley
2012-04-11 21:44     ` Paul Walmsley
2012-04-11 21:55     ` Mark A. Greer
2012-04-11 21:55       ` Mark A. Greer
2012-04-11 22:04       ` Paul Walmsley
2012-04-11 22:04         ` Paul Walmsley
2012-04-11 22:49         ` Mark A. Greer
2012-04-11 22:49           ` Mark A. Greer
2012-04-11 23:49           ` Paul Walmsley
2012-04-11 23:49             ` Paul Walmsley
2012-04-12  2:23             ` Mark A. Greer
2012-04-12  2:23               ` Mark A. Greer
2012-04-12  2:29               ` Paul Walmsley
2012-04-12  2:29                 ` Paul Walmsley
2012-04-12 23:00                 ` Mark A. Greer
2012-04-12 23:00                   ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 09/12] arm: omap3: am35x: Add SDRC EMIF4 feature Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 21:29   ` Paul Walmsley
2012-04-11 21:29     ` Paul Walmsley
2012-04-11 22:50     ` Mark A. Greer
2012-04-11 22:50       ` Mark A. Greer
2012-04-11 22:56   ` Paul Walmsley
2012-04-11 22:56     ` Paul Walmsley
2012-04-11 23:23     ` Mark A. Greer
2012-04-11 23:23       ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 10/12] arm: omap3: am35x: Add minimal EMIF4 support Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 21:31   ` Paul Walmsley
2012-04-11 21:31     ` Paul Walmsley
2012-04-11 23:22     ` Mark A. Greer
2012-04-11 23:22       ` Mark A. Greer
2012-04-11 19:05 ` [PATCH 11/12] arm: omap3: am35x: Add do_wfi routine for EMIF4 submodules Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 22:35   ` Kevin Hilman
2012-04-11 22:35     ` Kevin Hilman
2012-04-11 23:26     ` Mark A. Greer
2012-04-11 23:26       ` Mark A. Greer
2012-04-11 22:36   ` Paul Walmsley
2012-04-11 22:36     ` Paul Walmsley
2012-04-13  0:12     ` Mark A. Greer
2012-04-13  0:12       ` Mark A. Greer
2012-04-11 22:54   ` Paul Walmsley
2012-04-11 22:54     ` Paul Walmsley
2012-04-11 19:05 ` [PATCH 12/12] arm: omap3: am35x: Register davinci_mdio before davinci_emac Mark A. Greer
2012-04-11 19:05   ` Mark A. Greer
2012-04-11 21:24   ` Paul Walmsley
2012-04-11 21:24     ` Paul Walmsley
2012-04-11 22:00     ` Mark A. Greer
2012-04-11 22:00       ` Mark A. Greer

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.