All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 00/10] ARM: OMAP4: Add PMU Support
@ 2012-06-07 21:22 ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

This series adds PMU support for OMAP4 devices. This is based upon Will Deacons
series [1]. This series fixes the management of the EMU power domain so that
PMU can be enabled at runtime and low-power states are not prevented when PMU
is not in-use. The fix is based upon inputs from Benoit, Paul and Kevin [2].

This series also converts OMAP2/3 devices to use HWMOD to create the PMU device
and add a new file to mach-omap2 directory called pmu.c where the PMU devices
are created.

This series is based upon the latest linux-omap master branch from Tony
(3.5-rc1).

Testing:
- Verified that PMU is working on OMAP3430 Beagle Board, OMAP4430 Blaze and
  4460 Panda.
- Tested on the above boards with CPU-idle enabled to ensure that PMU is working
  with power management. For OMAP4 boards I have disabled CPU1 so that CPU0 and
  hence the MPU power domain is reaching the low-power retention state.
- I have booted the kernel on an OMAP2430 SDP but not verified PMU is working.
- Unable to verify 4470 Blaze because kernel is not currently booting.

[1] git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git perf/omap4
[2] http://marc.info/?l=oprofile-list&m=133657425417229&w=3

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Jon Hunter (8):
  ARM: PMU: Add runtime PM Support
  ARM: OMAP2+: PMU: Convert OMAP2/3 devices to use HWMOD
  ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
  ARM: OMAP2+: PMU: Add runtime PM support
  ARM: OMAP4: CLKDM: Update supported transition modes
  ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  ARM: OMAP4: Enable PMU for OMAP4460/70
  ARM: OMAP2+: PMU: Add QoS constraint

Ming Lei (2):
  ARM: OMAP4430: Create PMU device via HWMOD
  ARM: OMAP4: Route PMU IRQs to CTI IRQs

 arch/arm/include/asm/pmu.h                         |   20 +-
 arch/arm/kernel/perf_event.c                       |   41 +++-
 arch/arm/mach-omap2/Makefile                       |    1 +
 arch/arm/mach-omap2/clockdomain44xx.c              |    7 +-
 arch/arm/mach-omap2/clockdomains44xx_data.c        |    2 +-
 arch/arm/mach-omap2/cminst44xx.c                   |   14 --
 arch/arm/mach-omap2/devices.c                      |   33 ---
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |    6 +
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |    6 +
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c         |   11 +-
 arch/arm/mach-omap2/pmu.c                          |  251 ++++++++++++++++++++
 arch/arm/plat-omap/include/plat/irqs.h             |    1 +
 arch/arm/plat-omap/include/plat/omap44xx.h         |    3 +
 13 files changed, 328 insertions(+), 68 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pmu.c

-- 
1.7.9.5


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

* [PATCH V2 00/10] ARM: OMAP4: Add PMU Support
@ 2012-06-07 21:22 ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds PMU support for OMAP4 devices. This is based upon Will Deacons
series [1]. This series fixes the management of the EMU power domain so that
PMU can be enabled at runtime and low-power states are not prevented when PMU
is not in-use. The fix is based upon inputs from Benoit, Paul and Kevin [2].

This series also converts OMAP2/3 devices to use HWMOD to create the PMU device
and add a new file to mach-omap2 directory called pmu.c where the PMU devices
are created.

This series is based upon the latest linux-omap master branch from Tony
(3.5-rc1).

Testing:
- Verified that PMU is working on OMAP3430 Beagle Board, OMAP4430 Blaze and
  4460 Panda.
- Tested on the above boards with CPU-idle enabled to ensure that PMU is working
  with power management. For OMAP4 boards I have disabled CPU1 so that CPU0 and
  hence the MPU power domain is reaching the low-power retention state.
- I have booted the kernel on an OMAP2430 SDP but not verified PMU is working.
- Unable to verify 4470 Blaze because kernel is not currently booting.

[1] git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git perf/omap4
[2] http://marc.info/?l=oprofile-list&m=133657425417229&w=3

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Jon Hunter (8):
  ARM: PMU: Add runtime PM Support
  ARM: OMAP2+: PMU: Convert OMAP2/3 devices to use HWMOD
  ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
  ARM: OMAP2+: PMU: Add runtime PM support
  ARM: OMAP4: CLKDM: Update supported transition modes
  ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  ARM: OMAP4: Enable PMU for OMAP4460/70
  ARM: OMAP2+: PMU: Add QoS constraint

Ming Lei (2):
  ARM: OMAP4430: Create PMU device via HWMOD
  ARM: OMAP4: Route PMU IRQs to CTI IRQs

 arch/arm/include/asm/pmu.h                         |   20 +-
 arch/arm/kernel/perf_event.c                       |   41 +++-
 arch/arm/mach-omap2/Makefile                       |    1 +
 arch/arm/mach-omap2/clockdomain44xx.c              |    7 +-
 arch/arm/mach-omap2/clockdomains44xx_data.c        |    2 +-
 arch/arm/mach-omap2/cminst44xx.c                   |   14 --
 arch/arm/mach-omap2/devices.c                      |   33 ---
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |    6 +
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |    6 +
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c         |   11 +-
 arch/arm/mach-omap2/pmu.c                          |  251 ++++++++++++++++++++
 arch/arm/plat-omap/include/plat/irqs.h             |    1 +
 arch/arm/plat-omap/include/plat/omap44xx.h         |    3 +
 13 files changed, 328 insertions(+), 68 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pmu.c

-- 
1.7.9.5

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

Add runtime PM support to the ARM PMU driver so that devices such as OMAP
supporting dynamic PM can use the platform->runtime_* hooks to initialise
hardware at runtime. Without having these runtime PM hooks in place any
configuration of the PMU hardware would be lost when low power states are
entered and hence would prevent PMU from working.

This change also replaces the PMU platform functions enable_irq and disable_irq
added by Ming Lei with runtime_resume and runtime_suspend funtions. Ming had
added the enable_irq and disable_irq functions as a method to configure the
cross trigger interface on OMAP4 for routing the PMU interrupts. By adding
runtime PM support, we can move the code called by enable_irq and disable_irq
into the runtime PM callbacks runtime_resume and runtime_suspend.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/include/asm/pmu.h   |   20 ++++++++++++--------
 arch/arm/kernel/perf_event.c |   41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 90114fa..77b023b 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -31,18 +31,22 @@ enum arm_pmu_type {
  *	interrupt and passed the address of the low level handler,
  *	and can be used to implement any platform specific handling
  *	before or after calling it.
- * @enable_irq: an optional handler which will be called after
- *	request_irq and be used to handle some platform specific
- *	irq enablement
- * @disable_irq: an optional handler which will be called before
- *	free_irq and be used to handle some platform specific
- *	irq disablement
+ * @runtime_resume: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_get().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called once.
+ * @runtime_suspend: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_put().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called following the
+ *	final call to pm_runtime_put() that actually disables the
+ *	hardware.
  */
 struct arm_pmu_platdata {
 	irqreturn_t (*handle_irq)(int irq, void *dev,
 				  irq_handler_t pmu_handler);
-	void (*enable_irq)(int irq);
-	void (*disable_irq)(int irq);
+	int (*runtime_resume)(struct device *dev);
+	int (*runtime_suspend)(struct device *dev);
 };
 
 #ifdef CONFIG_CPU_HAS_PMU
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 186c8cb..00adb98 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 {
 	int i, irq, irqs;
 	struct platform_device *pmu_device = armpmu->plat_device;
-	struct arm_pmu_platdata *plat =
-		dev_get_platdata(&pmu_device->dev);
 
 	irqs = min(pmu_device->num_resources, num_possible_cpus());
 
@@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
 			continue;
 		irq = platform_get_irq(pmu_device, i);
-		if (irq >= 0) {
-			if (plat && plat->disable_irq)
-				plat->disable_irq(irq);
+		if (irq >= 0)
 			free_irq(irq, armpmu);
-		}
 	}
 
 	release_pmu(armpmu->type);
+	pm_runtime_put_sync(&armpmu->plat_device->dev);
 }
 
 static int
@@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 		return err;
 	}
 
+	pm_runtime_get_sync(&armpmu->plat_device->dev);
+
 	plat = dev_get_platdata(&pmu_device->dev);
 	if (plat && plat->handle_irq)
 		handle_irq = armpmu_platform_irq;
@@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 				irq);
 			armpmu_release_hardware(armpmu);
 			return err;
-		} else if (plat && plat->enable_irq)
-			plat->enable_irq(irq);
+		}
 
 		cpumask_set_cpu(i, &armpmu->active_irqs);
 	}
@@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
 	armpmu->stop();
 }
 
+#ifdef CONFIG_PM_RUNTIME
+static int armpmu_runtime_resume(struct device *dev)
+{
+	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+	if (plat->runtime_resume)
+		return plat->runtime_resume(dev);
+
+	return 0;
+}
+
+static int armpmu_runtime_suspend(struct device *dev)
+{
+	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+	if (plat->runtime_suspend)
+		return plat->runtime_suspend(dev);
+
+	return 0;
+}
+#endif
+
 static void __init armpmu_init(struct arm_pmu *armpmu)
 {
 	atomic_set(&armpmu->active_events, 0);
@@ -650,9 +670,14 @@ static int __devinit armpmu_device_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct dev_pm_ops armpmu_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
+};
+
 static struct platform_driver armpmu_driver = {
 	.driver		= {
 		.name	= "arm-pmu",
+		.pm	= &armpmu_dev_pm_ops,
 		.of_match_table = armpmu_of_device_ids,
 	},
 	.probe		= armpmu_device_probe,
-- 
1.7.9.5


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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

Add runtime PM support to the ARM PMU driver so that devices such as OMAP
supporting dynamic PM can use the platform->runtime_* hooks to initialise
hardware at runtime. Without having these runtime PM hooks in place any
configuration of the PMU hardware would be lost when low power states are
entered and hence would prevent PMU from working.

This change also replaces the PMU platform functions enable_irq and disable_irq
added by Ming Lei with runtime_resume and runtime_suspend funtions. Ming had
added the enable_irq and disable_irq functions as a method to configure the
cross trigger interface on OMAP4 for routing the PMU interrupts. By adding
runtime PM support, we can move the code called by enable_irq and disable_irq
into the runtime PM callbacks runtime_resume and runtime_suspend.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/include/asm/pmu.h   |   20 ++++++++++++--------
 arch/arm/kernel/perf_event.c |   41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 90114fa..77b023b 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -31,18 +31,22 @@ enum arm_pmu_type {
  *	interrupt and passed the address of the low level handler,
  *	and can be used to implement any platform specific handling
  *	before or after calling it.
- * @enable_irq: an optional handler which will be called after
- *	request_irq and be used to handle some platform specific
- *	irq enablement
- * @disable_irq: an optional handler which will be called before
- *	free_irq and be used to handle some platform specific
- *	irq disablement
+ * @runtime_resume: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_get().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called once.
+ * @runtime_suspend: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_put().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called following the
+ *	final call to pm_runtime_put() that actually disables the
+ *	hardware.
  */
 struct arm_pmu_platdata {
 	irqreturn_t (*handle_irq)(int irq, void *dev,
 				  irq_handler_t pmu_handler);
-	void (*enable_irq)(int irq);
-	void (*disable_irq)(int irq);
+	int (*runtime_resume)(struct device *dev);
+	int (*runtime_suspend)(struct device *dev);
 };
 
 #ifdef CONFIG_CPU_HAS_PMU
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 186c8cb..00adb98 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 {
 	int i, irq, irqs;
 	struct platform_device *pmu_device = armpmu->plat_device;
-	struct arm_pmu_platdata *plat =
-		dev_get_platdata(&pmu_device->dev);
 
 	irqs = min(pmu_device->num_resources, num_possible_cpus());
 
@@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
 			continue;
 		irq = platform_get_irq(pmu_device, i);
-		if (irq >= 0) {
-			if (plat && plat->disable_irq)
-				plat->disable_irq(irq);
+		if (irq >= 0)
 			free_irq(irq, armpmu);
-		}
 	}
 
 	release_pmu(armpmu->type);
+	pm_runtime_put_sync(&armpmu->plat_device->dev);
 }
 
 static int
@@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 		return err;
 	}
 
+	pm_runtime_get_sync(&armpmu->plat_device->dev);
+
 	plat = dev_get_platdata(&pmu_device->dev);
 	if (plat && plat->handle_irq)
 		handle_irq = armpmu_platform_irq;
@@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 				irq);
 			armpmu_release_hardware(armpmu);
 			return err;
-		} else if (plat && plat->enable_irq)
-			plat->enable_irq(irq);
+		}
 
 		cpumask_set_cpu(i, &armpmu->active_irqs);
 	}
@@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
 	armpmu->stop();
 }
 
+#ifdef CONFIG_PM_RUNTIME
+static int armpmu_runtime_resume(struct device *dev)
+{
+	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+	if (plat->runtime_resume)
+		return plat->runtime_resume(dev);
+
+	return 0;
+}
+
+static int armpmu_runtime_suspend(struct device *dev)
+{
+	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+	if (plat->runtime_suspend)
+		return plat->runtime_suspend(dev);
+
+	return 0;
+}
+#endif
+
 static void __init armpmu_init(struct arm_pmu *armpmu)
 {
 	atomic_set(&armpmu->active_events, 0);
@@ -650,9 +670,14 @@ static int __devinit armpmu_device_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct dev_pm_ops armpmu_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
+};
+
 static struct platform_driver armpmu_driver = {
 	.driver		= {
 		.name	= "arm-pmu",
+		.pm	= &armpmu_dev_pm_ops,
 		.of_match_table = armpmu_of_device_ids,
 	},
 	.probe		= armpmu_device_probe,
-- 
1.7.9.5

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

* [PATCH V2 02/10] ARM: OMAP2+: PMU: Convert OMAP2/3 devices to use HWMOD
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

Convert OMAP2/3 devices to use HWMOD for creating a PMU device. To support PMU
on OMAP2/3 devices we only need to use MPU sub-system and so we can simply use
the MPU HWMOD to create the PMU device. The MPU HWMOD for OMAP2/3 devices is
currently missing the PMU interrupt and so add the PMU interrupt to the MPU
HWMOD for these devices.

This change also moves the PMU code out of the mach-omap2/devices.c files into
its own pmu.c file as suggested by Kevin Hilman to de-clutter devices.c.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/Makefile                       |    1 +
 arch/arm/mach-omap2/devices.c                      |   33 -----------
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |    6 ++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |    6 ++
 arch/arm/mach-omap2/pmu.c                          |   59 ++++++++++++++++++++
 arch/arm/plat-omap/include/plat/irqs.h             |    1 +
 6 files changed, 73 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pmu.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 664224f..23a2569 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -169,6 +169,7 @@ obj-$(CONFIG_ARCH_OMAP4)		+= omap_hwmod_44xx_data.o
 
 # EMU peripherals
 obj-$(CONFIG_OMAP3_EMU)			+= emu.o
+obj-$(CONFIG_CPU_HAS_PMU)		+= pmu.o
 
 # L3 interconnect
 obj-$(CONFIG_ARCH_OMAP3)		+= omap_l3_smx.o
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 25130ff..ba0751a 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -23,7 +23,6 @@
 #include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 
 #include "iomap.h"
 #include <plat/board.h>
@@ -434,37 +433,6 @@ static void omap_init_mcspi(void)
 static inline void omap_init_mcspi(void) {}
 #endif
 
-static struct resource omap2_pmu_resource = {
-	.start	= 3,
-	.end	= 3,
-	.flags	= IORESOURCE_IRQ,
-};
-
-static struct resource omap3_pmu_resource = {
-	.start	= INT_34XX_BENCH_MPU_EMUL,
-	.end	= INT_34XX_BENCH_MPU_EMUL,
-	.flags	= IORESOURCE_IRQ,
-};
-
-static struct platform_device omap_pmu_device = {
-	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
-	.num_resources	= 1,
-};
-
-static void omap_init_pmu(void)
-{
-	if (cpu_is_omap24xx())
-		omap_pmu_device.resource = &omap2_pmu_resource;
-	else if (cpu_is_omap34xx())
-		omap_pmu_device.resource = &omap3_pmu_resource;
-	else
-		return;
-
-	platform_device_register(&omap_pmu_device);
-}
-
-
 #if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE)
 
 #ifdef CONFIG_ARCH_OMAP2
@@ -680,7 +648,6 @@ static int __init omap2_init_devices(void)
 		omap_init_mcpdm();
 		omap_init_mcspi();
 	}
-	omap_init_pmu();
 	omap_hdq_init();
 	omap_init_sti();
 	omap_init_sham();
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 83eafd9..4ef4b59 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -201,8 +201,14 @@ struct omap_hwmod omap2xxx_l4_wkup_hwmod = {
 };
 
 /* MPU */
+static struct omap_hwmod_irq_info omap2xxx_mpu_irqs[] = {
+	{ .name = "pmu", .irq = INT_24XX_BENCH_MPU_EMUL },
+	{ .irq = -1 }
+};
+
 struct omap_hwmod omap2xxx_mpu_hwmod = {
 	.name		= "mpu",
+	.mpu_irqs	= omap2xxx_mpu_irqs,
 	.class		= &mpu_hwmod_class,
 	.main_clk	= "mpu_ck",
 };
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index b26d3c9..5de8fc0 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -92,8 +92,14 @@ static struct omap_hwmod omap3xxx_l4_sec_hwmod = {
 };
 
 /* MPU */
+static struct omap_hwmod_irq_info omap3xxx_mpu_irqs[] = {
+	{ .name = "pmu", .irq = INT_34XX_BENCH_MPU_EMUL },
+	{ .irq = -1 }
+};
+
 static struct omap_hwmod omap3xxx_mpu_hwmod = {
 	.name		= "mpu",
+	.mpu_irqs	= omap3xxx_mpu_irqs,
 	.class		= &mpu_hwmod_class,
 	.main_clk	= "arm_fck",
 };
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
new file mode 100644
index 0000000..329e00c
--- /dev/null
+++ b/arch/arm/mach-omap2/pmu.c
@@ -0,0 +1,59 @@
+/*
+ * linux/arch/arm/mach-omap2/pmu.c
+ *
+ * OMAP2 ARM Performance Monitoring Unit (PMU) Support
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * Contacts:
+ * Jon Hunter <jon-hunter@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <asm/pmu.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+static struct platform_device *omap_pmu_dev;
+
+/*
+ * omap2_init_pmu - creates and registers PMU platform device
+ *
+ * Uses OMAP HWMOD framework to create and register an ARM PMU device.
+ * Currently supports OMAP2 and OMAP3 devices that only require the MPU
+ * sub-system to be active for PMU events to work.
+ */
+static int __init omap2_init_pmu(void)
+{
+	int id = -1;
+	struct omap_hwmod *oh;
+	char *oh_name = "mpu";
+	char *dev_name = "arm-pmu";
+
+	oh = omap_hwmod_lookup(oh_name);
+	if (!oh) {
+		pr_err("Could not look up %s hwmod\n", oh_name);
+		return -ENODEV;
+	}
+
+	omap_pmu_dev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
+
+	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
+				dev_name);
+
+	return 0;
+}
+
+static int __init omap_init_pmu(void)
+{
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		return omap2_init_pmu();
+
+	return 0;
+}
+
+subsys_initcall(omap_init_pmu);
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 37bbbbb..18883eb 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -243,6 +243,7 @@
 #define INT_7XX_DMA_CH15	(62 + IH2_BASE)
 #define INT_7XX_NAND		(63 + IH2_BASE)
 
+#define INT_24XX_BENCH_MPU_EMUL	3
 #define INT_24XX_SYS_NIRQ	7
 #define INT_24XX_SDMA_IRQ0	12
 #define INT_24XX_SDMA_IRQ1	13
-- 
1.7.9.5


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

* [PATCH V2 02/10] ARM: OMAP2+: PMU: Convert OMAP2/3 devices to use HWMOD
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

Convert OMAP2/3 devices to use HWMOD for creating a PMU device. To support PMU
on OMAP2/3 devices we only need to use MPU sub-system and so we can simply use
the MPU HWMOD to create the PMU device. The MPU HWMOD for OMAP2/3 devices is
currently missing the PMU interrupt and so add the PMU interrupt to the MPU
HWMOD for these devices.

This change also moves the PMU code out of the mach-omap2/devices.c files into
its own pmu.c file as suggested by Kevin Hilman to de-clutter devices.c.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/Makefile                       |    1 +
 arch/arm/mach-omap2/devices.c                      |   33 -----------
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |    6 ++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |    6 ++
 arch/arm/mach-omap2/pmu.c                          |   59 ++++++++++++++++++++
 arch/arm/plat-omap/include/plat/irqs.h             |    1 +
 6 files changed, 73 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pmu.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 664224f..23a2569 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -169,6 +169,7 @@ obj-$(CONFIG_ARCH_OMAP4)		+= omap_hwmod_44xx_data.o
 
 # EMU peripherals
 obj-$(CONFIG_OMAP3_EMU)			+= emu.o
+obj-$(CONFIG_CPU_HAS_PMU)		+= pmu.o
 
 # L3 interconnect
 obj-$(CONFIG_ARCH_OMAP3)		+= omap_l3_smx.o
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 25130ff..ba0751a 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -23,7 +23,6 @@
 #include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 
 #include "iomap.h"
 #include <plat/board.h>
@@ -434,37 +433,6 @@ static void omap_init_mcspi(void)
 static inline void omap_init_mcspi(void) {}
 #endif
 
-static struct resource omap2_pmu_resource = {
-	.start	= 3,
-	.end	= 3,
-	.flags	= IORESOURCE_IRQ,
-};
-
-static struct resource omap3_pmu_resource = {
-	.start	= INT_34XX_BENCH_MPU_EMUL,
-	.end	= INT_34XX_BENCH_MPU_EMUL,
-	.flags	= IORESOURCE_IRQ,
-};
-
-static struct platform_device omap_pmu_device = {
-	.name		= "arm-pmu",
-	.id		= ARM_PMU_DEVICE_CPU,
-	.num_resources	= 1,
-};
-
-static void omap_init_pmu(void)
-{
-	if (cpu_is_omap24xx())
-		omap_pmu_device.resource = &omap2_pmu_resource;
-	else if (cpu_is_omap34xx())
-		omap_pmu_device.resource = &omap3_pmu_resource;
-	else
-		return;
-
-	platform_device_register(&omap_pmu_device);
-}
-
-
 #if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE)
 
 #ifdef CONFIG_ARCH_OMAP2
@@ -680,7 +648,6 @@ static int __init omap2_init_devices(void)
 		omap_init_mcpdm();
 		omap_init_mcspi();
 	}
-	omap_init_pmu();
 	omap_hdq_init();
 	omap_init_sti();
 	omap_init_sham();
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 83eafd9..4ef4b59 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -201,8 +201,14 @@ struct omap_hwmod omap2xxx_l4_wkup_hwmod = {
 };
 
 /* MPU */
+static struct omap_hwmod_irq_info omap2xxx_mpu_irqs[] = {
+	{ .name = "pmu", .irq = INT_24XX_BENCH_MPU_EMUL },
+	{ .irq = -1 }
+};
+
 struct omap_hwmod omap2xxx_mpu_hwmod = {
 	.name		= "mpu",
+	.mpu_irqs	= omap2xxx_mpu_irqs,
 	.class		= &mpu_hwmod_class,
 	.main_clk	= "mpu_ck",
 };
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index b26d3c9..5de8fc0 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -92,8 +92,14 @@ static struct omap_hwmod omap3xxx_l4_sec_hwmod = {
 };
 
 /* MPU */
+static struct omap_hwmod_irq_info omap3xxx_mpu_irqs[] = {
+	{ .name = "pmu", .irq = INT_34XX_BENCH_MPU_EMUL },
+	{ .irq = -1 }
+};
+
 static struct omap_hwmod omap3xxx_mpu_hwmod = {
 	.name		= "mpu",
+	.mpu_irqs	= omap3xxx_mpu_irqs,
 	.class		= &mpu_hwmod_class,
 	.main_clk	= "arm_fck",
 };
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
new file mode 100644
index 0000000..329e00c
--- /dev/null
+++ b/arch/arm/mach-omap2/pmu.c
@@ -0,0 +1,59 @@
+/*
+ * linux/arch/arm/mach-omap2/pmu.c
+ *
+ * OMAP2 ARM Performance Monitoring Unit (PMU) Support
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * Contacts:
+ * Jon Hunter <jon-hunter@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <asm/pmu.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+static struct platform_device *omap_pmu_dev;
+
+/*
+ * omap2_init_pmu - creates and registers PMU platform device
+ *
+ * Uses OMAP HWMOD framework to create and register an ARM PMU device.
+ * Currently supports OMAP2 and OMAP3 devices that only require the MPU
+ * sub-system to be active for PMU events to work.
+ */
+static int __init omap2_init_pmu(void)
+{
+	int id = -1;
+	struct omap_hwmod *oh;
+	char *oh_name = "mpu";
+	char *dev_name = "arm-pmu";
+
+	oh = omap_hwmod_lookup(oh_name);
+	if (!oh) {
+		pr_err("Could not look up %s hwmod\n", oh_name);
+		return -ENODEV;
+	}
+
+	omap_pmu_dev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
+
+	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
+				dev_name);
+
+	return 0;
+}
+
+static int __init omap_init_pmu(void)
+{
+	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		return omap2_init_pmu();
+
+	return 0;
+}
+
+subsys_initcall(omap_init_pmu);
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 37bbbbb..18883eb 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -243,6 +243,7 @@
 #define INT_7XX_DMA_CH15	(62 + IH2_BASE)
 #define INT_7XX_NAND		(63 + IH2_BASE)
 
+#define INT_24XX_BENCH_MPU_EMUL	3
 #define INT_24XX_SYS_NIRQ	7
 #define INT_24XX_SDMA_IRQ0	12
 #define INT_24XX_SDMA_IRQ1	13
-- 
1.7.9.5

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

* [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

In order to use the CTI interrupts inconjunction with the DEBUGSS we need to
re-map the CTI IRQs to the DEBUGSS HWMOD. The purpose for doing this is so we
can create a PMU device based upon the DEBUGSS HWMOD and use the CTI interrupts
for routing ARM PMU events for OMAP4430 devices.

This is based upon Benoit Cousson's patch [1].

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/073319.html

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 950454a..faf5a6d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -482,10 +482,17 @@ static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
 };
 
 /* debugss */
+static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = {
+	{ .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
+	{ .irq = -1 }
+};
+
 static struct omap_hwmod omap44xx_debugss_hwmod = {
 	.name		= "debugss",
 	.class		= &omap44xx_debugss_hwmod_class,
 	.clkdm_name	= "emu_sys_clkdm",
+	.mpu_irqs	= omap44xx_debugss_irqs,
 	.main_clk	= "trace_clk_div_ck",
 	.prcm = {
 		.omap4 = {
@@ -2447,8 +2454,6 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
 /* mpu */
 static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
 	{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
 	{ .irq = -1 }
 };
 
-- 
1.7.9.5


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

* [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

In order to use the CTI interrupts inconjunction with the DEBUGSS we need to
re-map the CTI IRQs to the DEBUGSS HWMOD. The purpose for doing this is so we
can create a PMU device based upon the DEBUGSS HWMOD and use the CTI interrupts
for routing ARM PMU events for OMAP4430 devices.

This is based upon Benoit Cousson's patch [1].

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/073319.html

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 950454a..faf5a6d 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -482,10 +482,17 @@ static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
 };
 
 /* debugss */
+static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = {
+	{ .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
+	{ .irq = -1 }
+};
+
 static struct omap_hwmod omap44xx_debugss_hwmod = {
 	.name		= "debugss",
 	.class		= &omap44xx_debugss_hwmod_class,
 	.clkdm_name	= "emu_sys_clkdm",
+	.mpu_irqs	= omap44xx_debugss_irqs,
 	.main_clk	= "trace_clk_div_ck",
 	.prcm = {
 		.omap4 = {
@@ -2447,8 +2454,6 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
 /* mpu */
 static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
 	{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
 	{ .irq = -1 }
 };
 
-- 
1.7.9.5

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

* [PATCH V2 04/10] ARM: OMAP4430: Create PMU device via HWMOD
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman, Jon Hunter

From: Ming Lei <ming.lei@canonical.com>

For OMAP4430 PMU events are routed to the CPU via the cross trigger interface
(CTI) because there are no dedicated interrupts. In order to route the PMU
events via the CTI IRQs, the following modules must be enabled:

        l3_instr, l3_main_3, debugss

Therefore, build the arm-pmu device via these three HWMODs.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/pmu.c |   46 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 329e00c..b3b9306 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -48,10 +48,56 @@ static int __init omap2_init_pmu(void)
 	return 0;
 }
 
+/*
+ * omap4430_init_pmu - creates and registers PMU platform device
+ *
+ * Uses OMAP HWMOD framework to create and register an ARM PMU device.
+ * Only supports OMAP4430 devices that require PMU interrupts to be
+ * routed to the interrupt controller via the coresight cross trigger
+ * interface (CTI). To route the interrpts via the coresight CTI module,
+ * the OMAP modules L3_MAIN_3, L3_INSTR and DEBUGSS need to be active.
+ */
+static int __init omap4430_init_pmu(void)
+{
+	int id = -1;
+	struct omap_hwmod *oh[3];
+	char *oh_name;
+	char *dev_name = "arm-pmu";
+
+	oh_name = "l3_main_3";
+	oh[0] = omap_hwmod_lookup(oh_name);
+	if (!oh[0]) {
+		pr_err("Could not look up %s hwmod\n", oh_name);
+		return -ENODEV;
+	}
+	oh_name = "l3_instr";
+	oh[1] = omap_hwmod_lookup(oh_name);
+	if (!oh[1]) {
+		pr_err("Could not look up %s hwmod\n", oh_name);
+		return -ENODEV;
+	}
+	oh_name = "debugss";
+	oh[2] = omap_hwmod_lookup(oh_name);
+	if (!oh[2]) {
+		pr_err("Could not look up %s hwmod\n", oh_name);
+		return -ENODEV;
+	}
+
+	omap_pmu_dev = omap_device_build_ss(dev_name, id, oh, 3, NULL,
+				0, NULL, 0, 0);
+	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
+				dev_name);
+
+	return 0;
+}
+
 static int __init omap_init_pmu(void)
 {
+
 	if (cpu_is_omap24xx() || cpu_is_omap34xx())
 		return omap2_init_pmu();
+	if (cpu_is_omap443x())
+		return omap4430_init_pmu();
 
 	return 0;
 }
-- 
1.7.9.5


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

* [PATCH V2 04/10] ARM: OMAP4430: Create PMU device via HWMOD
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ming Lei <ming.lei@canonical.com>

For OMAP4430 PMU events are routed to the CPU via the cross trigger interface
(CTI) because there are no dedicated interrupts. In order to route the PMU
events via the CTI IRQs, the following modules must be enabled:

        l3_instr, l3_main_3, debugss

Therefore, build the arm-pmu device via these three HWMODs.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/pmu.c |   46 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 329e00c..b3b9306 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -48,10 +48,56 @@ static int __init omap2_init_pmu(void)
 	return 0;
 }
 
+/*
+ * omap4430_init_pmu - creates and registers PMU platform device
+ *
+ * Uses OMAP HWMOD framework to create and register an ARM PMU device.
+ * Only supports OMAP4430 devices that require PMU interrupts to be
+ * routed to the interrupt controller via the coresight cross trigger
+ * interface (CTI). To route the interrpts via the coresight CTI module,
+ * the OMAP modules L3_MAIN_3, L3_INSTR and DEBUGSS need to be active.
+ */
+static int __init omap4430_init_pmu(void)
+{
+	int id = -1;
+	struct omap_hwmod *oh[3];
+	char *oh_name;
+	char *dev_name = "arm-pmu";
+
+	oh_name = "l3_main_3";
+	oh[0] = omap_hwmod_lookup(oh_name);
+	if (!oh[0]) {
+		pr_err("Could not look up %s hwmod\n", oh_name);
+		return -ENODEV;
+	}
+	oh_name = "l3_instr";
+	oh[1] = omap_hwmod_lookup(oh_name);
+	if (!oh[1]) {
+		pr_err("Could not look up %s hwmod\n", oh_name);
+		return -ENODEV;
+	}
+	oh_name = "debugss";
+	oh[2] = omap_hwmod_lookup(oh_name);
+	if (!oh[2]) {
+		pr_err("Could not look up %s hwmod\n", oh_name);
+		return -ENODEV;
+	}
+
+	omap_pmu_dev = omap_device_build_ss(dev_name, id, oh, 3, NULL,
+				0, NULL, 0, 0);
+	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
+				dev_name);
+
+	return 0;
+}
+
 static int __init omap_init_pmu(void)
 {
+
 	if (cpu_is_omap24xx() || cpu_is_omap34xx())
 		return omap2_init_pmu();
+	if (cpu_is_omap443x())
+		return omap4430_init_pmu();
 
 	return 0;
 }
-- 
1.7.9.5

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

* [PATCH V2 05/10] ARM: OMAP2+: PMU: Add runtime PM support
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

The original implementation of this patch was done by Ming Lei for PMU on OMAP4
[1]. Since then the PM runtime calls have been moved into the ARM PMU code and
this greatly simplifies the changes.

The another differnce since the original version, is that it is no longer
necessary to call pm_runtime_get/put during the PMU initialisation was we are no
longer accessing the hardware at this stage.

By adding runtime PM support, we can ensure that the appropriate power and clock
domains are kept on while PMU is being used.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074153.html

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/pmu.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index b3b9306..1b36eda 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -13,6 +13,8 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
+#include <linux/pm_runtime.h>
+
 #include <asm/pmu.h>
 
 #include <plat/omap_hwmod.h>
@@ -45,6 +47,9 @@ static int __init omap2_init_pmu(void)
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 				dev_name);
 
+	if (omap_pmu_dev)
+		pm_runtime_enable(&omap_pmu_dev->dev);
+
 	return 0;
 }
 
@@ -88,6 +93,9 @@ static int __init omap4430_init_pmu(void)
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 				dev_name);
 
+	if (omap_pmu_dev)
+		pm_runtime_enable(&omap_pmu_dev->dev);
+
 	return 0;
 }
 
-- 
1.7.9.5


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

* [PATCH V2 05/10] ARM: OMAP2+: PMU: Add runtime PM support
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

The original implementation of this patch was done by Ming Lei for PMU on OMAP4
[1]. Since then the PM runtime calls have been moved into the ARM PMU code and
this greatly simplifies the changes.

The another differnce since the original version, is that it is no longer
necessary to call pm_runtime_get/put during the PMU initialisation was we are no
longer accessing the hardware at this stage.

By adding runtime PM support, we can ensure that the appropriate power and clock
domains are kept on while PMU is being used.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074153.html

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/pmu.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index b3b9306..1b36eda 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -13,6 +13,8 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
+#include <linux/pm_runtime.h>
+
 #include <asm/pmu.h>
 
 #include <plat/omap_hwmod.h>
@@ -45,6 +47,9 @@ static int __init omap2_init_pmu(void)
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 				dev_name);
 
+	if (omap_pmu_dev)
+		pm_runtime_enable(&omap_pmu_dev->dev);
+
 	return 0;
 }
 
@@ -88,6 +93,9 @@ static int __init omap4430_init_pmu(void)
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 				dev_name);
 
+	if (omap_pmu_dev)
+		pm_runtime_enable(&omap_pmu_dev->dev);
+
 	return 0;
 }
 
-- 
1.7.9.5

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

* [PATCH V2 06/10] ARM: OMAP4: Route PMU IRQs to CTI IRQs
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Ming Lei, Woodruff Richard, Will Deacon, Benoit Cousson,
	Paul Walmsley, Kevin Hilman, Jon Hunter

From: Ming Lei <ming.lei@canonical.com>

For OMAP4430 there are no dedicate PMU interrupts, however, PMU events can be
routed to via the CTI IRQs. This allows tools such as PERF and OPROFILE to work
on OMAP4430.

The idea is from Woodruff Richard in the disscussion about "Oprofile on
Pandaboard / Omap4" on pandaboard@googlegroups.com.

Ming's original patch was called "arm: omap4: support pmu" [1] and has been
renamed and modified by Jon Hunter. There main differences from the original
patch are ...

1. Instead of only configuring the CTI interrupt once during boot, the
   interrupts are configured everytime the the PMU is used. The reason for this
   is because during power transitions the CTI logic state will be lost and so
   we will need to configure the interrupts everytime they are used. This is
   accomplished by using the PM runtime callbacks which will be called whenever
   the PMU is used.
2. Assign the PMU events to different cross triggering channels. This prevents
   a single PMU event generating interrupts to both CPUs and hence can cause
   spurious interrupts to occur. Reported by Ming [2].

[1] http://marc.info/?l=linux-arm-kernel&m=132227620816504&w=2
[2] http://permalink.gmane.org/gmane.linux.linaro.devel/10532

Acked-by: Jean Pihet <j-pihet@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Woodruff Richard <r-woodruff2@ti.com>
Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/pmu.c                  |   92 +++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/omap44xx.h |    3 +
 2 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 1b36eda..228e247 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -16,11 +16,14 @@
 #include <linux/pm_runtime.h>
 
 #include <asm/pmu.h>
+#include <asm/cti.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+static struct arm_pmu_platdata omap_pmu_data;
 static struct platform_device *omap_pmu_dev;
+static struct cti omap4_cti[2];
 
 /*
  * omap2_init_pmu - creates and registers PMU platform device
@@ -54,6 +57,84 @@ static int __init omap2_init_pmu(void)
 }
 
 /*
+ * omap4_pmu_runtime_resume - PMU runtime resume callback
+ *
+ * Platform specific PMU runtime resume callback for OMAP4430 devices to
+ * configure the cross trigger interface for routing PMU interrupts. This
+ * is called by the PM runtime framework.
+ */
+static int omap4_pmu_runtime_resume(struct device *dev)
+{
+	/* configure CTI0 for PMU IRQ routing */
+	cti_unlock(&omap4_cti[0]);
+	cti_map_trigger(&omap4_cti[0], 1, 6, 2);
+	cti_enable(&omap4_cti[0]);
+
+	/* configure CTI1 for PMU IRQ routing */
+	cti_unlock(&omap4_cti[1]);
+	cti_map_trigger(&omap4_cti[1], 1, 6, 3);
+	cti_enable(&omap4_cti[1]);
+
+	return 0;
+}
+
+/*
+ * omap4_pmu_runtime_suspend - PMU runtime suspend callback
+ *
+ * Platform specific PMU runtime suspend callback for OMAP4430 devices to
+ * disable the cross trigger interface interrupts. This is called by the
+ * PM runtime framework.
+ */
+static int omap4_pmu_runtime_suspend(struct device *dev)
+{
+	cti_disable(&omap4_cti[0]);
+	cti_disable(&omap4_cti[1]);
+
+	return 0;
+}
+
+/*
+ * omap4_pmu_handle_irq - PMU IRQ Handler
+ *
+ * Platform specific PMU IRQ handler for OMAP4430 devices that route PMU
+ * interrupts via cross trigger interface. This is called by the PMU driver.
+ */
+static irqreturn_t
+omap4_pmu_handle_irq(int irq, void *dev, irq_handler_t handler)
+{
+	if (irq == OMAP44XX_IRQ_CTI0)
+		cti_irq_ack(&omap4_cti[0]);
+	else if (irq == OMAP44XX_IRQ_CTI1)
+		cti_irq_ack(&omap4_cti[1]);
+
+	return handler(irq, dev);
+}
+
+/*
+ * omap4_init_cti - initialise cross trigger interface instances
+ *
+ * Initialises two cross trigger interface (CTI) instances in preparation
+ * for routing PMU interrupts to the OMAP interrupt controller. Note that
+ * this does not configure the actual CTI hardware but just the CTI
+ * software structures to be used.
+ */
+static int __init omap4_init_cti(void)
+{
+	omap4_cti[0].base = ioremap(OMAP44XX_CTI0_BASE, SZ_4K);
+	omap4_cti[1].base = ioremap(OMAP44XX_CTI1_BASE, SZ_4K);
+
+	if (!omap4_cti[0].base || !omap4_cti[1].base) {
+		pr_err("ioremap for OMAP4 CTI failed\n");
+		return -ENOMEM;
+	}
+
+	cti_init(&omap4_cti[0], omap4_cti[0].base, OMAP44XX_IRQ_CTI0, 6);
+	cti_init(&omap4_cti[1], omap4_cti[1].base, OMAP44XX_IRQ_CTI1, 6);
+
+	return 0;
+}
+
+/*
  * omap4430_init_pmu - creates and registers PMU platform device
  *
  * Uses OMAP HWMOD framework to create and register an ARM PMU device.
@@ -69,6 +150,9 @@ static int __init omap4430_init_pmu(void)
 	char *oh_name;
 	char *dev_name = "arm-pmu";
 
+	if (omap4_init_cti())
+		return -ENOMEM;
+
 	oh_name = "l3_main_3";
 	oh[0] = omap_hwmod_lookup(oh_name);
 	if (!oh[0]) {
@@ -88,8 +172,12 @@ static int __init omap4430_init_pmu(void)
 		return -ENODEV;
 	}
 
-	omap_pmu_dev = omap_device_build_ss(dev_name, id, oh, 3, NULL,
-				0, NULL, 0, 0);
+	omap_pmu_data.handle_irq = omap4_pmu_handle_irq;
+	omap_pmu_data.runtime_resume = omap4_pmu_runtime_resume;
+	omap_pmu_data.runtime_suspend = omap4_pmu_runtime_suspend;
+
+	omap_pmu_dev = omap_device_build_ss(dev_name, id, oh, 3, &omap_pmu_data,
+				sizeof(omap_pmu_data), NULL, 0, 0);
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 				dev_name);
 
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index c0d478e..1800a9b 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -58,5 +58,8 @@
 #define OMAP44XX_HSUSB_OHCI_BASE	(L4_44XX_BASE + 0x64800)
 #define OMAP44XX_HSUSB_EHCI_BASE	(L4_44XX_BASE + 0x64C00)
 
+#define OMAP44XX_CTI0_BASE		(L4_EMU_44XX_BASE + 0x148000)
+#define OMAP44XX_CTI1_BASE		(L4_EMU_44XX_BASE + 0x149000)
+
 #endif /* __ASM_ARCH_OMAP44XX_H */
 
-- 
1.7.9.5


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

* [PATCH V2 06/10] ARM: OMAP4: Route PMU IRQs to CTI IRQs
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ming Lei <ming.lei@canonical.com>

For OMAP4430 there are no dedicate PMU interrupts, however, PMU events can be
routed to via the CTI IRQs. This allows tools such as PERF and OPROFILE to work
on OMAP4430.

The idea is from Woodruff Richard in the disscussion about "Oprofile on
Pandaboard / Omap4" on pandaboard at googlegroups.com.

Ming's original patch was called "arm: omap4: support pmu" [1] and has been
renamed and modified by Jon Hunter. There main differences from the original
patch are ...

1. Instead of only configuring the CTI interrupt once during boot, the
   interrupts are configured everytime the the PMU is used. The reason for this
   is because during power transitions the CTI logic state will be lost and so
   we will need to configure the interrupts everytime they are used. This is
   accomplished by using the PM runtime callbacks which will be called whenever
   the PMU is used.
2. Assign the PMU events to different cross triggering channels. This prevents
   a single PMU event generating interrupts to both CPUs and hence can cause
   spurious interrupts to occur. Reported by Ming [2].

[1] http://marc.info/?l=linux-arm-kernel&m=132227620816504&w=2
[2] http://permalink.gmane.org/gmane.linux.linaro.devel/10532

Acked-by: Jean Pihet <j-pihet@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Woodruff Richard <r-woodruff2@ti.com>
Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/pmu.c                  |   92 +++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/omap44xx.h |    3 +
 2 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 1b36eda..228e247 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -16,11 +16,14 @@
 #include <linux/pm_runtime.h>
 
 #include <asm/pmu.h>
+#include <asm/cti.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+static struct arm_pmu_platdata omap_pmu_data;
 static struct platform_device *omap_pmu_dev;
+static struct cti omap4_cti[2];
 
 /*
  * omap2_init_pmu - creates and registers PMU platform device
@@ -54,6 +57,84 @@ static int __init omap2_init_pmu(void)
 }
 
 /*
+ * omap4_pmu_runtime_resume - PMU runtime resume callback
+ *
+ * Platform specific PMU runtime resume callback for OMAP4430 devices to
+ * configure the cross trigger interface for routing PMU interrupts. This
+ * is called by the PM runtime framework.
+ */
+static int omap4_pmu_runtime_resume(struct device *dev)
+{
+	/* configure CTI0 for PMU IRQ routing */
+	cti_unlock(&omap4_cti[0]);
+	cti_map_trigger(&omap4_cti[0], 1, 6, 2);
+	cti_enable(&omap4_cti[0]);
+
+	/* configure CTI1 for PMU IRQ routing */
+	cti_unlock(&omap4_cti[1]);
+	cti_map_trigger(&omap4_cti[1], 1, 6, 3);
+	cti_enable(&omap4_cti[1]);
+
+	return 0;
+}
+
+/*
+ * omap4_pmu_runtime_suspend - PMU runtime suspend callback
+ *
+ * Platform specific PMU runtime suspend callback for OMAP4430 devices to
+ * disable the cross trigger interface interrupts. This is called by the
+ * PM runtime framework.
+ */
+static int omap4_pmu_runtime_suspend(struct device *dev)
+{
+	cti_disable(&omap4_cti[0]);
+	cti_disable(&omap4_cti[1]);
+
+	return 0;
+}
+
+/*
+ * omap4_pmu_handle_irq - PMU IRQ Handler
+ *
+ * Platform specific PMU IRQ handler for OMAP4430 devices that route PMU
+ * interrupts via cross trigger interface. This is called by the PMU driver.
+ */
+static irqreturn_t
+omap4_pmu_handle_irq(int irq, void *dev, irq_handler_t handler)
+{
+	if (irq == OMAP44XX_IRQ_CTI0)
+		cti_irq_ack(&omap4_cti[0]);
+	else if (irq == OMAP44XX_IRQ_CTI1)
+		cti_irq_ack(&omap4_cti[1]);
+
+	return handler(irq, dev);
+}
+
+/*
+ * omap4_init_cti - initialise cross trigger interface instances
+ *
+ * Initialises two cross trigger interface (CTI) instances in preparation
+ * for routing PMU interrupts to the OMAP interrupt controller. Note that
+ * this does not configure the actual CTI hardware but just the CTI
+ * software structures to be used.
+ */
+static int __init omap4_init_cti(void)
+{
+	omap4_cti[0].base = ioremap(OMAP44XX_CTI0_BASE, SZ_4K);
+	omap4_cti[1].base = ioremap(OMAP44XX_CTI1_BASE, SZ_4K);
+
+	if (!omap4_cti[0].base || !omap4_cti[1].base) {
+		pr_err("ioremap for OMAP4 CTI failed\n");
+		return -ENOMEM;
+	}
+
+	cti_init(&omap4_cti[0], omap4_cti[0].base, OMAP44XX_IRQ_CTI0, 6);
+	cti_init(&omap4_cti[1], omap4_cti[1].base, OMAP44XX_IRQ_CTI1, 6);
+
+	return 0;
+}
+
+/*
  * omap4430_init_pmu - creates and registers PMU platform device
  *
  * Uses OMAP HWMOD framework to create and register an ARM PMU device.
@@ -69,6 +150,9 @@ static int __init omap4430_init_pmu(void)
 	char *oh_name;
 	char *dev_name = "arm-pmu";
 
+	if (omap4_init_cti())
+		return -ENOMEM;
+
 	oh_name = "l3_main_3";
 	oh[0] = omap_hwmod_lookup(oh_name);
 	if (!oh[0]) {
@@ -88,8 +172,12 @@ static int __init omap4430_init_pmu(void)
 		return -ENODEV;
 	}
 
-	omap_pmu_dev = omap_device_build_ss(dev_name, id, oh, 3, NULL,
-				0, NULL, 0, 0);
+	omap_pmu_data.handle_irq = omap4_pmu_handle_irq;
+	omap_pmu_data.runtime_resume = omap4_pmu_runtime_resume;
+	omap_pmu_data.runtime_suspend = omap4_pmu_runtime_suspend;
+
+	omap_pmu_dev = omap_device_build_ss(dev_name, id, oh, 3, &omap_pmu_data,
+				sizeof(omap_pmu_data), NULL, 0, 0);
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 				dev_name);
 
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index c0d478e..1800a9b 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -58,5 +58,8 @@
 #define OMAP44XX_HSUSB_OHCI_BASE	(L4_44XX_BASE + 0x64800)
 #define OMAP44XX_HSUSB_EHCI_BASE	(L4_44XX_BASE + 0x64C00)
 
+#define OMAP44XX_CTI0_BASE		(L4_EMU_44XX_BASE + 0x148000)
+#define OMAP44XX_CTI1_BASE		(L4_EMU_44XX_BASE + 0x149000)
+
 #endif /* __ASM_ARCH_OMAP44XX_H */
 
-- 
1.7.9.5

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

* [PATCH V2 07/10] ARM: OMAP4: CLKDM: Update supported transition modes
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

For OMAP3+ devices, the clock domains (CLKDMs) support one or more of the
following transition modes ...

NO_SLEEP (0x0) - A clock domain sleep transition is never initiated,
		 irrespective of the hardware conditions.
SW_SLEEP (0x1) - A software-forced sleep transition. The transition is initiated
		 when the associated hardware conditions are satisfied
SW_WKUP  (0x2) - A software-forced clock domain wake-up transition is initiated,
		 irrespective of the hardware conditions.
HW_AUTO  (0x3) - Hardware-controlled automatic sleep and wake-up transition is
		 initiated by the PRCM module when the associated hardware
		 conditions are satisfied.

For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is equivalent
to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP for OMAP4 devices
is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt status is set in case of
SW_SLEEP transition, and not set in case of HW_AUTO transition.

For OMAP4 devices, all CLKDMs support HW_AUTO and therefore we can place the
CLKDMs in the HW_AUTO state instead of the SW_SLEEP mode. Hence, we do not
need to use the SW_SLEEP mode. With regard to NO_SLEEP and SW_WKUP it is
preferred to use SW_WKUP mode if the CLKDM supports it and so use this mode
instead of NO_SLEEP where possible.

For a software perspective the above 4 modes are represented by the following
flags to indicate what modes are supported by each of the CLKDMs.

CLKDM_CAN_DISABLE_AUTO	--> NO_SLEEP
CLKDM_CAN_ENABLE_AUTO	--> HW_AUTO
CLKDM_CAN_FORCE_SLEEP	--> SW_SLEEP
CLKDM_CAN_FORCE_WAKEUP	--> SW_WKUP

By eliminating the SW_SLEEP mode the the mapping of the flags for OMAP4 devices
can becomes ...

CLKDM_CAN_DISABLE_AUTO	--> NO_SLEEP
CLKDM_CAN_ENABLE_AUTO	--> HW_AUTO
CLKDM_CAN_FORCE_SLEEP	--> HW_AUTO
CLKDM_CAN_FORCE_WAKEUP	--> SW_WKUP

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Reviewed-by: Benoit Cousson <b-cousson@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/clockdomain44xx.c |    7 +++++--
 arch/arm/mach-omap2/cminst44xx.c      |   14 --------------
 2 files changed, 5 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 4f04dd1..99ce556 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -70,7 +70,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
 
 static int omap4_clkdm_sleep(struct clockdomain *clkdm)
 {
-	omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
+	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 	return 0;
 }
@@ -90,7 +90,10 @@ static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
 
 static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
 {
-	omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+		omap4_clkdm_wakeup(clkdm);
+	else
+		omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 }
 
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 8c86d29..7990dff 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -235,20 +235,6 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs)
 }
 
 /**
- * omap4_cminst_clkdm_force_sleep - try to put a clockdomain into idle
- * @part: PRCM partition ID that the clockdomain registers exist in
- * @inst: CM instance register offset (*_INST macro)
- * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
- *
- * Put a clockdomain referred to by (@part, @inst, @cdoffs) into idle
- * No return value.
- */
-void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs)
-{
-	_clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs);
-}
-
-/**
  * omap4_cminst_clkdm_force_sleep - try to take a clockdomain out of idle
  * @part: PRCM partition ID that the clockdomain registers exist in
  * @inst: CM instance register offset (*_INST macro)
-- 
1.7.9.5


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

* [PATCH V2 07/10] ARM: OMAP4: CLKDM: Update supported transition modes
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

For OMAP3+ devices, the clock domains (CLKDMs) support one or more of the
following transition modes ...

NO_SLEEP (0x0) - A clock domain sleep transition is never initiated,
		 irrespective of the hardware conditions.
SW_SLEEP (0x1) - A software-forced sleep transition. The transition is initiated
		 when the associated hardware conditions are satisfied
SW_WKUP  (0x2) - A software-forced clock domain wake-up transition is initiated,
		 irrespective of the hardware conditions.
HW_AUTO  (0x3) - Hardware-controlled automatic sleep and wake-up transition is
		 initiated by the PRCM module when the associated hardware
		 conditions are satisfied.

For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is equivalent
to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP for OMAP4 devices
is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt status is set in case of
SW_SLEEP transition, and not set in case of HW_AUTO transition.

For OMAP4 devices, all CLKDMs support HW_AUTO and therefore we can place the
CLKDMs in the HW_AUTO state instead of the SW_SLEEP mode. Hence, we do not
need to use the SW_SLEEP mode. With regard to NO_SLEEP and SW_WKUP it is
preferred to use SW_WKUP mode if the CLKDM supports it and so use this mode
instead of NO_SLEEP where possible.

For a software perspective the above 4 modes are represented by the following
flags to indicate what modes are supported by each of the CLKDMs.

CLKDM_CAN_DISABLE_AUTO	--> NO_SLEEP
CLKDM_CAN_ENABLE_AUTO	--> HW_AUTO
CLKDM_CAN_FORCE_SLEEP	--> SW_SLEEP
CLKDM_CAN_FORCE_WAKEUP	--> SW_WKUP

By eliminating the SW_SLEEP mode the the mapping of the flags for OMAP4 devices
can becomes ...

CLKDM_CAN_DISABLE_AUTO	--> NO_SLEEP
CLKDM_CAN_ENABLE_AUTO	--> HW_AUTO
CLKDM_CAN_FORCE_SLEEP	--> HW_AUTO
CLKDM_CAN_FORCE_WAKEUP	--> SW_WKUP

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Reviewed-by: Benoit Cousson <b-cousson@ti.com>
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/clockdomain44xx.c |    7 +++++--
 arch/arm/mach-omap2/cminst44xx.c      |   14 --------------
 2 files changed, 5 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 4f04dd1..99ce556 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -70,7 +70,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
 
 static int omap4_clkdm_sleep(struct clockdomain *clkdm)
 {
-	omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
+	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 	return 0;
 }
@@ -90,7 +90,10 @@ static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
 
 static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
 {
-	omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+		omap4_clkdm_wakeup(clkdm);
+	else
+		omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 }
 
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 8c86d29..7990dff 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -235,20 +235,6 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs)
 }
 
 /**
- * omap4_cminst_clkdm_force_sleep - try to put a clockdomain into idle
- * @part: PRCM partition ID that the clockdomain registers exist in
- * @inst: CM instance register offset (*_INST macro)
- * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
- *
- * Put a clockdomain referred to by (@part, @inst, @cdoffs) into idle
- * No return value.
- */
-void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs)
-{
-	_clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs);
-}
-
-/**
  * omap4_cminst_clkdm_force_sleep - try to take a clockdomain out of idle
  * @part: PRCM partition ID that the clockdomain registers exist in
  * @inst: CM instance register offset (*_INST macro)
-- 
1.7.9.5

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

On the OMAP4 devices the EMU power domain is configured in hardware so that its
next power state is OFF. This cannot be overriden by software and this means
that when ever the EMU clock domain automatically transitions to the idle
state, the power domain will transition to OFF. Therefore, when the EMU power
domain is in-use, we need to prevent the clock domain from transitioning to
the idle state. This can be accomplished by placing the EMU clock domain in the
SW_WKUP mode versus the HW_AUTO mode.

In the current software configuration of the EMU clock domain the flag
CLKDM_CAN_ENABLE_AUTO is set and this is allowing the clock domain to
automatically transition to the idle state via hardware control (by enabling
the HW_AUTO mode). To avoid this, disable the CLKDM_CAN_ENABLE_AUTO flag for
the EMU clock domain.

By removing the CLKDM_CAN_ENABLE_AUTO flag, the EMU clock domain will always
remain on and hence, this will break low-power modes. The EMU clock domain only
support the SW_WKUP and HW_AUTO transition modes (for more details refer to the
OMAP4430 TRM) and power down the EMU power domain we need to place the EMU
clock domain back into the HW_AUTO mode. This can be accomplished by setting
the CLKDM_CAN_FORCE_SLEEP flag, which for an OMAP4 device will enable the
HW_AUTO mode.

Therefore, set the CLKDM_CAN_SWSUP flag for the EMU clock domain, which defined
as follows.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/clockdomains44xx_data.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index c534258..ba74006 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,7 @@ static struct clockdomain emu_sys_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
-	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+	.flags		  = CLKDM_CAN_SWSUP,
 };
 
 static struct clockdomain l3_dma_44xx_clkdm = {
-- 
1.7.9.5


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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

On the OMAP4 devices the EMU power domain is configured in hardware so that its
next power state is OFF. This cannot be overriden by software and this means
that when ever the EMU clock domain automatically transitions to the idle
state, the power domain will transition to OFF. Therefore, when the EMU power
domain is in-use, we need to prevent the clock domain from transitioning to
the idle state. This can be accomplished by placing the EMU clock domain in the
SW_WKUP mode versus the HW_AUTO mode.

In the current software configuration of the EMU clock domain the flag
CLKDM_CAN_ENABLE_AUTO is set and this is allowing the clock domain to
automatically transition to the idle state via hardware control (by enabling
the HW_AUTO mode). To avoid this, disable the CLKDM_CAN_ENABLE_AUTO flag for
the EMU clock domain.

By removing the CLKDM_CAN_ENABLE_AUTO flag, the EMU clock domain will always
remain on and hence, this will break low-power modes. The EMU clock domain only
support the SW_WKUP and HW_AUTO transition modes (for more details refer to the
OMAP4430 TRM) and power down the EMU power domain we need to place the EMU
clock domain back into the HW_AUTO mode. This can be accomplished by setting
the CLKDM_CAN_FORCE_SLEEP flag, which for an OMAP4 device will enable the
HW_AUTO mode.

Therefore, set the CLKDM_CAN_SWSUP flag for the EMU clock domain, which defined
as follows.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/clockdomains44xx_data.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index c534258..ba74006 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,7 @@ static struct clockdomain emu_sys_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
-	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+	.flags		  = CLKDM_CAN_SWSUP,
 };
 
 static struct clockdomain l3_dma_44xx_clkdm = {
-- 
1.7.9.5

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

* [PATCH V2 09/10] ARM: OMAP4: Enable PMU for OMAP4460/70
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

OMAP4460 and OMAP4470 devices have dedicated PMU interrupts and so add these
interrupts to the MPU HWMOD so we can use these for PMU events on these
devices. The PMU interrupts need to be the first interrupts in the array of
interrupts as the ARM PMU driver assumes this.

By using these dedicated interrupts we only need to enable the MPU sub-system
for PMU to work. This is different to OMAP4430 that did not have dedicated
interrupts and required other power domains such as the DEBUGSS to be enabled
so we could route the PMU events to the CTI interrupts. Hence, OMAP4460 and
OMAP4470 devices can use the same function to create the PMU device that is
using by OMAP2/3.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    2 ++
 arch/arm/mach-omap2/pmu.c                  |   14 +++++++++-----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index faf5a6d..882bbe6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -2453,6 +2453,8 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
 
 /* mpu */
 static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
+	{ .name = "pmu0", .irq = 54 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "pmu1", .irq = 55 + OMAP44XX_IRQ_GIC_START },
 	{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
 	{ .irq = -1 }
 };
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 228e247..f1b535a 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -189,13 +189,17 @@ static int __init omap4430_init_pmu(void)
 
 static int __init omap_init_pmu(void)
 {
-
-	if (cpu_is_omap24xx() || cpu_is_omap34xx())
-		return omap2_init_pmu();
+	/*
+	 * OMAP4460/70 devices may use the omap2_init_pmu() function because
+	 * these devices have dedicated PMU IRQs and only need the MPU
+	 * sub-system to be enabled. OMAP4430 does not have dedicated PMU
+	 * interrupts and so the CTI IRQs are used and this requires additional
+	 * sub-systems to be enabled.
+	 */
 	if (cpu_is_omap443x())
 		return omap4430_init_pmu();
-
-	return 0;
+	else
+		return omap2_init_pmu();
 }
 
 subsys_initcall(omap_init_pmu);
-- 
1.7.9.5


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

* [PATCH V2 09/10] ARM: OMAP4: Enable PMU for OMAP4460/70
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

OMAP4460 and OMAP4470 devices have dedicated PMU interrupts and so add these
interrupts to the MPU HWMOD so we can use these for PMU events on these
devices. The PMU interrupts need to be the first interrupts in the array of
interrupts as the ARM PMU driver assumes this.

By using these dedicated interrupts we only need to enable the MPU sub-system
for PMU to work. This is different to OMAP4430 that did not have dedicated
interrupts and required other power domains such as the DEBUGSS to be enabled
so we could route the PMU events to the CTI interrupts. Hence, OMAP4460 and
OMAP4470 devices can use the same function to create the PMU device that is
using by OMAP2/3.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    2 ++
 arch/arm/mach-omap2/pmu.c                  |   14 +++++++++-----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index faf5a6d..882bbe6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -2453,6 +2453,8 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
 
 /* mpu */
 static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
+	{ .name = "pmu0", .irq = 54 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "pmu1", .irq = 55 + OMAP44XX_IRQ_GIC_START },
 	{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
 	{ .irq = -1 }
 };
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 228e247..f1b535a 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -189,13 +189,17 @@ static int __init omap4430_init_pmu(void)
 
 static int __init omap_init_pmu(void)
 {
-
-	if (cpu_is_omap24xx() || cpu_is_omap34xx())
-		return omap2_init_pmu();
+	/*
+	 * OMAP4460/70 devices may use the omap2_init_pmu() function because
+	 * these devices have dedicated PMU IRQs and only need the MPU
+	 * sub-system to be enabled. OMAP4430 does not have dedicated PMU
+	 * interrupts and so the CTI IRQs are used and this requires additional
+	 * sub-systems to be enabled.
+	 */
 	if (cpu_is_omap443x())
 		return omap4430_init_pmu();
-
-	return 0;
+	else
+		return omap2_init_pmu();
 }
 
 subsys_initcall(omap_init_pmu);
-- 
1.7.9.5

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

* [PATCH V2 10/10] ARM: OMAP2+: PMU: Add QoS constraint
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 21:22   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-omap, linux-arm
  Cc: Jon Hunter, Ming Lei, Will Deacon, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

When CPU-idle is enabled, the MPU sub-system will transition to low power
states during idle periods. If the PMU is active and the MPU sub-system
transitions to a low power state, such as retention, then the PMU context
will be lost and PMU events will stop. To prevent this from happening add a
QoS constraint whenever PMU is active to prevent the MPU sub-system from
transitioning to a low power state.

By default the PMU QoS constraint is set to -1 so it will not prevent any low
power states and when the PMU is enabled, it is set to 0, so that only C-state
C0 is allowed.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/pmu.c |   52 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index f1b535a..e457f0e 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -13,6 +13,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
+#include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 
 #include <asm/pmu.h>
@@ -21,11 +22,40 @@
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+static struct pm_qos_request pmu_pm_qos_request;
 static struct arm_pmu_platdata omap_pmu_data;
 static struct platform_device *omap_pmu_dev;
 static struct cti omap4_cti[2];
 
 /*
+ * omap_pmu_runtime_resume - PMU runtime resume callback
+ *
+ * Platform specific PMU runtime resume callback for OMAP devices to
+ * configure the cross trigger interface for routing PMU interrupts.
+ * This is called by the PM runtime framework.
+ */
+static int omap_pmu_runtime_resume(struct device *dev)
+{
+	pm_qos_update_request(&pmu_pm_qos_request, 0);
+
+	return 0;
+}
+
+/*
+ * omap_pmu_runtime_suspend - PMU runtime suspend callback
+ *
+ * Platform specific PMU runtime suspend callback for OMAP devices to
+ * disable the cross trigger interface interrupts. This is called by
+ * the PM runtime framework.
+ */
+static int omap_pmu_runtime_suspend(struct device *dev)
+{
+	pm_qos_update_request(&pmu_pm_qos_request, PM_QOS_DEFAULT_VALUE);
+
+	return 0;
+}
+
+/*
  * omap2_init_pmu - creates and registers PMU platform device
  *
  * Uses OMAP HWMOD framework to create and register an ARM PMU device.
@@ -45,7 +75,11 @@ static int __init omap2_init_pmu(void)
 		return -ENODEV;
 	}
 
-	omap_pmu_dev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
+	omap_pmu_data.runtime_resume = omap_pmu_runtime_resume;
+	omap_pmu_data.runtime_suspend = omap_pmu_runtime_suspend;
+
+	omap_pmu_dev = omap_device_build(dev_name, id, oh, &omap_pmu_data,
+				sizeof(omap_pmu_data), NULL, 0, 0);
 
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 				dev_name);
@@ -65,6 +99,8 @@ static int __init omap2_init_pmu(void)
  */
 static int omap4_pmu_runtime_resume(struct device *dev)
 {
+	pm_qos_update_request(&pmu_pm_qos_request, 0);
+
 	/* configure CTI0 for PMU IRQ routing */
 	cti_unlock(&omap4_cti[0]);
 	cti_map_trigger(&omap4_cti[0], 1, 6, 2);
@@ -90,6 +126,8 @@ static int omap4_pmu_runtime_suspend(struct device *dev)
 	cti_disable(&omap4_cti[0]);
 	cti_disable(&omap4_cti[1]);
 
+	pm_qos_update_request(&pmu_pm_qos_request, PM_QOS_DEFAULT_VALUE);
+
 	return 0;
 }
 
@@ -189,6 +227,8 @@ static int __init omap4430_init_pmu(void)
 
 static int __init omap_init_pmu(void)
 {
+	int r;
+
 	/*
 	 * OMAP4460/70 devices may use the omap2_init_pmu() function because
 	 * these devices have dedicated PMU IRQs and only need the MPU
@@ -197,9 +237,15 @@ static int __init omap_init_pmu(void)
 	 * sub-systems to be enabled.
 	 */
 	if (cpu_is_omap443x())
-		return omap4430_init_pmu();
+		r = omap4430_init_pmu();
 	else
-		return omap2_init_pmu();
+		r = omap2_init_pmu();
+
+	if (!r)
+		pm_qos_add_request(&pmu_pm_qos_request, PM_QOS_CPU_DMA_LATENCY,
+				PM_QOS_DEFAULT_VALUE);
+
+	return r;
 }
 
 subsys_initcall(omap_init_pmu);
-- 
1.7.9.5


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

* [PATCH V2 10/10] ARM: OMAP2+: PMU: Add QoS constraint
@ 2012-06-07 21:22   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 21:22 UTC (permalink / raw)
  To: linux-arm-kernel

When CPU-idle is enabled, the MPU sub-system will transition to low power
states during idle periods. If the PMU is active and the MPU sub-system
transitions to a low power state, such as retention, then the PMU context
will be lost and PMU events will stop. To prevent this from happening add a
QoS constraint whenever PMU is active to prevent the MPU sub-system from
transitioning to a low power state.

By default the PMU QoS constraint is set to -1 so it will not prevent any low
power states and when the PMU is enabled, it is set to 0, so that only C-state
C0 is allowed.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/pmu.c |   52 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index f1b535a..e457f0e 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -13,6 +13,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
+#include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 
 #include <asm/pmu.h>
@@ -21,11 +22,40 @@
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+static struct pm_qos_request pmu_pm_qos_request;
 static struct arm_pmu_platdata omap_pmu_data;
 static struct platform_device *omap_pmu_dev;
 static struct cti omap4_cti[2];
 
 /*
+ * omap_pmu_runtime_resume - PMU runtime resume callback
+ *
+ * Platform specific PMU runtime resume callback for OMAP devices to
+ * configure the cross trigger interface for routing PMU interrupts.
+ * This is called by the PM runtime framework.
+ */
+static int omap_pmu_runtime_resume(struct device *dev)
+{
+	pm_qos_update_request(&pmu_pm_qos_request, 0);
+
+	return 0;
+}
+
+/*
+ * omap_pmu_runtime_suspend - PMU runtime suspend callback
+ *
+ * Platform specific PMU runtime suspend callback for OMAP devices to
+ * disable the cross trigger interface interrupts. This is called by
+ * the PM runtime framework.
+ */
+static int omap_pmu_runtime_suspend(struct device *dev)
+{
+	pm_qos_update_request(&pmu_pm_qos_request, PM_QOS_DEFAULT_VALUE);
+
+	return 0;
+}
+
+/*
  * omap2_init_pmu - creates and registers PMU platform device
  *
  * Uses OMAP HWMOD framework to create and register an ARM PMU device.
@@ -45,7 +75,11 @@ static int __init omap2_init_pmu(void)
 		return -ENODEV;
 	}
 
-	omap_pmu_dev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
+	omap_pmu_data.runtime_resume = omap_pmu_runtime_resume;
+	omap_pmu_data.runtime_suspend = omap_pmu_runtime_suspend;
+
+	omap_pmu_dev = omap_device_build(dev_name, id, oh, &omap_pmu_data,
+				sizeof(omap_pmu_data), NULL, 0, 0);
 
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 				dev_name);
@@ -65,6 +99,8 @@ static int __init omap2_init_pmu(void)
  */
 static int omap4_pmu_runtime_resume(struct device *dev)
 {
+	pm_qos_update_request(&pmu_pm_qos_request, 0);
+
 	/* configure CTI0 for PMU IRQ routing */
 	cti_unlock(&omap4_cti[0]);
 	cti_map_trigger(&omap4_cti[0], 1, 6, 2);
@@ -90,6 +126,8 @@ static int omap4_pmu_runtime_suspend(struct device *dev)
 	cti_disable(&omap4_cti[0]);
 	cti_disable(&omap4_cti[1]);
 
+	pm_qos_update_request(&pmu_pm_qos_request, PM_QOS_DEFAULT_VALUE);
+
 	return 0;
 }
 
@@ -189,6 +227,8 @@ static int __init omap4430_init_pmu(void)
 
 static int __init omap_init_pmu(void)
 {
+	int r;
+
 	/*
 	 * OMAP4460/70 devices may use the omap2_init_pmu() function because
 	 * these devices have dedicated PMU IRQs and only need the MPU
@@ -197,9 +237,15 @@ static int __init omap_init_pmu(void)
 	 * sub-systems to be enabled.
 	 */
 	if (cpu_is_omap443x())
-		return omap4430_init_pmu();
+		r = omap4430_init_pmu();
 	else
-		return omap2_init_pmu();
+		r = omap2_init_pmu();
+
+	if (!r)
+		pm_qos_add_request(&pmu_pm_qos_request, PM_QOS_CPU_DMA_LATENCY,
+				PM_QOS_DEFAULT_VALUE);
+
+	return r;
 }
 
 subsys_initcall(omap_init_pmu);
-- 
1.7.9.5

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

* Re: [PATCH V2 00/10] ARM: OMAP4: Add PMU Support
  2012-06-07 21:22 ` Jon Hunter
@ 2012-06-07 23:36   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 23:36 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Paul Walmsley, Kevin Hilman


On 06/07/2012 04:22 PM, Jon Hunter wrote:
> This series adds PMU support for OMAP4 devices. This is based upon Will Deacons
> series [1]. This series fixes the management of the EMU power domain so that
> PMU can be enabled at runtime and low-power states are not prevented when PMU
> is not in-use. The fix is based upon inputs from Benoit, Paul and Kevin [2].
> 
> This series also converts OMAP2/3 devices to use HWMOD to create the PMU device
> and add a new file to mach-omap2 directory called pmu.c where the PMU devices
> are created.
> 
> This series is based upon the latest linux-omap master branch from Tony
> (3.5-rc1).
> 
> Testing:
> - Verified that PMU is working on OMAP3430 Beagle Board, OMAP4430 Blaze and
>   4460 Panda.
> - Tested on the above boards with CPU-idle enabled to ensure that PMU is working
>   with power management. For OMAP4 boards I have disabled CPU1 so that CPU0 and
>   hence the MPU power domain is reaching the low-power retention state.
> - I have booted the kernel on an OMAP2430 SDP but not verified PMU is working.
> - Unable to verify 4470 Blaze because kernel is not currently booting.

Update on the 4470 status. Now I have 4470 booting [1], I have now
verified that PMU on 4470 is also working with this series (and with
CPU-idle enabled).

Cheers
Jon

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

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

* [PATCH V2 00/10] ARM: OMAP4: Add PMU Support
@ 2012-06-07 23:36   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-07 23:36 UTC (permalink / raw)
  To: linux-arm-kernel


On 06/07/2012 04:22 PM, Jon Hunter wrote:
> This series adds PMU support for OMAP4 devices. This is based upon Will Deacons
> series [1]. This series fixes the management of the EMU power domain so that
> PMU can be enabled at runtime and low-power states are not prevented when PMU
> is not in-use. The fix is based upon inputs from Benoit, Paul and Kevin [2].
> 
> This series also converts OMAP2/3 devices to use HWMOD to create the PMU device
> and add a new file to mach-omap2 directory called pmu.c where the PMU devices
> are created.
> 
> This series is based upon the latest linux-omap master branch from Tony
> (3.5-rc1).
> 
> Testing:
> - Verified that PMU is working on OMAP3430 Beagle Board, OMAP4430 Blaze and
>   4460 Panda.
> - Tested on the above boards with CPU-idle enabled to ensure that PMU is working
>   with power management. For OMAP4 boards I have disabled CPU1 so that CPU0 and
>   hence the MPU power domain is reaching the low-power retention state.
> - I have booted the kernel on an OMAP2430 SDP but not verified PMU is working.
> - Unable to verify 4470 Blaze because kernel is not currently booting.

Update on the 4470 status. Now I have 4470 booting [1], I have now
verified that PMU on 4470 is also working with this series (and with
CPU-idle enabled).

Cheers
Jon

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

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-07 21:22   ` Jon Hunter
@ 2012-06-08  9:47     ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-06-08  9:47 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Ming Lei, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

Hi Jon,

On Thu, Jun 07, 2012 at 10:22:03PM +0100, Jon Hunter wrote:
> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
> index 186c8cb..00adb98 100644
> --- a/arch/arm/kernel/perf_event.c
> +++ b/arch/arm/kernel/perf_event.c
> @@ -20,6 +20,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/spinlock.h>
>  #include <linux/uaccess.h>
> +#include <linux/pm_runtime.h>
>  
>  #include <asm/cputype.h>
>  #include <asm/irq.h>
> @@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>  {
>  	int i, irq, irqs;
>  	struct platform_device *pmu_device = armpmu->plat_device;
> -	struct arm_pmu_platdata *plat =
> -		dev_get_platdata(&pmu_device->dev);
>  
>  	irqs = min(pmu_device->num_resources, num_possible_cpus());
>  
> @@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>  		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
>  			continue;
>  		irq = platform_get_irq(pmu_device, i);
> -		if (irq >= 0) {
> -			if (plat && plat->disable_irq)
> -				plat->disable_irq(irq);
> +		if (irq >= 0)
>  			free_irq(irq, armpmu);
> -		}
>  	}
>  
>  	release_pmu(armpmu->type);
> +	pm_runtime_put_sync(&armpmu->plat_device->dev);

We probably want to suspend the device before releasing it, otherwise we
could race against somebody else trying to initialise the PMU again.

>  
>  static int
> @@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>  		return err;
>  	}
>  
> +	pm_runtime_get_sync(&armpmu->plat_device->dev);

Better pass &pmu_device->dev instead (similarly in release).

> +
>  	plat = dev_get_platdata(&pmu_device->dev);
>  	if (plat && plat->handle_irq)
>  		handle_irq = armpmu_platform_irq;
> @@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>  				irq);
>  			armpmu_release_hardware(armpmu);
>  			return err;
> -		} else if (plat && plat->enable_irq)
> -			plat->enable_irq(irq);
> +		}
>  
>  		cpumask_set_cpu(i, &armpmu->active_irqs);
>  	}
> @@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
>  	armpmu->stop();
>  }

There are potential failure paths in the reservation code here where we
don't `put' the PMU back. Can you move the pm_runtime_get_sync call later in
the function, or does it have to called before we enable the IRQ line?

> +#ifdef CONFIG_PM_RUNTIME
> +static int armpmu_runtime_resume(struct device *dev)
> +{
> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
> +
> +	if (plat->runtime_resume)

I think you need to check plat too since it may be NULL on other platforms.

> +		return plat->runtime_resume(dev);
> +
> +	return 0;
> +}
> +
> +static int armpmu_runtime_suspend(struct device *dev)
> +{
> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
> +
> +	if (plat->runtime_suspend)

Same here.

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-08  9:47     ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-06-08  9:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

On Thu, Jun 07, 2012 at 10:22:03PM +0100, Jon Hunter wrote:
> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
> index 186c8cb..00adb98 100644
> --- a/arch/arm/kernel/perf_event.c
> +++ b/arch/arm/kernel/perf_event.c
> @@ -20,6 +20,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/spinlock.h>
>  #include <linux/uaccess.h>
> +#include <linux/pm_runtime.h>
>  
>  #include <asm/cputype.h>
>  #include <asm/irq.h>
> @@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>  {
>  	int i, irq, irqs;
>  	struct platform_device *pmu_device = armpmu->plat_device;
> -	struct arm_pmu_platdata *plat =
> -		dev_get_platdata(&pmu_device->dev);
>  
>  	irqs = min(pmu_device->num_resources, num_possible_cpus());
>  
> @@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>  		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
>  			continue;
>  		irq = platform_get_irq(pmu_device, i);
> -		if (irq >= 0) {
> -			if (plat && plat->disable_irq)
> -				plat->disable_irq(irq);
> +		if (irq >= 0)
>  			free_irq(irq, armpmu);
> -		}
>  	}
>  
>  	release_pmu(armpmu->type);
> +	pm_runtime_put_sync(&armpmu->plat_device->dev);

We probably want to suspend the device before releasing it, otherwise we
could race against somebody else trying to initialise the PMU again.

>  
>  static int
> @@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>  		return err;
>  	}
>  
> +	pm_runtime_get_sync(&armpmu->plat_device->dev);

Better pass &pmu_device->dev instead (similarly in release).

> +
>  	plat = dev_get_platdata(&pmu_device->dev);
>  	if (plat && plat->handle_irq)
>  		handle_irq = armpmu_platform_irq;
> @@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>  				irq);
>  			armpmu_release_hardware(armpmu);
>  			return err;
> -		} else if (plat && plat->enable_irq)
> -			plat->enable_irq(irq);
> +		}
>  
>  		cpumask_set_cpu(i, &armpmu->active_irqs);
>  	}
> @@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
>  	armpmu->stop();
>  }

There are potential failure paths in the reservation code here where we
don't `put' the PMU back. Can you move the pm_runtime_get_sync call later in
the function, or does it have to called before we enable the IRQ line?

> +#ifdef CONFIG_PM_RUNTIME
> +static int armpmu_runtime_resume(struct device *dev)
> +{
> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
> +
> +	if (plat->runtime_resume)

I think you need to check plat too since it may be NULL on other platforms.

> +		return plat->runtime_resume(dev);
> +
> +	return 0;
> +}
> +
> +static int armpmu_runtime_suspend(struct device *dev)
> +{
> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
> +
> +	if (plat->runtime_suspend)

Same here.

Will

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-08  9:47     ` Will Deacon
@ 2012-06-08 14:17       ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-08 14:17 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-omap, linux-arm, Ming Lei, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

Hi Will,

On 06/08/2012 04:47 AM, Will Deacon wrote:
> Hi Jon,
> 
> On Thu, Jun 07, 2012 at 10:22:03PM +0100, Jon Hunter wrote:
>> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
>> index 186c8cb..00adb98 100644
>> --- a/arch/arm/kernel/perf_event.c
>> +++ b/arch/arm/kernel/perf_event.c
>> @@ -20,6 +20,7 @@
>>  #include <linux/platform_device.h>
>>  #include <linux/spinlock.h>
>>  #include <linux/uaccess.h>
>> +#include <linux/pm_runtime.h>
>>  
>>  #include <asm/cputype.h>
>>  #include <asm/irq.h>
>> @@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>>  {
>>  	int i, irq, irqs;
>>  	struct platform_device *pmu_device = armpmu->plat_device;
>> -	struct arm_pmu_platdata *plat =
>> -		dev_get_platdata(&pmu_device->dev);
>>  
>>  	irqs = min(pmu_device->num_resources, num_possible_cpus());
>>  
>> @@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>>  		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
>>  			continue;
>>  		irq = platform_get_irq(pmu_device, i);
>> -		if (irq >= 0) {
>> -			if (plat && plat->disable_irq)
>> -				plat->disable_irq(irq);
>> +		if (irq >= 0)
>>  			free_irq(irq, armpmu);
>> -		}
>>  	}
>>  
>>  	release_pmu(armpmu->type);
>> +	pm_runtime_put_sync(&armpmu->plat_device->dev);
> 
> We probably want to suspend the device before releasing it, otherwise we
> could race against somebody else trying to initialise the PMU again.

Good point, will change that.

>>  
>>  static int
>> @@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>>  		return err;
>>  	}
>>  
>> +	pm_runtime_get_sync(&armpmu->plat_device->dev);
> 
> Better pass &pmu_device->dev instead (similarly in release).

Ok.

>> +
>>  	plat = dev_get_platdata(&pmu_device->dev);
>>  	if (plat && plat->handle_irq)
>>  		handle_irq = armpmu_platform_irq;
>> @@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>>  				irq);
>>  			armpmu_release_hardware(armpmu);
>>  			return err;
>> -		} else if (plat && plat->enable_irq)
>> -			plat->enable_irq(irq);
>> +		}
>>  
>>  		cpumask_set_cpu(i, &armpmu->active_irqs);
>>  	}
>> @@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
>>  	armpmu->stop();
>>  }
> 
> There are potential failure paths in the reservation code here where we
> don't `put' the PMU back. Can you move the pm_runtime_get_sync call later in
> the function, or does it have to called before we enable the IRQ line?

Yes we can move that. It does not need to be before we enable the IRQ line.

>> +#ifdef CONFIG_PM_RUNTIME
>> +static int armpmu_runtime_resume(struct device *dev)
>> +{
>> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> +	if (plat->runtime_resume)
> 
> I think you need to check plat too since it may be NULL on other platforms.

Ah, good point. I will add that.

>> +		return plat->runtime_resume(dev);
>> +
>> +	return 0;
>> +}
>> +
>> +static int armpmu_runtime_suspend(struct device *dev)
>> +{
>> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> +	if (plat->runtime_suspend)
> 
> Same here.

Ok, yes. Thanks for the feedback!

Cheers
Jon

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-08 14:17       ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-08 14:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 06/08/2012 04:47 AM, Will Deacon wrote:
> Hi Jon,
> 
> On Thu, Jun 07, 2012 at 10:22:03PM +0100, Jon Hunter wrote:
>> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
>> index 186c8cb..00adb98 100644
>> --- a/arch/arm/kernel/perf_event.c
>> +++ b/arch/arm/kernel/perf_event.c
>> @@ -20,6 +20,7 @@
>>  #include <linux/platform_device.h>
>>  #include <linux/spinlock.h>
>>  #include <linux/uaccess.h>
>> +#include <linux/pm_runtime.h>
>>  
>>  #include <asm/cputype.h>
>>  #include <asm/irq.h>
>> @@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>>  {
>>  	int i, irq, irqs;
>>  	struct platform_device *pmu_device = armpmu->plat_device;
>> -	struct arm_pmu_platdata *plat =
>> -		dev_get_platdata(&pmu_device->dev);
>>  
>>  	irqs = min(pmu_device->num_resources, num_possible_cpus());
>>  
>> @@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>>  		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
>>  			continue;
>>  		irq = platform_get_irq(pmu_device, i);
>> -		if (irq >= 0) {
>> -			if (plat && plat->disable_irq)
>> -				plat->disable_irq(irq);
>> +		if (irq >= 0)
>>  			free_irq(irq, armpmu);
>> -		}
>>  	}
>>  
>>  	release_pmu(armpmu->type);
>> +	pm_runtime_put_sync(&armpmu->plat_device->dev);
> 
> We probably want to suspend the device before releasing it, otherwise we
> could race against somebody else trying to initialise the PMU again.

Good point, will change that.

>>  
>>  static int
>> @@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>>  		return err;
>>  	}
>>  
>> +	pm_runtime_get_sync(&armpmu->plat_device->dev);
> 
> Better pass &pmu_device->dev instead (similarly in release).

Ok.

>> +
>>  	plat = dev_get_platdata(&pmu_device->dev);
>>  	if (plat && plat->handle_irq)
>>  		handle_irq = armpmu_platform_irq;
>> @@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>>  				irq);
>>  			armpmu_release_hardware(armpmu);
>>  			return err;
>> -		} else if (plat && plat->enable_irq)
>> -			plat->enable_irq(irq);
>> +		}
>>  
>>  		cpumask_set_cpu(i, &armpmu->active_irqs);
>>  	}
>> @@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
>>  	armpmu->stop();
>>  }
> 
> There are potential failure paths in the reservation code here where we
> don't `put' the PMU back. Can you move the pm_runtime_get_sync call later in
> the function, or does it have to called before we enable the IRQ line?

Yes we can move that. It does not need to be before we enable the IRQ line.

>> +#ifdef CONFIG_PM_RUNTIME
>> +static int armpmu_runtime_resume(struct device *dev)
>> +{
>> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> +	if (plat->runtime_resume)
> 
> I think you need to check plat too since it may be NULL on other platforms.

Ah, good point. I will add that.

>> +		return plat->runtime_resume(dev);
>> +
>> +	return 0;
>> +}
>> +
>> +static int armpmu_runtime_suspend(struct device *dev)
>> +{
>> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> +	if (plat->runtime_suspend)
> 
> Same here.

Ok, yes. Thanks for the feedback!

Cheers
Jon

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-08  9:47     ` Will Deacon
@ 2012-06-08 15:24       ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-08 15:24 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-omap, linux-arm, Ming Lei, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

Hi Will,

On 06/08/2012 04:47 AM, Will Deacon wrote:
> Hi Jon,
> 
> On Thu, Jun 07, 2012 at 10:22:03PM +0100, Jon Hunter wrote:
>> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
>> index 186c8cb..00adb98 100644
>> --- a/arch/arm/kernel/perf_event.c
>> +++ b/arch/arm/kernel/perf_event.c
>> @@ -20,6 +20,7 @@
>>  #include <linux/platform_device.h>
>>  #include <linux/spinlock.h>
>>  #include <linux/uaccess.h>
>> +#include <linux/pm_runtime.h>
>>  
>>  #include <asm/cputype.h>
>>  #include <asm/irq.h>
>> @@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>>  {
>>  	int i, irq, irqs;
>>  	struct platform_device *pmu_device = armpmu->plat_device;
>> -	struct arm_pmu_platdata *plat =
>> -		dev_get_platdata(&pmu_device->dev);
>>  
>>  	irqs = min(pmu_device->num_resources, num_possible_cpus());
>>  
>> @@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>>  		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
>>  			continue;
>>  		irq = platform_get_irq(pmu_device, i);
>> -		if (irq >= 0) {
>> -			if (plat && plat->disable_irq)
>> -				plat->disable_irq(irq);
>> +		if (irq >= 0)
>>  			free_irq(irq, armpmu);
>> -		}
>>  	}
>>  
>>  	release_pmu(armpmu->type);
>> +	pm_runtime_put_sync(&armpmu->plat_device->dev);
> 
> We probably want to suspend the device before releasing it, otherwise we
> could race against somebody else trying to initialise the PMU again.
> 
>>  
>>  static int
>> @@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>>  		return err;
>>  	}
>>  
>> +	pm_runtime_get_sync(&armpmu->plat_device->dev);
> 
> Better pass &pmu_device->dev instead (similarly in release).
> 
>> +
>>  	plat = dev_get_platdata(&pmu_device->dev);
>>  	if (plat && plat->handle_irq)
>>  		handle_irq = armpmu_platform_irq;
>> @@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>>  				irq);
>>  			armpmu_release_hardware(armpmu);
>>  			return err;
>> -		} else if (plat && plat->enable_irq)
>> -			plat->enable_irq(irq);
>> +		}
>>  
>>  		cpumask_set_cpu(i, &armpmu->active_irqs);
>>  	}
>> @@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
>>  	armpmu->stop();
>>  }
> 
> There are potential failure paths in the reservation code here where we
> don't `put' the PMU back. Can you move the pm_runtime_get_sync call later in
> the function, or does it have to called before we enable the IRQ line?
> 
>> +#ifdef CONFIG_PM_RUNTIME
>> +static int armpmu_runtime_resume(struct device *dev)
>> +{
>> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> +	if (plat->runtime_resume)
> 
> I think you need to check plat too since it may be NULL on other platforms.
> 
>> +		return plat->runtime_resume(dev);
>> +
>> +	return 0;
>> +}
>> +
>> +static int armpmu_runtime_suspend(struct device *dev)
>> +{
>> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> +	if (plat->runtime_suspend)
> 
> Same here.

Here is an updated version. I was going to send out a V3, but I wanted
to wait to see if others had more comments first.

Cheers
Jon

>From c53dcbe091928d293f14e890c2b38be57692ccca Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Thu, 31 May 2012 13:05:20 -0500
Subject: [PATCH] ARM: PMU: Add runtime PM Support

Add runtime PM support to the ARM PMU driver so that devices such as OMAP
supporting dynamic PM can use the platform->runtime_* hooks to initialise
hardware at runtime. Without having these runtime PM hooks in place any
configuration of the PMU hardware would be lost when low power states are
entered and hence would prevent PMU from working.

This change also replaces the PMU platform functions enable_irq and disable_irq
added by Ming Lei with runtime_resume and runtime_suspend funtions. Ming had
added the enable_irq and disable_irq functions as a method to configure the
cross trigger interface on OMAP4 for routing the PMU interrupts. By adding
runtime PM support, we can move the code called by enable_irq and disable_irq
into the runtime PM callbacks runtime_resume and runtime_suspend.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/include/asm/pmu.h   |   20 ++++++++++++--------
 arch/arm/kernel/perf_event.c |   41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 90114fa..77b023b 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -31,18 +31,22 @@ enum arm_pmu_type {
  *	interrupt and passed the address of the low level handler,
  *	and can be used to implement any platform specific handling
  *	before or after calling it.
- * @enable_irq: an optional handler which will be called after
- *	request_irq and be used to handle some platform specific
- *	irq enablement
- * @disable_irq: an optional handler which will be called before
- *	free_irq and be used to handle some platform specific
- *	irq disablement
+ * @runtime_resume: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_get().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called once.
+ * @runtime_suspend: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_put().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called following the
+ *	final call to pm_runtime_put() that actually disables the
+ *	hardware.
  */
 struct arm_pmu_platdata {
 	irqreturn_t (*handle_irq)(int irq, void *dev,
 				  irq_handler_t pmu_handler);
-	void (*enable_irq)(int irq);
-	void (*disable_irq)(int irq);
+	int (*runtime_resume)(struct device *dev);
+	int (*runtime_suspend)(struct device *dev);
 };
 
 #ifdef CONFIG_CPU_HAS_PMU
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 186c8cb..2878651 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 {
 	int i, irq, irqs;
 	struct platform_device *pmu_device = armpmu->plat_device;
-	struct arm_pmu_platdata *plat =
-		dev_get_platdata(&pmu_device->dev);
 
 	irqs = min(pmu_device->num_resources, num_possible_cpus());
 
@@ -376,13 +375,11 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
 			continue;
 		irq = platform_get_irq(pmu_device, i);
-		if (irq >= 0) {
-			if (plat && plat->disable_irq)
-				plat->disable_irq(irq);
+		if (irq >= 0)
 			free_irq(irq, armpmu);
-		}
 	}
 
+	pm_runtime_put_sync(&pmu_device->dev);
 	release_pmu(armpmu->type);
 }
 
@@ -415,6 +412,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 		return -ENODEV;
 	}
 
+	pm_runtime_get_sync(&pmu_device->dev);
+
 	for (i = 0; i < irqs; ++i) {
 		err = 0;
 		irq = platform_get_irq(pmu_device, i);
@@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 				irq);
 			armpmu_release_hardware(armpmu);
 			return err;
-		} else if (plat && plat->enable_irq)
-			plat->enable_irq(irq);
+		}
 
 		cpumask_set_cpu(i, &armpmu->active_irqs);
 	}
@@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
 	armpmu->stop();
 }
 
+#ifdef CONFIG_PM_RUNTIME
+static int armpmu_runtime_resume(struct device *dev)
+{
+	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+	if (plat && plat->runtime_resume)
+		return plat->runtime_resume(dev);
+
+	return 0;
+}
+
+static int armpmu_runtime_suspend(struct device *dev)
+{
+	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+	if (plat && plat->runtime_suspend)
+		return plat->runtime_suspend(dev);
+
+	return 0;
+}
+#endif
+
 static void __init armpmu_init(struct arm_pmu *armpmu)
 {
 	atomic_set(&armpmu->active_events, 0);
@@ -650,9 +670,14 @@ static int __devinit armpmu_device_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct dev_pm_ops armpmu_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
+};
+
 static struct platform_driver armpmu_driver = {
 	.driver		= {
 		.name	= "arm-pmu",
+		.pm	= &armpmu_dev_pm_ops,
 		.of_match_table = armpmu_of_device_ids,
 	},
 	.probe		= armpmu_device_probe,
-- 
1.7.9.5


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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-08 15:24       ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-08 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 06/08/2012 04:47 AM, Will Deacon wrote:
> Hi Jon,
> 
> On Thu, Jun 07, 2012 at 10:22:03PM +0100, Jon Hunter wrote:
>> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
>> index 186c8cb..00adb98 100644
>> --- a/arch/arm/kernel/perf_event.c
>> +++ b/arch/arm/kernel/perf_event.c
>> @@ -20,6 +20,7 @@
>>  #include <linux/platform_device.h>
>>  #include <linux/spinlock.h>
>>  #include <linux/uaccess.h>
>> +#include <linux/pm_runtime.h>
>>  
>>  #include <asm/cputype.h>
>>  #include <asm/irq.h>
>> @@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>>  {
>>  	int i, irq, irqs;
>>  	struct platform_device *pmu_device = armpmu->plat_device;
>> -	struct arm_pmu_platdata *plat =
>> -		dev_get_platdata(&pmu_device->dev);
>>  
>>  	irqs = min(pmu_device->num_resources, num_possible_cpus());
>>  
>> @@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>>  		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
>>  			continue;
>>  		irq = platform_get_irq(pmu_device, i);
>> -		if (irq >= 0) {
>> -			if (plat && plat->disable_irq)
>> -				plat->disable_irq(irq);
>> +		if (irq >= 0)
>>  			free_irq(irq, armpmu);
>> -		}
>>  	}
>>  
>>  	release_pmu(armpmu->type);
>> +	pm_runtime_put_sync(&armpmu->plat_device->dev);
> 
> We probably want to suspend the device before releasing it, otherwise we
> could race against somebody else trying to initialise the PMU again.
> 
>>  
>>  static int
>> @@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>>  		return err;
>>  	}
>>  
>> +	pm_runtime_get_sync(&armpmu->plat_device->dev);
> 
> Better pass &pmu_device->dev instead (similarly in release).
> 
>> +
>>  	plat = dev_get_platdata(&pmu_device->dev);
>>  	if (plat && plat->handle_irq)
>>  		handle_irq = armpmu_platform_irq;
>> @@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>>  				irq);
>>  			armpmu_release_hardware(armpmu);
>>  			return err;
>> -		} else if (plat && plat->enable_irq)
>> -			plat->enable_irq(irq);
>> +		}
>>  
>>  		cpumask_set_cpu(i, &armpmu->active_irqs);
>>  	}
>> @@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
>>  	armpmu->stop();
>>  }
> 
> There are potential failure paths in the reservation code here where we
> don't `put' the PMU back. Can you move the pm_runtime_get_sync call later in
> the function, or does it have to called before we enable the IRQ line?
> 
>> +#ifdef CONFIG_PM_RUNTIME
>> +static int armpmu_runtime_resume(struct device *dev)
>> +{
>> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> +	if (plat->runtime_resume)
> 
> I think you need to check plat too since it may be NULL on other platforms.
> 
>> +		return plat->runtime_resume(dev);
>> +
>> +	return 0;
>> +}
>> +
>> +static int armpmu_runtime_suspend(struct device *dev)
>> +{
>> +	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> +	if (plat->runtime_suspend)
> 
> Same here.

Here is an updated version. I was going to send out a V3, but I wanted
to wait to see if others had more comments first.

Cheers
Jon

>From c53dcbe091928d293f14e890c2b38be57692ccca Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Thu, 31 May 2012 13:05:20 -0500
Subject: [PATCH] ARM: PMU: Add runtime PM Support

Add runtime PM support to the ARM PMU driver so that devices such as OMAP
supporting dynamic PM can use the platform->runtime_* hooks to initialise
hardware at runtime. Without having these runtime PM hooks in place any
configuration of the PMU hardware would be lost when low power states are
entered and hence would prevent PMU from working.

This change also replaces the PMU platform functions enable_irq and disable_irq
added by Ming Lei with runtime_resume and runtime_suspend funtions. Ming had
added the enable_irq and disable_irq functions as a method to configure the
cross trigger interface on OMAP4 for routing the PMU interrupts. By adding
runtime PM support, we can move the code called by enable_irq and disable_irq
into the runtime PM callbacks runtime_resume and runtime_suspend.

Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/include/asm/pmu.h   |   20 ++++++++++++--------
 arch/arm/kernel/perf_event.c |   41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 90114fa..77b023b 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -31,18 +31,22 @@ enum arm_pmu_type {
  *	interrupt and passed the address of the low level handler,
  *	and can be used to implement any platform specific handling
  *	before or after calling it.
- * @enable_irq: an optional handler which will be called after
- *	request_irq and be used to handle some platform specific
- *	irq enablement
- * @disable_irq: an optional handler which will be called before
- *	free_irq and be used to handle some platform specific
- *	irq disablement
+ * @runtime_resume: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_get().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called once.
+ * @runtime_suspend: an optional handler which will be called by the
+ *	runtime PM framework following a call to pm_runtime_put().
+ *	Note that if pm_runtime_get() is called more than once in
+ *	succession this handler will only be called following the
+ *	final call to pm_runtime_put() that actually disables the
+ *	hardware.
  */
 struct arm_pmu_platdata {
 	irqreturn_t (*handle_irq)(int irq, void *dev,
 				  irq_handler_t pmu_handler);
-	void (*enable_irq)(int irq);
-	void (*disable_irq)(int irq);
+	int (*runtime_resume)(struct device *dev);
+	int (*runtime_suspend)(struct device *dev);
 };
 
 #ifdef CONFIG_CPU_HAS_PMU
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 186c8cb..2878651 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
 
 #include <asm/cputype.h>
 #include <asm/irq.h>
@@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 {
 	int i, irq, irqs;
 	struct platform_device *pmu_device = armpmu->plat_device;
-	struct arm_pmu_platdata *plat =
-		dev_get_platdata(&pmu_device->dev);
 
 	irqs = min(pmu_device->num_resources, num_possible_cpus());
 
@@ -376,13 +375,11 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
 		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
 			continue;
 		irq = platform_get_irq(pmu_device, i);
-		if (irq >= 0) {
-			if (plat && plat->disable_irq)
-				plat->disable_irq(irq);
+		if (irq >= 0)
 			free_irq(irq, armpmu);
-		}
 	}
 
+	pm_runtime_put_sync(&pmu_device->dev);
 	release_pmu(armpmu->type);
 }
 
@@ -415,6 +412,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 		return -ENODEV;
 	}
 
+	pm_runtime_get_sync(&pmu_device->dev);
+
 	for (i = 0; i < irqs; ++i) {
 		err = 0;
 		irq = platform_get_irq(pmu_device, i);
@@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
 				irq);
 			armpmu_release_hardware(armpmu);
 			return err;
-		} else if (plat && plat->enable_irq)
-			plat->enable_irq(irq);
+		}
 
 		cpumask_set_cpu(i, &armpmu->active_irqs);
 	}
@@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
 	armpmu->stop();
 }
 
+#ifdef CONFIG_PM_RUNTIME
+static int armpmu_runtime_resume(struct device *dev)
+{
+	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+	if (plat && plat->runtime_resume)
+		return plat->runtime_resume(dev);
+
+	return 0;
+}
+
+static int armpmu_runtime_suspend(struct device *dev)
+{
+	struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+	if (plat && plat->runtime_suspend)
+		return plat->runtime_suspend(dev);
+
+	return 0;
+}
+#endif
+
 static void __init armpmu_init(struct arm_pmu *armpmu)
 {
 	atomic_set(&armpmu->active_events, 0);
@@ -650,9 +670,14 @@ static int __devinit armpmu_device_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct dev_pm_ops armpmu_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
+};
+
 static struct platform_driver armpmu_driver = {
 	.driver		= {
 		.name	= "arm-pmu",
+		.pm	= &armpmu_dev_pm_ops,
 		.of_match_table = armpmu_of_device_ids,
 	},
 	.probe		= armpmu_device_probe,
-- 
1.7.9.5

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-08 15:24       ` Jon Hunter
@ 2012-06-11 17:39         ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-06-11 17:39 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Ming Lei, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

On Fri, Jun 08, 2012 at 04:24:32PM +0100, Jon Hunter wrote:
> Hi Will,

Hi Jon,

> Here is an updated version. I was going to send out a V3, but I wanted
> to wait to see if others had more comments first.

This looks better to me, so I took it for a spin on my 4460 (thanks Nicolas!)
and noticed that only the cycle counter seems to tick -- the event counters
always return 0 deltas (that is, they don't increment). Booting the same SD
card on a 4430 (same MLO, u-boot, kernel and filesystem) I see that the
event counters function correctly there.

It also seems that we can remove the dependency on CONFIG_OMAP3_EMU with these
patches but I don't have any OMAP3 hardware to check if we get any regressions
on older platforms. Do your patches only deal with OMAP4?

Cheers,

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-11 17:39         ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-06-11 17:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 08, 2012 at 04:24:32PM +0100, Jon Hunter wrote:
> Hi Will,

Hi Jon,

> Here is an updated version. I was going to send out a V3, but I wanted
> to wait to see if others had more comments first.

This looks better to me, so I took it for a spin on my 4460 (thanks Nicolas!)
and noticed that only the cycle counter seems to tick -- the event counters
always return 0 deltas (that is, they don't increment). Booting the same SD
card on a 4430 (same MLO, u-boot, kernel and filesystem) I see that the
event counters function correctly there.

It also seems that we can remove the dependency on CONFIG_OMAP3_EMU with these
patches but I don't have any OMAP3 hardware to check if we get any regressions
on older platforms. Do your patches only deal with OMAP4?

Cheers,

Will

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-11 17:39         ` Will Deacon
@ 2012-06-11 19:01           ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-11 19:01 UTC (permalink / raw)
  To: Will Deacon
  Cc: linux-omap, linux-arm, Ming Lei, Benoit Cousson, Paul Walmsley,
	Kevin Hilman

Hi Will,

On 06/11/2012 12:39 PM, Will Deacon wrote:
> On Fri, Jun 08, 2012 at 04:24:32PM +0100, Jon Hunter wrote:
>> Hi Will,
> 
> Hi Jon,
> 
>> Here is an updated version. I was going to send out a V3, but I wanted
>> to wait to see if others had more comments first.
> 
> This looks better to me, so I took it for a spin on my 4460 (thanks Nicolas!)
> and noticed that only the cycle counter seems to tick -- the event counters
> always return 0 deltas (that is, they don't increment). Booting the same SD
> card on a 4430 (same MLO, u-boot, kernel and filesystem) I see that the
> event counters function correctly there.

Thanks for the feedback. Being somewhat new to PMU, I was mainly using
PERF to test and verify that with "perf top" I was seeing interrupts.
How do I check what the event counters are returning? Any perf tests I
could use?

By the way, as a quick test you could modify the code in omap_init_pmu()
to call omap4430_init_pmu() for all omap4 devices as follows ...

	if (cpu_is_omap44xx())
 		return omap4430_init_pmu();

I was hoping for 4460/70 we would not need to keep the debugss and other
domains on and hence, I called the above function omap4430_init_pmu().
However this function works for all omap4 devices, it just turns on more
power domains.

> It also seems that we can remove the dependency on CONFIG_OMAP3_EMU with these
> patches but I don't have any OMAP3 hardware to check if we get any regressions
> on older platforms. Do your patches only deal with OMAP4?

It *should* work for all omap2+. So far I have tested an omap3 beagle
but I have not tested an omap2 device. Again the extent of my testing
was to run "perf top" and verify interrupts we being generated. I
realise that this may not be sufficient and so if you have a more
exhaustive test you recommend let me know.

Cheers
Jon


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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-11 19:01           ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-11 19:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 06/11/2012 12:39 PM, Will Deacon wrote:
> On Fri, Jun 08, 2012 at 04:24:32PM +0100, Jon Hunter wrote:
>> Hi Will,
> 
> Hi Jon,
> 
>> Here is an updated version. I was going to send out a V3, but I wanted
>> to wait to see if others had more comments first.
> 
> This looks better to me, so I took it for a spin on my 4460 (thanks Nicolas!)
> and noticed that only the cycle counter seems to tick -- the event counters
> always return 0 deltas (that is, they don't increment). Booting the same SD
> card on a 4430 (same MLO, u-boot, kernel and filesystem) I see that the
> event counters function correctly there.

Thanks for the feedback. Being somewhat new to PMU, I was mainly using
PERF to test and verify that with "perf top" I was seeing interrupts.
How do I check what the event counters are returning? Any perf tests I
could use?

By the way, as a quick test you could modify the code in omap_init_pmu()
to call omap4430_init_pmu() for all omap4 devices as follows ...

	if (cpu_is_omap44xx())
 		return omap4430_init_pmu();

I was hoping for 4460/70 we would not need to keep the debugss and other
domains on and hence, I called the above function omap4430_init_pmu().
However this function works for all omap4 devices, it just turns on more
power domains.

> It also seems that we can remove the dependency on CONFIG_OMAP3_EMU with these
> patches but I don't have any OMAP3 hardware to check if we get any regressions
> on older platforms. Do your patches only deal with OMAP4?

It *should* work for all omap2+. So far I have tested an omap3 beagle
but I have not tested an omap2 device. Again the extent of my testing
was to run "perf top" and verify interrupts we being generated. I
realise that this may not be sufficient and so if you have a more
exhaustive test you recommend let me know.

Cheers
Jon

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-11 19:01           ` Jon Hunter
@ 2012-06-12  9:28             ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-06-12  9:28 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

On Mon, Jun 11, 2012 at 08:01:23PM +0100, Jon Hunter wrote:
> Hi Will,

Hello,

> On 06/11/2012 12:39 PM, Will Deacon wrote:
> > This looks better to me, so I took it for a spin on my 4460 (thanks Nicolas!)
> > and noticed that only the cycle counter seems to tick -- the event counters
> > always return 0 deltas (that is, they don't increment). Booting the same SD
> > card on a 4430 (same MLO, u-boot, kernel and filesystem) I see that the
> > event counters function correctly there.
> 
> Thanks for the feedback. Being somewhat new to PMU, I was mainly using
> PERF to test and verify that with "perf top" I was seeing interrupts.
> How do I check what the event counters are returning? Any perf tests I
> could use?

You can continue to use perf top, just specify an event other than cycles:

# perf top -e instructions

for example. You can also use perf stat, but that probably won't be
triggering irqs.

> By the way, as a quick test you could modify the code in omap_init_pmu()
> to call omap4430_init_pmu() for all omap4 devices as follows ...
> 
> 	if (cpu_is_omap44xx())
>  		return omap4430_init_pmu();
> 
> I was hoping for 4460/70 we would not need to keep the debugss and other
> domains on and hence, I called the above function omap4430_init_pmu().
> However this function works for all omap4 devices, it just turns on more
> power domains.

Well, I tried that and the results are pretty whacky: the event counters do
indeed tick but interrupts only fire if I pin the perf task to CPU1! What's
more, the interrupts do fire on both cores when they're working...

Without the above change, I can generate cycle counter interrupts regardless
of which CPU I run execute perf.

> > It also seems that we can remove the dependency on CONFIG_OMAP3_EMU with these
> > patches but I don't have any OMAP3 hardware to check if we get any regressions
> > on older platforms. Do your patches only deal with OMAP4?
> 
> It *should* work for all omap2+. So far I have tested an omap3 beagle
> but I have not tested an omap2 device. Again the extent of my testing
> was to run "perf top" and verify interrupts we being generated. I
> realise that this may not be sufficient and so if you have a more
> exhaustive test you recommend let me know.

Well, try the above as well as what you're currently doing and that should
test the basics. If that works, I'll happily drop the Kconfig dependency on
OMAP3_EMU (which has been a regular source of confusion).

Cheers,

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-12  9:28             ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-06-12  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 11, 2012 at 08:01:23PM +0100, Jon Hunter wrote:
> Hi Will,

Hello,

> On 06/11/2012 12:39 PM, Will Deacon wrote:
> > This looks better to me, so I took it for a spin on my 4460 (thanks Nicolas!)
> > and noticed that only the cycle counter seems to tick -- the event counters
> > always return 0 deltas (that is, they don't increment). Booting the same SD
> > card on a 4430 (same MLO, u-boot, kernel and filesystem) I see that the
> > event counters function correctly there.
> 
> Thanks for the feedback. Being somewhat new to PMU, I was mainly using
> PERF to test and verify that with "perf top" I was seeing interrupts.
> How do I check what the event counters are returning? Any perf tests I
> could use?

You can continue to use perf top, just specify an event other than cycles:

# perf top -e instructions

for example. You can also use perf stat, but that probably won't be
triggering irqs.

> By the way, as a quick test you could modify the code in omap_init_pmu()
> to call omap4430_init_pmu() for all omap4 devices as follows ...
> 
> 	if (cpu_is_omap44xx())
>  		return omap4430_init_pmu();
> 
> I was hoping for 4460/70 we would not need to keep the debugss and other
> domains on and hence, I called the above function omap4430_init_pmu().
> However this function works for all omap4 devices, it just turns on more
> power domains.

Well, I tried that and the results are pretty whacky: the event counters do
indeed tick but interrupts only fire if I pin the perf task to CPU1! What's
more, the interrupts do fire on both cores when they're working...

Without the above change, I can generate cycle counter interrupts regardless
of which CPU I run execute perf.

> > It also seems that we can remove the dependency on CONFIG_OMAP3_EMU with these
> > patches but I don't have any OMAP3 hardware to check if we get any regressions
> > on older platforms. Do your patches only deal with OMAP4?
> 
> It *should* work for all omap2+. So far I have tested an omap3 beagle
> but I have not tested an omap2 device. Again the extent of my testing
> was to run "perf top" and verify interrupts we being generated. I
> realise that this may not be sufficient and so if you have a more
> exhaustive test you recommend let me know.

Well, try the above as well as what you're currently doing and that should
test the basics. If that works, I'll happily drop the Kconfig dependency on
OMAP3_EMU (which has been a regular source of confusion).

Cheers,

Will

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-12  9:28             ` Will Deacon
@ 2012-06-12 21:17               ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-12 21:17 UTC (permalink / raw)
  To: Will Deacon
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

Hi Will,

On 06/12/2012 04:28 AM, Will Deacon wrote:
> On Mon, Jun 11, 2012 at 08:01:23PM +0100, Jon Hunter wrote:
>> Hi Will,
> 
> Hello,
> 
>> On 06/11/2012 12:39 PM, Will Deacon wrote:
>>> This looks better to me, so I took it for a spin on my 4460 (thanks Nicolas!)
>>> and noticed that only the cycle counter seems to tick -- the event counters
>>> always return 0 deltas (that is, they don't increment). Booting the same SD
>>> card on a 4430 (same MLO, u-boot, kernel and filesystem) I see that the
>>> event counters function correctly there.
>>
>> Thanks for the feedback. Being somewhat new to PMU, I was mainly using
>> PERF to test and verify that with "perf top" I was seeing interrupts.
>> How do I check what the event counters are returning? Any perf tests I
>> could use?
> 
> You can continue to use perf top, just specify an event other than cycles:
> 
> # perf top -e instructions
> 
> for example. You can also use perf stat, but that probably won't be
> triggering irqs.
> 
>> By the way, as a quick test you could modify the code in omap_init_pmu()
>> to call omap4430_init_pmu() for all omap4 devices as follows ...
>>
>> 	if (cpu_is_omap44xx())
>>  		return omap4430_init_pmu();
>>
>> I was hoping for 4460/70 we would not need to keep the debugss and other
>> domains on and hence, I called the above function omap4430_init_pmu().
>> However this function works for all omap4 devices, it just turns on more
>> power domains.
> 
> Well, I tried that and the results are pretty whacky: the event counters do
> indeed tick but interrupts only fire if I pin the perf task to CPU1! What's
> more, the interrupts do fire on both cores when they're working...

I tried this, and I see that interrupts occur on both, however, it seems
that the majority occur on one CPU and only a few on the other. So it
does appear that one CPU is getting a lot more interrupts.

> Without the above change, I can generate cycle counter interrupts regardless
> of which CPU I run execute perf.

Yes, I see this to. From more testing, I see that as soon as I turn off
the debugss clock domain "perf top -e instructions" stops working. So I
assume that the event counters are returning 0 in this case.

>From a PMU programming standpoint, if we just use "perf top" are the
event counters not used/programmed?

And when we use "perf top -e instructions" is it the "software
increment" event that the event counter(s) are monitoring? I am just
trying to understand how the counters are being programmed and then I
can ask the design folks an intelligent question :-)

By the way, I don't suppose there is any debugfs entry to dump the PMU
registers?

>>> It also seems that we can remove the dependency on CONFIG_OMAP3_EMU with these
>>> patches but I don't have any OMAP3 hardware to check if we get any regressions
>>> on older platforms. Do your patches only deal with OMAP4?
>>
>> It *should* work for all omap2+. So far I have tested an omap3 beagle
>> but I have not tested an omap2 device. Again the extent of my testing
>> was to run "perf top" and verify interrupts we being generated. I
>> realise that this may not be sufficient and so if you have a more
>> exhaustive test you recommend let me know.
> 
> Well, try the above as well as what you're currently doing and that should
> test the basics. If that works, I'll happily drop the Kconfig dependency on
> OMAP3_EMU (which has been a regular source of confusion).

I still think that there is something I need to understand better here.

Cheers
Jon

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-12 21:17               ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-12 21:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 06/12/2012 04:28 AM, Will Deacon wrote:
> On Mon, Jun 11, 2012 at 08:01:23PM +0100, Jon Hunter wrote:
>> Hi Will,
> 
> Hello,
> 
>> On 06/11/2012 12:39 PM, Will Deacon wrote:
>>> This looks better to me, so I took it for a spin on my 4460 (thanks Nicolas!)
>>> and noticed that only the cycle counter seems to tick -- the event counters
>>> always return 0 deltas (that is, they don't increment). Booting the same SD
>>> card on a 4430 (same MLO, u-boot, kernel and filesystem) I see that the
>>> event counters function correctly there.
>>
>> Thanks for the feedback. Being somewhat new to PMU, I was mainly using
>> PERF to test and verify that with "perf top" I was seeing interrupts.
>> How do I check what the event counters are returning? Any perf tests I
>> could use?
> 
> You can continue to use perf top, just specify an event other than cycles:
> 
> # perf top -e instructions
> 
> for example. You can also use perf stat, but that probably won't be
> triggering irqs.
> 
>> By the way, as a quick test you could modify the code in omap_init_pmu()
>> to call omap4430_init_pmu() for all omap4 devices as follows ...
>>
>> 	if (cpu_is_omap44xx())
>>  		return omap4430_init_pmu();
>>
>> I was hoping for 4460/70 we would not need to keep the debugss and other
>> domains on and hence, I called the above function omap4430_init_pmu().
>> However this function works for all omap4 devices, it just turns on more
>> power domains.
> 
> Well, I tried that and the results are pretty whacky: the event counters do
> indeed tick but interrupts only fire if I pin the perf task to CPU1! What's
> more, the interrupts do fire on both cores when they're working...

I tried this, and I see that interrupts occur on both, however, it seems
that the majority occur on one CPU and only a few on the other. So it
does appear that one CPU is getting a lot more interrupts.

> Without the above change, I can generate cycle counter interrupts regardless
> of which CPU I run execute perf.

Yes, I see this to. From more testing, I see that as soon as I turn off
the debugss clock domain "perf top -e instructions" stops working. So I
assume that the event counters are returning 0 in this case.

>From a PMU programming standpoint, if we just use "perf top" are the
event counters not used/programmed?

And when we use "perf top -e instructions" is it the "software
increment" event that the event counter(s) are monitoring? I am just
trying to understand how the counters are being programmed and then I
can ask the design folks an intelligent question :-)

By the way, I don't suppose there is any debugfs entry to dump the PMU
registers?

>>> It also seems that we can remove the dependency on CONFIG_OMAP3_EMU with these
>>> patches but I don't have any OMAP3 hardware to check if we get any regressions
>>> on older platforms. Do your patches only deal with OMAP4?
>>
>> It *should* work for all omap2+. So far I have tested an omap3 beagle
>> but I have not tested an omap2 device. Again the extent of my testing
>> was to run "perf top" and verify interrupts we being generated. I
>> realise that this may not be sufficient and so if you have a more
>> exhaustive test you recommend let me know.
> 
> Well, try the above as well as what you're currently doing and that should
> test the basics. If that works, I'll happily drop the Kconfig dependency on
> OMAP3_EMU (which has been a regular source of confusion).

I still think that there is something I need to understand better here.

Cheers
Jon

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-12 21:17               ` Jon Hunter
@ 2012-06-12 21:31                 ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-06-12 21:31 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

On Tue, Jun 12, 2012 at 10:17:16PM +0100, Jon Hunter wrote:
> Hi Will,

Hi Jon,

> On 06/12/2012 04:28 AM, Will Deacon wrote:
> > 
> > Well, I tried that and the results are pretty whacky: the event counters do
> > indeed tick but interrupts only fire if I pin the perf task to CPU1! What's
> > more, the interrupts do fire on both cores when they're working...
> 
> I tried this, and I see that interrupts occur on both, however, it seems
> that the majority occur on one CPU and only a few on the other. So it
> does appear that one CPU is getting a lot more interrupts.

That's understandable -- one of the CPUs is likely more loaded than the
other. However, I'd like to confirm whether or not you see what I see. With
the 4430_init hack on a 4460, if I run:

# taskset 0x2 perf top

then I get no samples. If I do:

# taskset 0x1 perf top

then I *do* get samples and from *both* CPUs. So it smells more like an
issue poking some configuration registers from CPU1 rather than the IRQ
path being broken. As I said before, if I don't do the extra init hack
then I don't get this problem (but event counters don't tick).

> From a PMU programming standpoint, if we just use "perf top" are the
> event counters not used/programmed?

Just using perf top should use the cycle counter as the event source.

> And when we use "perf top -e instructions" is it the "software
> increment" event that the event counter(s) are monitoring? I am just
> trying to understand how the counters are being programmed and then I
> can ask the design folks an intelligent question :-)

It depends on the CPU. For Cortex-A9, `instructions' maps to event 0x68,
which isn't a perfect match. If you want to specify a hex value for the
event code, you can do:

# perf top -e rNN

where NN is the hex event number. On A9, r11 would give you cycles via
an event counter.

> By the way, I don't suppose there is any debugfs entry to dump the PMU
> registers?

'fraid not, but there is some debug code in perf_event_v7.c that you
could call if you wanted to (just #define DEBUG at the top of the file).

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-12 21:31                 ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-06-12 21:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 12, 2012 at 10:17:16PM +0100, Jon Hunter wrote:
> Hi Will,

Hi Jon,

> On 06/12/2012 04:28 AM, Will Deacon wrote:
> > 
> > Well, I tried that and the results are pretty whacky: the event counters do
> > indeed tick but interrupts only fire if I pin the perf task to CPU1! What's
> > more, the interrupts do fire on both cores when they're working...
> 
> I tried this, and I see that interrupts occur on both, however, it seems
> that the majority occur on one CPU and only a few on the other. So it
> does appear that one CPU is getting a lot more interrupts.

That's understandable -- one of the CPUs is likely more loaded than the
other. However, I'd like to confirm whether or not you see what I see. With
the 4430_init hack on a 4460, if I run:

# taskset 0x2 perf top

then I get no samples. If I do:

# taskset 0x1 perf top

then I *do* get samples and from *both* CPUs. So it smells more like an
issue poking some configuration registers from CPU1 rather than the IRQ
path being broken. As I said before, if I don't do the extra init hack
then I don't get this problem (but event counters don't tick).

> From a PMU programming standpoint, if we just use "perf top" are the
> event counters not used/programmed?

Just using perf top should use the cycle counter as the event source.

> And when we use "perf top -e instructions" is it the "software
> increment" event that the event counter(s) are monitoring? I am just
> trying to understand how the counters are being programmed and then I
> can ask the design folks an intelligent question :-)

It depends on the CPU. For Cortex-A9, `instructions' maps to event 0x68,
which isn't a perfect match. If you want to specify a hex value for the
event code, you can do:

# perf top -e rNN

where NN is the hex event number. On A9, r11 would give you cycles via
an event counter.

> By the way, I don't suppose there is any debugfs entry to dump the PMU
> registers?

'fraid not, but there is some debug code in perf_event_v7.c that you
could call if you wanted to (just #define DEBUG at the top of the file).

Will

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-12 21:31                 ` Will Deacon
@ 2012-06-12 22:41                   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-12 22:41 UTC (permalink / raw)
  To: Will Deacon
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm


On 06/12/2012 04:31 PM, Will Deacon wrote:
> On Tue, Jun 12, 2012 at 10:17:16PM +0100, Jon Hunter wrote:
>> Hi Will,
> 
> Hi Jon,
> 
>> On 06/12/2012 04:28 AM, Will Deacon wrote:
>>>
>>> Well, I tried that and the results are pretty whacky: the event counters do
>>> indeed tick but interrupts only fire if I pin the perf task to CPU1! What's
>>> more, the interrupts do fire on both cores when they're working...
>>
>> I tried this, and I see that interrupts occur on both, however, it seems
>> that the majority occur on one CPU and only a few on the other. So it
>> does appear that one CPU is getting a lot more interrupts.
> 
> That's understandable -- one of the CPUs is likely more loaded than the
> other. However, I'd like to confirm whether or not you see what I see. With
> the 4430_init hack on a 4460, if I run:
> 
> # taskset 0x2 perf top
> 
> then I get no samples. If I do:
> 
> # taskset 0x1 perf top
> 
> then I *do* get samples and from *both* CPUs. So it smells more like an
> issue poking some configuration registers from CPU1 rather than the IRQ
> path being broken. As I said before, if I don't do the extra init hack
> then I don't get this problem (but event counters don't tick).

In both cases, I see interrupts on both CPUs. However, typically more on
the CPU that perf is running on (which is probably to be expected). And
I confirm that the only change I made was ...

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index f90d958..042881b 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -286,7 +286,7 @@ static int __init omap_init_pmu(void)
         * interrupts and so the CTI IRQs are used and this requires
additional
         * sub-systems to be enabled.
         */
-       if (cpu_is_omap443x())
+       if (cpu_is_omap44xx())
                r = omap4430_init_pmu();
        else


When you boot the kernel what 4460 rev does it show (very early in the
kernel boot log)? Mine shows ...

[    0.000000] OMAP4460 ES1.1

However, the A9 version has not changed between ES1.0 and ES1.1. Both
should be r2p10.

>> From a PMU programming standpoint, if we just use "perf top" are the
>> event counters not used/programmed?
> 
> Just using perf top should use the cycle counter as the event source.

Ok, so no event counters are used.

>> And when we use "perf top -e instructions" is it the "software
>> increment" event that the event counter(s) are monitoring? I am just
>> trying to understand how the counters are being programmed and then I
>> can ask the design folks an intelligent question :-)
> 
> It depends on the CPU. For Cortex-A9, `instructions' maps to event 0x68,
> which isn't a perfect match. If you want to specify a hex value for the
> event code, you can do:
> 
> # perf top -e rNN
> 
> where NN is the hex event number. On A9, r11 would give you cycles via
> an event counter.

Ok, thanks.

>> By the way, I don't suppose there is any debugfs entry to dump the PMU
>> registers?
> 
> 'fraid not, but there is some debug code in perf_event_v7.c that you
> could call if you wanted to (just #define DEBUG at the top of the file).

Thanks
Jon

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-06-12 22:41                   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-06-12 22:41 UTC (permalink / raw)
  To: linux-arm-kernel


On 06/12/2012 04:31 PM, Will Deacon wrote:
> On Tue, Jun 12, 2012 at 10:17:16PM +0100, Jon Hunter wrote:
>> Hi Will,
> 
> Hi Jon,
> 
>> On 06/12/2012 04:28 AM, Will Deacon wrote:
>>>
>>> Well, I tried that and the results are pretty whacky: the event counters do
>>> indeed tick but interrupts only fire if I pin the perf task to CPU1! What's
>>> more, the interrupts do fire on both cores when they're working...
>>
>> I tried this, and I see that interrupts occur on both, however, it seems
>> that the majority occur on one CPU and only a few on the other. So it
>> does appear that one CPU is getting a lot more interrupts.
> 
> That's understandable -- one of the CPUs is likely more loaded than the
> other. However, I'd like to confirm whether or not you see what I see. With
> the 4430_init hack on a 4460, if I run:
> 
> # taskset 0x2 perf top
> 
> then I get no samples. If I do:
> 
> # taskset 0x1 perf top
> 
> then I *do* get samples and from *both* CPUs. So it smells more like an
> issue poking some configuration registers from CPU1 rather than the IRQ
> path being broken. As I said before, if I don't do the extra init hack
> then I don't get this problem (but event counters don't tick).

In both cases, I see interrupts on both CPUs. However, typically more on
the CPU that perf is running on (which is probably to be expected). And
I confirm that the only change I made was ...

diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index f90d958..042881b 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -286,7 +286,7 @@ static int __init omap_init_pmu(void)
         * interrupts and so the CTI IRQs are used and this requires
additional
         * sub-systems to be enabled.
         */
-       if (cpu_is_omap443x())
+       if (cpu_is_omap44xx())
                r = omap4430_init_pmu();
        else


When you boot the kernel what 4460 rev does it show (very early in the
kernel boot log)? Mine shows ...

[    0.000000] OMAP4460 ES1.1

However, the A9 version has not changed between ES1.0 and ES1.1. Both
should be r2p10.

>> From a PMU programming standpoint, if we just use "perf top" are the
>> event counters not used/programmed?
> 
> Just using perf top should use the cycle counter as the event source.

Ok, so no event counters are used.

>> And when we use "perf top -e instructions" is it the "software
>> increment" event that the event counter(s) are monitoring? I am just
>> trying to understand how the counters are being programmed and then I
>> can ask the design folks an intelligent question :-)
> 
> It depends on the CPU. For Cortex-A9, `instructions' maps to event 0x68,
> which isn't a perfect match. If you want to specify a hex value for the
> event code, you can do:
> 
> # perf top -e rNN
> 
> where NN is the hex event number. On A9, r11 would give you cycles via
> an event counter.

Ok, thanks.

>> By the way, I don't suppose there is any debugfs entry to dump the PMU
>> registers?
> 
> 'fraid not, but there is some debug code in perf_event_v7.c that you
> could call if you wanted to (just #define DEBUG at the top of the file).

Thanks
Jon

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

* Re: [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
  2012-06-07 21:22   ` Jon Hunter
@ 2012-06-13  6:07     ` Pandita, Vikram
  -1 siblings, 0 replies; 118+ messages in thread
From: Pandita, Vikram @ 2012-06-13  6:07 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Kevin Hilman, Paul Walmsley,
	Benoit Cousson, Ming Lei, Will Deacon

On Thu, Jun 7, 2012 at 2:22 PM, Jon Hunter <jon-hunter@ti.com> wrote:
> In order to use the CTI interrupts inconjunction with the DEBUGSS we need to
> re-map the CTI IRQs to the DEBUGSS HWMOD. The purpose for doing this is so we
> can create a PMU device based upon the DEBUGSS HWMOD and use the CTI interrupts
> for routing ARM PMU events for OMAP4430 devices.
>
> This is based upon Benoit Cousson's patch [1].
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/073319.html
>
> Cc: Ming Lei <ming.lei@canonical.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@ti.com>
>
> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
>  arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> index 950454a..faf5a6d 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> @@ -482,10 +482,17 @@ static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
>  };
>
>  /* debugss */
> +static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = {
> +       { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
> +       { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },

Data manual assigns cit0 == MA_IRQ_1 and cti1 == MA_IRQ_2
Why do you add 32 base GIC_START ?

> +       { .irq = -1 }
> +};
> +
>  static struct omap_hwmod omap44xx_debugss_hwmod = {
>        .name           = "debugss",
>        .class          = &omap44xx_debugss_hwmod_class,
>        .clkdm_name     = "emu_sys_clkdm",
> +       .mpu_irqs       = omap44xx_debugss_irqs,
>        .main_clk       = "trace_clk_div_ck",
>        .prcm = {
>                .omap4 = {
> @@ -2447,8 +2454,6 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
>  /* mpu */
>  static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
>        { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
> -       { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
> -       { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
>        { .irq = -1 }
>  };
>
> --
> 1.7.9.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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] 118+ messages in thread

* [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
@ 2012-06-13  6:07     ` Pandita, Vikram
  0 siblings, 0 replies; 118+ messages in thread
From: Pandita, Vikram @ 2012-06-13  6:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 7, 2012 at 2:22 PM, Jon Hunter <jon-hunter@ti.com> wrote:
> In order to use the CTI interrupts inconjunction with the DEBUGSS we need to
> re-map the CTI IRQs to the DEBUGSS HWMOD. The purpose for doing this is so we
> can create a PMU device based upon the DEBUGSS HWMOD and use the CTI interrupts
> for routing ARM PMU events for OMAP4430 devices.
>
> This is based upon Benoit Cousson's patch [1].
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/073319.html
>
> Cc: Ming Lei <ming.lei@canonical.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@ti.com>
>
> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
> ---
> ?arch/arm/mach-omap2/omap_hwmod_44xx_data.c | ? ?9 +++++++--
> ?1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> index 950454a..faf5a6d 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> @@ -482,10 +482,17 @@ static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
> ?};
>
> ?/* debugss */
> +static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = {
> + ? ? ? { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
> + ? ? ? { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },

Data manual assigns cit0 == MA_IRQ_1 and cti1 == MA_IRQ_2
Why do you add 32 base GIC_START ?

> + ? ? ? { .irq = -1 }
> +};
> +
> ?static struct omap_hwmod omap44xx_debugss_hwmod = {
> ? ? ? ?.name ? ? ? ? ? = "debugss",
> ? ? ? ?.class ? ? ? ? ?= &omap44xx_debugss_hwmod_class,
> ? ? ? ?.clkdm_name ? ? = "emu_sys_clkdm",
> + ? ? ? .mpu_irqs ? ? ? = omap44xx_debugss_irqs,
> ? ? ? ?.main_clk ? ? ? = "trace_clk_div_ck",
> ? ? ? ?.prcm = {
> ? ? ? ? ? ? ? ?.omap4 = {
> @@ -2447,8 +2454,6 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
> ?/* mpu */
> ?static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
> ? ? ? ?{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
> - ? ? ? { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
> - ? ? ? { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
> ? ? ? ?{ .irq = -1 }
> ?};
>
> --
> 1.7.9.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
  2012-06-13  6:07     ` Pandita, Vikram
@ 2012-06-13  6:13       ` Pandita, Vikram
  -1 siblings, 0 replies; 118+ messages in thread
From: Pandita, Vikram @ 2012-06-13  6:13 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Kevin Hilman, Paul Walmsley,
	Benoit Cousson, Ming Lei, Will Deacon

On Tue, Jun 12, 2012 at 11:07 PM, Pandita, Vikram <vikram.pandita@ti.com> wrote:
> On Thu, Jun 7, 2012 at 2:22 PM, Jon Hunter <jon-hunter@ti.com> wrote:
>> In order to use the CTI interrupts inconjunction with the DEBUGSS we need to
>> re-map the CTI IRQs to the DEBUGSS HWMOD. The purpose for doing this is so we
>> can create a PMU device based upon the DEBUGSS HWMOD and use the CTI interrupts
>> for routing ARM PMU events for OMAP4430 devices.
>>
>> This is based upon Benoit Cousson's patch [1].
>>
>> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/073319.html
>>
>> Cc: Ming Lei <ming.lei@canonical.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Cc: Benoit Cousson <b-cousson@ti.com>
>> Cc: Paul Walmsley <paul@pwsan.com>
>> Cc: Kevin Hilman <khilman@ti.com>
>>
>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    9 +++++++--
>>  1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>> index 950454a..faf5a6d 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>> @@ -482,10 +482,17 @@ static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
>>  };
>>
>>  /* debugss */
>> +static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = {
>> +       { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
>> +       { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
>
> Data manual assigns cit0 == MA_IRQ_1 and cti1 == MA_IRQ_2
> Why do you add 32 base GIC_START ?

Looks we do the same for pl310:
{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },

so u can ignore my comment .. excuse the noise...

>
>> +       { .irq = -1 }
>> +};
>> +
>>  static struct omap_hwmod omap44xx_debugss_hwmod = {
>>        .name           = "debugss",
>>        .class          = &omap44xx_debugss_hwmod_class,
>>        .clkdm_name     = "emu_sys_clkdm",
>> +       .mpu_irqs       = omap44xx_debugss_irqs,
>>        .main_clk       = "trace_clk_div_ck",
>>        .prcm = {
>>                .omap4 = {
>> @@ -2447,8 +2454,6 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
>>  /* mpu */
>>  static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
>>        { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
>> -       { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
>> -       { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
>>        { .irq = -1 }
>>  };
>>
>> --
>> 1.7.9.5
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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] 118+ messages in thread

* [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
@ 2012-06-13  6:13       ` Pandita, Vikram
  0 siblings, 0 replies; 118+ messages in thread
From: Pandita, Vikram @ 2012-06-13  6:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 12, 2012 at 11:07 PM, Pandita, Vikram <vikram.pandita@ti.com> wrote:
> On Thu, Jun 7, 2012 at 2:22 PM, Jon Hunter <jon-hunter@ti.com> wrote:
>> In order to use the CTI interrupts inconjunction with the DEBUGSS we need to
>> re-map the CTI IRQs to the DEBUGSS HWMOD. The purpose for doing this is so we
>> can create a PMU device based upon the DEBUGSS HWMOD and use the CTI interrupts
>> for routing ARM PMU events for OMAP4430 devices.
>>
>> This is based upon Benoit Cousson's patch [1].
>>
>> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/073319.html
>>
>> Cc: Ming Lei <ming.lei@canonical.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Cc: Benoit Cousson <b-cousson@ti.com>
>> Cc: Paul Walmsley <paul@pwsan.com>
>> Cc: Kevin Hilman <khilman@ti.com>
>>
>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>> ---
>> ?arch/arm/mach-omap2/omap_hwmod_44xx_data.c | ? ?9 +++++++--
>> ?1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>> index 950454a..faf5a6d 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>> @@ -482,10 +482,17 @@ static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
>> ?};
>>
>> ?/* debugss */
>> +static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = {
>> + ? ? ? { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
>> + ? ? ? { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
>
> Data manual assigns cit0 == MA_IRQ_1 and cti1 == MA_IRQ_2
> Why do you add 32 base GIC_START ?

Looks we do the same for pl310:
{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },

so u can ignore my comment .. excuse the noise...

>
>> + ? ? ? { .irq = -1 }
>> +};
>> +
>> ?static struct omap_hwmod omap44xx_debugss_hwmod = {
>> ? ? ? ?.name ? ? ? ? ? = "debugss",
>> ? ? ? ?.class ? ? ? ? ?= &omap44xx_debugss_hwmod_class,
>> ? ? ? ?.clkdm_name ? ? = "emu_sys_clkdm",
>> + ? ? ? .mpu_irqs ? ? ? = omap44xx_debugss_irqs,
>> ? ? ? ?.main_clk ? ? ? = "trace_clk_div_ck",
>> ? ? ? ?.prcm = {
>> ? ? ? ? ? ? ? ?.omap4 = {
>> @@ -2447,8 +2454,6 @@ static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
>> ?/* mpu */
>> ?static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
>> ? ? ? ?{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
>> - ? ? ? { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
>> - ? ? ? { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
>> ? ? ? ?{ .irq = -1 }
>> ?};
>>
>> --
>> 1.7.9.5
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
  2012-06-13  6:13       ` Pandita, Vikram
@ 2012-06-13  6:19         ` Shilimkar, Santosh
  -1 siblings, 0 replies; 118+ messages in thread
From: Shilimkar, Santosh @ 2012-06-13  6:19 UTC (permalink / raw)
  To: Pandita, Vikram
  Cc: Jon Hunter, linux-omap, linux-arm, Kevin Hilman, Paul Walmsley,
	Benoit Cousson, Ming Lei, Will Deacon

On Wed, Jun 13, 2012 at 11:43 AM, Pandita, Vikram <vikram.pandita@ti.com> wrote:
> On Tue, Jun 12, 2012 at 11:07 PM, Pandita, Vikram <vikram.pandita@ti.com> wrote:
>> On Thu, Jun 7, 2012 at 2:22 PM, Jon Hunter <jon-hunter@ti.com> wrote:
>>> In order to use the CTI interrupts inconjunction with the DEBUGSS we need to
>>> re-map the CTI IRQs to the DEBUGSS HWMOD. The purpose for doing this is so we
>>> can create a PMU device based upon the DEBUGSS HWMOD and use the CTI interrupts
>>> for routing ARM PMU events for OMAP4430 devices.
>>>
>>> This is based upon Benoit Cousson's patch [1].
>>>
>>> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/073319.html
>>>
>>> Cc: Ming Lei <ming.lei@canonical.com>
>>> Cc: Will Deacon <will.deacon@arm.com>
>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>> Cc: Paul Walmsley <paul@pwsan.com>
>>> Cc: Kevin Hilman <khilman@ti.com>
>>>
>>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>>> ---
>>>  arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    9 +++++++--
>>>  1 file changed, 7 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>>> index 950454a..faf5a6d 100644
>>> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>>> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>>> @@ -482,10 +482,17 @@ static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
>>>  };
>>>
>>>  /* debugss */
>>> +static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = {
>>> +       { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
>>> +       { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
>>
>> Data manual assigns cit0 == MA_IRQ_1 and cti1 == MA_IRQ_2
>> Why do you add 32 base GIC_START ?
>
> Looks we do the same for pl310:
> { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
>
> so u can ignore my comment .. excuse the noise...
>
All the SPI ( shared Peripheral IRQ's) have offset since first 32 IRQs
are dedicated
for SGI and PPI's.

CTIx and PL310 interrupts are mapped on SPI and hence they need that offset.

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

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

* [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS
@ 2012-06-13  6:19         ` Shilimkar, Santosh
  0 siblings, 0 replies; 118+ messages in thread
From: Shilimkar, Santosh @ 2012-06-13  6:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 13, 2012 at 11:43 AM, Pandita, Vikram <vikram.pandita@ti.com> wrote:
> On Tue, Jun 12, 2012 at 11:07 PM, Pandita, Vikram <vikram.pandita@ti.com> wrote:
>> On Thu, Jun 7, 2012 at 2:22 PM, Jon Hunter <jon-hunter@ti.com> wrote:
>>> In order to use the CTI interrupts inconjunction with the DEBUGSS we need to
>>> re-map the CTI IRQs to the DEBUGSS HWMOD. The purpose for doing this is so we
>>> can create a PMU device based upon the DEBUGSS HWMOD and use the CTI interrupts
>>> for routing ARM PMU events for OMAP4430 devices.
>>>
>>> This is based upon Benoit Cousson's patch [1].
>>>
>>> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/073319.html
>>>
>>> Cc: Ming Lei <ming.lei@canonical.com>
>>> Cc: Will Deacon <will.deacon@arm.com>
>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>> Cc: Paul Walmsley <paul@pwsan.com>
>>> Cc: Kevin Hilman <khilman@ti.com>
>>>
>>> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> Signed-off-by: Jon Hunter <jon-hunter@ti.com>
>>> ---
>>> ?arch/arm/mach-omap2/omap_hwmod_44xx_data.c | ? ?9 +++++++--
>>> ?1 file changed, 7 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>>> index 950454a..faf5a6d 100644
>>> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>>> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
>>> @@ -482,10 +482,17 @@ static struct omap_hwmod_class omap44xx_debugss_hwmod_class = {
>>> ?};
>>>
>>> ?/* debugss */
>>> +static struct omap_hwmod_irq_info omap44xx_debugss_irqs[] = {
>>> + ? ? ? { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
>>> + ? ? ? { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
>>
>> Data manual assigns cit0 == MA_IRQ_1 and cti1 == MA_IRQ_2
>> Why do you add 32 base GIC_START ?
>
> Looks we do the same for pl310:
> { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
>
> so u can ignore my comment .. excuse the noise...
>
All the SPI ( shared Peripheral IRQ's) have offset since first 32 IRQs
are dedicated
for SGI and PPI's.

CTIx and PL310 interrupts are mapped on SPI and hence they need that offset.

Regards
Santosh

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-06-12 22:41                   ` Jon Hunter
@ 2012-07-02  9:55                     ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-02  9:55 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

Hi Jon,

Did you have any luck getting to the bottom of this?

It would be good to take your PMU suspend/resume patches once we know that
they will get used.

On Tue, Jun 12, 2012 at 11:41:27PM +0100, Jon Hunter wrote:
> On 06/12/2012 04:31 PM, Will Deacon wrote:
> > That's understandable -- one of the CPUs is likely more loaded than the
> > other. However, I'd like to confirm whether or not you see what I see. With
> > the 4430_init hack on a 4460, if I run:
> > 
> > # taskset 0x2 perf top
> > 
> > then I get no samples. If I do:
> > 
> > # taskset 0x1 perf top
> > 
> > then I *do* get samples and from *both* CPUs. So it smells more like an
> > issue poking some configuration registers from CPU1 rather than the IRQ
> > path being broken. As I said before, if I don't do the extra init hack
> > then I don't get this problem (but event counters don't tick).
> 
> In both cases, I see interrupts on both CPUs. However, typically more on
> the CPU that perf is running on (which is probably to be expected). And
> I confirm that the only change I made was ...

[...]

> When you boot the kernel what 4460 rev does it show (very early in the
> kernel boot log)? Mine shows ...
> 
> [    0.000000] OMAP4460 ES1.1

Snap: [    0.000000] OMAP4460 ES1.1

> However, the A9 version has not changed between ES1.0 and ES1.1. Both
> should be r2p10.

Yup, that's what /proc/cpuinfo says.

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-02  9:55                     ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-02  9:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

Did you have any luck getting to the bottom of this?

It would be good to take your PMU suspend/resume patches once we know that
they will get used.

On Tue, Jun 12, 2012 at 11:41:27PM +0100, Jon Hunter wrote:
> On 06/12/2012 04:31 PM, Will Deacon wrote:
> > That's understandable -- one of the CPUs is likely more loaded than the
> > other. However, I'd like to confirm whether or not you see what I see. With
> > the 4430_init hack on a 4460, if I run:
> > 
> > # taskset 0x2 perf top
> > 
> > then I get no samples. If I do:
> > 
> > # taskset 0x1 perf top
> > 
> > then I *do* get samples and from *both* CPUs. So it smells more like an
> > issue poking some configuration registers from CPU1 rather than the IRQ
> > path being broken. As I said before, if I don't do the extra init hack
> > then I don't get this problem (but event counters don't tick).
> 
> In both cases, I see interrupts on both CPUs. However, typically more on
> the CPU that perf is running on (which is probably to be expected). And
> I confirm that the only change I made was ...

[...]

> When you boot the kernel what 4460 rev does it show (very early in the
> kernel boot log)? Mine shows ...
> 
> [    0.000000] OMAP4460 ES1.1

Snap: [    0.000000] OMAP4460 ES1.1

> However, the A9 version has not changed between ES1.0 and ES1.1. Both
> should be r2p10.

Yup, that's what /proc/cpuinfo says.

Will

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-02  9:55                     ` Will Deacon
@ 2012-07-02 16:50                       ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-02 16:50 UTC (permalink / raw)
  To: Will Deacon
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

Hi Will,

On 07/02/2012 04:55 AM, Will Deacon wrote:
> Hi Jon,
> 
> Did you have any luck getting to the bottom of this?

I am still waiting for feedback from design. They were trying to confirm
my observations. Unfortunately, it is taking some time. I will ping them
again.

> It would be good to take your PMU suspend/resume patches once we know that
> they will get used.

Yes that would be good. I could drop the 4460 specific changes for now
and make 4460 work in the same way as 4430 (using CTI) for the time
being and see if we can get these in. However, I recall that was not
working for you, but it was working fine for me.

> On Tue, Jun 12, 2012 at 11:41:27PM +0100, Jon Hunter wrote:
>> On 06/12/2012 04:31 PM, Will Deacon wrote:
>>> That's understandable -- one of the CPUs is likely more loaded than the
>>> other. However, I'd like to confirm whether or not you see what I see. With
>>> the 4430_init hack on a 4460, if I run:
>>>
>>> # taskset 0x2 perf top
>>>
>>> then I get no samples. If I do:
>>>
>>> # taskset 0x1 perf top
>>>
>>> then I *do* get samples and from *both* CPUs. So it smells more like an
>>> issue poking some configuration registers from CPU1 rather than the IRQ
>>> path being broken. As I said before, if I don't do the extra init hack
>>> then I don't get this problem (but event counters don't tick).
>>
>> In both cases, I see interrupts on both CPUs. However, typically more on
>> the CPU that perf is running on (which is probably to be expected). And
>> I confirm that the only change I made was ...
> 
> [...]
> 
>> When you boot the kernel what 4460 rev does it show (very early in the
>> kernel boot log)? Mine shows ...
>>
>> [    0.000000] OMAP4460 ES1.1
> 
> Snap: [    0.000000] OMAP4460 ES1.1

Ok.

>> However, the A9 version has not changed between ES1.0 and ES1.1. Both
>> should be r2p10.
> 
> Yup, that's what /proc/cpuinfo says.

Hmmm ... so that does not explain the observation that you made with 4460.

Cheers
Jon

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-02 16:50                       ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-02 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 07/02/2012 04:55 AM, Will Deacon wrote:
> Hi Jon,
> 
> Did you have any luck getting to the bottom of this?

I am still waiting for feedback from design. They were trying to confirm
my observations. Unfortunately, it is taking some time. I will ping them
again.

> It would be good to take your PMU suspend/resume patches once we know that
> they will get used.

Yes that would be good. I could drop the 4460 specific changes for now
and make 4460 work in the same way as 4430 (using CTI) for the time
being and see if we can get these in. However, I recall that was not
working for you, but it was working fine for me.

> On Tue, Jun 12, 2012 at 11:41:27PM +0100, Jon Hunter wrote:
>> On 06/12/2012 04:31 PM, Will Deacon wrote:
>>> That's understandable -- one of the CPUs is likely more loaded than the
>>> other. However, I'd like to confirm whether or not you see what I see. With
>>> the 4430_init hack on a 4460, if I run:
>>>
>>> # taskset 0x2 perf top
>>>
>>> then I get no samples. If I do:
>>>
>>> # taskset 0x1 perf top
>>>
>>> then I *do* get samples and from *both* CPUs. So it smells more like an
>>> issue poking some configuration registers from CPU1 rather than the IRQ
>>> path being broken. As I said before, if I don't do the extra init hack
>>> then I don't get this problem (but event counters don't tick).
>>
>> In both cases, I see interrupts on both CPUs. However, typically more on
>> the CPU that perf is running on (which is probably to be expected). And
>> I confirm that the only change I made was ...
> 
> [...]
> 
>> When you boot the kernel what 4460 rev does it show (very early in the
>> kernel boot log)? Mine shows ...
>>
>> [    0.000000] OMAP4460 ES1.1
> 
> Snap: [    0.000000] OMAP4460 ES1.1

Ok.

>> However, the A9 version has not changed between ES1.0 and ES1.1. Both
>> should be r2p10.
> 
> Yup, that's what /proc/cpuinfo says.

Hmmm ... so that does not explain the observation that you made with 4460.

Cheers
Jon

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-02 16:50                       ` Jon Hunter
@ 2012-07-02 22:01                         ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-02 22:01 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

On Mon, Jul 02, 2012 at 05:50:38PM +0100, Jon Hunter wrote:
> On 07/02/2012 04:55 AM, Will Deacon wrote:
> > 
> > Did you have any luck getting to the bottom of this?
> 
> I am still waiting for feedback from design. They were trying to confirm
> my observations. Unfortunately, it is taking some time. I will ping them
> again.

Ok, thanks. If pinging doesn't work, bribery can be quite effective with
hardware guys :)

> > It would be good to take your PMU suspend/resume patches once we know that
> > they will get used.
> 
> Yes that would be good. I could drop the 4460 specific changes for now
> and make 4460 work in the same way as 4430 (using CTI) for the time
> being and see if we can get these in. However, I recall that was not
> working for you, but it was working fine for me.

Indeed, that hack didn't help me and I'd rather not commit it if it only
partially fixes the problem. A better bet might just be to go with your
original approach and see how many bug reports we receive. That might also
help us narrow down the problem, but it's your call.

In the meantime, I pushed what I think is the latest drop of your series to
a new branch on kernel.org:

  git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git perf/omap4-dev

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-02 22:01                         ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-02 22:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 02, 2012 at 05:50:38PM +0100, Jon Hunter wrote:
> On 07/02/2012 04:55 AM, Will Deacon wrote:
> > 
> > Did you have any luck getting to the bottom of this?
> 
> I am still waiting for feedback from design. They were trying to confirm
> my observations. Unfortunately, it is taking some time. I will ping them
> again.

Ok, thanks. If pinging doesn't work, bribery can be quite effective with
hardware guys :)

> > It would be good to take your PMU suspend/resume patches once we know that
> > they will get used.
> 
> Yes that would be good. I could drop the 4460 specific changes for now
> and make 4460 work in the same way as 4430 (using CTI) for the time
> being and see if we can get these in. However, I recall that was not
> working for you, but it was working fine for me.

Indeed, that hack didn't help me and I'd rather not commit it if it only
partially fixes the problem. A better bet might just be to go with your
original approach and see how many bug reports we receive. That might also
help us narrow down the problem, but it's your call.

In the meantime, I pushed what I think is the latest drop of your series to
a new branch on kernel.org:

  git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git perf/omap4-dev

Will

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

* Re: [PATCH V2 07/10] ARM: OMAP4: CLKDM: Update supported transition modes
  2012-06-07 21:22   ` Jon Hunter
@ 2012-07-04 15:38     ` Paul Walmsley
  -1 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-07-04 15:38 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

On Thu, 7 Jun 2012, Jon Hunter wrote:

> For OMAP3+ devices, the clock domains (CLKDMs) support one or more of the
> following transition modes ...

Thanks, queued.


- Paul

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

* [PATCH V2 07/10] ARM: OMAP4: CLKDM: Update supported transition modes
@ 2012-07-04 15:38     ` Paul Walmsley
  0 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-07-04 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 7 Jun 2012, Jon Hunter wrote:

> For OMAP3+ devices, the clock domains (CLKDMs) support one or more of the
> following transition modes ...

Thanks, queued.


- Paul

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

* Re: [PATCH V2 07/10] ARM: OMAP4: CLKDM: Update supported transition modes
  2012-07-04 15:38     ` Paul Walmsley
@ 2012-07-05 17:14       ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-05 17:14 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hi Paul,

On 07/04/2012 10:38 AM, Paul Walmsley wrote:
> On Thu, 7 Jun 2012, Jon Hunter wrote:
> 
>> For OMAP3+ devices, the clock domains (CLKDMs) support one or more of the
>> following transition modes ...
> 
> Thanks, queued.

Thanks. Any comments on patch 8/10 of this series?

Cheers
Jon

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

* [PATCH V2 07/10] ARM: OMAP4: CLKDM: Update supported transition modes
@ 2012-07-05 17:14       ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-05 17:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/04/2012 10:38 AM, Paul Walmsley wrote:
> On Thu, 7 Jun 2012, Jon Hunter wrote:
> 
>> For OMAP3+ devices, the clock domains (CLKDMs) support one or more of the
>> following transition modes ...
> 
> Thanks, queued.

Thanks. Any comments on patch 8/10 of this series?

Cheers
Jon

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-02 22:01                         ` Will Deacon
@ 2012-07-06  0:40                           ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-06  0:40 UTC (permalink / raw)
  To: Will Deacon
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

Hi Will,

On 07/02/2012 05:01 PM, Will Deacon wrote:
> On Mon, Jul 02, 2012 at 05:50:38PM +0100, Jon Hunter wrote:
>> On 07/02/2012 04:55 AM, Will Deacon wrote:
>>>
>>> Did you have any luck getting to the bottom of this?
>>
>> I am still waiting for feedback from design. They were trying to confirm
>> my observations. Unfortunately, it is taking some time. I will ping them
>> again.
> 
> Ok, thanks. If pinging doesn't work, bribery can be quite effective with
> hardware guys :)

Yes looks like I am going to need to get creative :-)

>>> It would be good to take your PMU suspend/resume patches once we know that
>>> they will get used.
>>
>> Yes that would be good. I could drop the 4460 specific changes for now
>> and make 4460 work in the same way as 4430 (using CTI) for the time
>> being and see if we can get these in. However, I recall that was not
>> working for you, but it was working fine for me.
> 
> Indeed, that hack didn't help me and I'd rather not commit it if it only
> partially fixes the problem. A better bet might just be to go with your
> original approach and see how many bug reports we receive. That might also
> help us narrow down the problem, but it's your call.

Ok, I think that that is best.

> In the meantime, I pushed what I think is the latest drop of your series to
> a new branch on kernel.org:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git perf/omap4-dev

Looks good.

Cheers
Jon

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-06  0:40                           ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-06  0:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 07/02/2012 05:01 PM, Will Deacon wrote:
> On Mon, Jul 02, 2012 at 05:50:38PM +0100, Jon Hunter wrote:
>> On 07/02/2012 04:55 AM, Will Deacon wrote:
>>>
>>> Did you have any luck getting to the bottom of this?
>>
>> I am still waiting for feedback from design. They were trying to confirm
>> my observations. Unfortunately, it is taking some time. I will ping them
>> again.
> 
> Ok, thanks. If pinging doesn't work, bribery can be quite effective with
> hardware guys :)

Yes looks like I am going to need to get creative :-)

>>> It would be good to take your PMU suspend/resume patches once we know that
>>> they will get used.
>>
>> Yes that would be good. I could drop the 4460 specific changes for now
>> and make 4460 work in the same way as 4430 (using CTI) for the time
>> being and see if we can get these in. However, I recall that was not
>> working for you, but it was working fine for me.
> 
> Indeed, that hack didn't help me and I'd rather not commit it if it only
> partially fixes the problem. A better bet might just be to go with your
> original approach and see how many bug reports we receive. That might also
> help us narrow down the problem, but it's your call.

Ok, I think that that is best.

> In the meantime, I pushed what I think is the latest drop of your series to
> a new branch on kernel.org:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git perf/omap4-dev

Looks good.

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-06-07 21:22   ` Jon Hunter
@ 2012-07-12 21:17     ` Paul Walmsley
  -1 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-07-12 21:17 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hello Jon

On Thu, 7 Jun 2012, Jon Hunter wrote:

> By removing the CLKDM_CAN_ENABLE_AUTO flag, the EMU clock domain will always
> remain on and hence, this will break low-power modes. The EMU clock domain only
> support the SW_WKUP and HW_AUTO transition modes (for more details refer to the
> OMAP4430 TRM) and power down the EMU power domain we need to place the EMU
> clock domain back into the HW_AUTO mode. This can be accomplished by setting
> the CLKDM_CAN_FORCE_SLEEP flag, which for an OMAP4 device will enable the
> HW_AUTO mode.

Hmm, it would be nice if we could keep the CLKDM_CAN_* flags matching the 
hardware capabilities.  Looking at the 4430 TRM Rev X Table 3-744 
"CM_EMU_CLKSTCTRL", the CLKTRCTRL field isn't documented as supporting the 
SW_SLEEP mode (which CLKDM_CAN_FORCE_SLEEP will set).

Maybe the CLKDM_CAN_* flags should be moved to a separate u8...

Anyway, what do you think about the following approach?  It uses a 
special flag to indicate that the EMU clockdomain is behaving in an 
unexpected way.  If you think it's reasonable, perhaps you could try your 
PMU tests with it?  It applies on top of linux-omap master 
(cb07e3394573a419147a1783f3bd7ef13045353c) plus the clockdomain patch 
posted earlier at:

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

But these patches may need to be applied on Kevin's 'pm' branch for 
meaningful PM testing:

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



- Paul

From: Paul Walmsley <paul@pwsan.com>
Date: Thu, 12 Jul 2012 14:58:43 -0600
Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
 clockdomain idle problems

The idle status of the IP blocks and clocks inside the EMU clockdomain
isn't taken into account by the PRCM hardware when deciding whether
the clockdomain is idle.  Add a workaround flag, CLKDM_MISSING_IDLE_REPORTING,
to deal with this problem, and add the code necessary to support it.

XXX Add more description of what this flag actually does

XXX Jon, Ming, Will
---
 arch/arm/mach-omap2/clockdomain.c           |   17 ++++++
 arch/arm/mach-omap2/clockdomain.h           |   20 ++++++-
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c  |   86 +++++++++++++++++----------
 arch/arm/mach-omap2/clockdomain44xx.c       |   11 ++++
 arch/arm/mach-omap2/clockdomains3xxx_data.c |    7 +--
 arch/arm/mach-omap2/clockdomains44xx_data.c |    3 +-
 arch/arm/mach-omap2/omap_hwmod.c            |    3 +-
 7 files changed, 105 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index b851ba4..17b1d32 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -914,6 +914,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
 	return ret;
 }
 
+/**
+ * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm has the
+ * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
+ * null.  More information is available in the documentation for the
+ * CLKDM_MISSING_IDLE_REPORTING macro.
+ */
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
+{
+	if (!clkdm)
+		return false;
+
+	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
+}
+
 /* Clockdomain-to-clock/hwmod framework interface code */
 
 static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 7b3c1d2..fb5d37f 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -1,9 +1,7 @@
 /*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
  * OMAP2/3 clockdomain framework functions
  *
- * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008, 2012 Texas Instruments, Inc.
  * Copyright (C) 2008-2011 Nokia Corporation
  *
  * Paul Walmsley
@@ -34,6 +32,20 @@
  * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
  *     active whenever the MPU is active.  True for interconnects and
  *     the WKUP clockdomains.
+ * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
+ *     clocks inside this clockdomain are not taken into account by
+ *     the PRCM when determining whether the clockdomain is idle.
+ *     Without this flag, if the clockdomain is set to
+ *     hardware-supervised idle mode, the PRCM may transition the
+ *     enclosing powerdomain to a low power state, even when devices
+ *     inside the clockdomain and powerdomain are in use.  (An example
+ *     of such a clockdomain is the EMU clockdomain on OMAP3/4.)  If
+ *     this flag is set, and the clockdomain does not support the
+ *     force-sleep mode, then the HW_AUTO mode will be used to put the
+ *     clockdomain to sleep.  Similarly, if the clockdomain supports
+ *     the force-wakeup mode, then it will be used whenever a clock or
+ *     IP block inside the clockdomain is active, rather than the
+ *     HW_AUTO mode.
  */
 #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
 #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
@@ -41,6 +53,7 @@
 #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
 #define CLKDM_NO_AUTODEPS			(1 << 4)
 #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
+#define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
 
 #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
 #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@ -188,6 +201,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
 void clkdm_allow_idle(struct clockdomain *clkdm);
 void clkdm_deny_idle(struct clockdomain *clkdm);
 bool clkdm_in_hwsup(struct clockdomain *clkdm);
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
 
 int clkdm_wakeup(struct clockdomain *clkdm);
 int clkdm_sleep(struct clockdomain *clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index a0d68db..09385a9 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -162,6 +162,37 @@ static void _disable_hwsup(struct clockdomain *clkdm)
 						clkdm->clktrctrl_mask);
 }
 
+static int omap3_clkdm_sleep(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+				      clkdm->clktrctrl_mask);
+	return 0;
+}
+
+static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+				       clkdm->clktrctrl_mask);
+	return 0;
+}
+
+static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_add_autodeps(clkdm);
+
+	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				       clkdm->clktrctrl_mask);
+}
+
+static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					clkdm->clktrctrl_mask);
+
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_del_autodeps(clkdm);
+}
 
 static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
 {
@@ -170,6 +201,18 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & (CLKDM_MISSING_IDLE_REPORTING |
+			    CLKDM_CAN_FORCE_WAKEUP)) {
+		(cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
+			omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -193,6 +236,17 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -209,38 +263,6 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
 	return 0;
 }
 
-static int omap3_clkdm_sleep(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-	return 0;
-}
-
-static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-	return 0;
-}
-
-static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
-{
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_add_autodeps(clkdm);
-
-	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-}
-
-static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_del_autodeps(clkdm);
-}
-
 struct clkdm_ops omap2_clkdm_operations = {
 	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
 	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 762f2cc..6fc6155 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->prcm_partition)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		omap4_clkdm_allow_idle(clkdm);
+		return 0;
+	}
+
 	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index 56089c4..933a35c 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
 	.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
- */
 static struct clockdomain emu_clkdm = {
 	.name		= "emu_clkdm",
 	.pwrdm		= { .name = "emu_pwrdm" },
-	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
+	.flags		= (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
+			   CLKDM_MISSING_IDLE_REPORTING),
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
 };
 
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 63d60a7..b56d06b 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
-	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+	.flags		  = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
+			     CLKDM_MISSING_IDLE_REPORTING),
 };
 
 static struct clockdomain l3_dma_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6ca8e51..36f0603 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1857,7 +1857,8 @@ static int _enable(struct omap_hwmod *oh)
 		 * completely the module. The clockdomain can be set
 		 * in HW_AUTO only when the module become ready.
 		 */
-		hwsup = clkdm_in_hwsup(oh->clkdm);
+		hwsup = clkdm_in_hwsup(oh->clkdm) &&
+			!clkdm_missing_idle_reporting(oh->clkdm);
 		r = clkdm_hwmod_enable(oh->clkdm, oh);
 		if (r) {
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
-- 
1.7.10




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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-12 21:17     ` Paul Walmsley
  0 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-07-12 21:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Jon

On Thu, 7 Jun 2012, Jon Hunter wrote:

> By removing the CLKDM_CAN_ENABLE_AUTO flag, the EMU clock domain will always
> remain on and hence, this will break low-power modes. The EMU clock domain only
> support the SW_WKUP and HW_AUTO transition modes (for more details refer to the
> OMAP4430 TRM) and power down the EMU power domain we need to place the EMU
> clock domain back into the HW_AUTO mode. This can be accomplished by setting
> the CLKDM_CAN_FORCE_SLEEP flag, which for an OMAP4 device will enable the
> HW_AUTO mode.

Hmm, it would be nice if we could keep the CLKDM_CAN_* flags matching the 
hardware capabilities.  Looking at the 4430 TRM Rev X Table 3-744 
"CM_EMU_CLKSTCTRL", the CLKTRCTRL field isn't documented as supporting the 
SW_SLEEP mode (which CLKDM_CAN_FORCE_SLEEP will set).

Maybe the CLKDM_CAN_* flags should be moved to a separate u8...

Anyway, what do you think about the following approach?  It uses a 
special flag to indicate that the EMU clockdomain is behaving in an 
unexpected way.  If you think it's reasonable, perhaps you could try your 
PMU tests with it?  It applies on top of linux-omap master 
(cb07e3394573a419147a1783f3bd7ef13045353c) plus the clockdomain patch 
posted earlier at:

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

But these patches may need to be applied on Kevin's 'pm' branch for 
meaningful PM testing:

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



- Paul

From: Paul Walmsley <paul@pwsan.com>
Date: Thu, 12 Jul 2012 14:58:43 -0600
Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
 clockdomain idle problems

The idle status of the IP blocks and clocks inside the EMU clockdomain
isn't taken into account by the PRCM hardware when deciding whether
the clockdomain is idle.  Add a workaround flag, CLKDM_MISSING_IDLE_REPORTING,
to deal with this problem, and add the code necessary to support it.

XXX Add more description of what this flag actually does

XXX Jon, Ming, Will
---
 arch/arm/mach-omap2/clockdomain.c           |   17 ++++++
 arch/arm/mach-omap2/clockdomain.h           |   20 ++++++-
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c  |   86 +++++++++++++++++----------
 arch/arm/mach-omap2/clockdomain44xx.c       |   11 ++++
 arch/arm/mach-omap2/clockdomains3xxx_data.c |    7 +--
 arch/arm/mach-omap2/clockdomains44xx_data.c |    3 +-
 arch/arm/mach-omap2/omap_hwmod.c            |    3 +-
 7 files changed, 105 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index b851ba4..17b1d32 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -914,6 +914,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
 	return ret;
 }
 
+/**
+ * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm has the
+ * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
+ * null.  More information is available in the documentation for the
+ * CLKDM_MISSING_IDLE_REPORTING macro.
+ */
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
+{
+	if (!clkdm)
+		return false;
+
+	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
+}
+
 /* Clockdomain-to-clock/hwmod framework interface code */
 
 static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 7b3c1d2..fb5d37f 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -1,9 +1,7 @@
 /*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
  * OMAP2/3 clockdomain framework functions
  *
- * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008, 2012 Texas Instruments, Inc.
  * Copyright (C) 2008-2011 Nokia Corporation
  *
  * Paul Walmsley
@@ -34,6 +32,20 @@
  * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
  *     active whenever the MPU is active.  True for interconnects and
  *     the WKUP clockdomains.
+ * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
+ *     clocks inside this clockdomain are not taken into account by
+ *     the PRCM when determining whether the clockdomain is idle.
+ *     Without this flag, if the clockdomain is set to
+ *     hardware-supervised idle mode, the PRCM may transition the
+ *     enclosing powerdomain to a low power state, even when devices
+ *     inside the clockdomain and powerdomain are in use.  (An example
+ *     of such a clockdomain is the EMU clockdomain on OMAP3/4.)  If
+ *     this flag is set, and the clockdomain does not support the
+ *     force-sleep mode, then the HW_AUTO mode will be used to put the
+ *     clockdomain to sleep.  Similarly, if the clockdomain supports
+ *     the force-wakeup mode, then it will be used whenever a clock or
+ *     IP block inside the clockdomain is active, rather than the
+ *     HW_AUTO mode.
  */
 #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
 #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
@@ -41,6 +53,7 @@
 #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
 #define CLKDM_NO_AUTODEPS			(1 << 4)
 #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
+#define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
 
 #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
 #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@ -188,6 +201,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
 void clkdm_allow_idle(struct clockdomain *clkdm);
 void clkdm_deny_idle(struct clockdomain *clkdm);
 bool clkdm_in_hwsup(struct clockdomain *clkdm);
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
 
 int clkdm_wakeup(struct clockdomain *clkdm);
 int clkdm_sleep(struct clockdomain *clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index a0d68db..09385a9 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -162,6 +162,37 @@ static void _disable_hwsup(struct clockdomain *clkdm)
 						clkdm->clktrctrl_mask);
 }
 
+static int omap3_clkdm_sleep(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+				      clkdm->clktrctrl_mask);
+	return 0;
+}
+
+static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+				       clkdm->clktrctrl_mask);
+	return 0;
+}
+
+static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_add_autodeps(clkdm);
+
+	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+				       clkdm->clktrctrl_mask);
+}
+
+static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+					clkdm->clktrctrl_mask);
+
+	if (atomic_read(&clkdm->usecount) > 0)
+		_clkdm_del_autodeps(clkdm);
+}
 
 static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
 {
@@ -170,6 +201,18 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & (CLKDM_MISSING_IDLE_REPORTING |
+			    CLKDM_CAN_FORCE_WAKEUP)) {
+		(cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
+			omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -193,6 +236,17 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -209,38 +263,6 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
 	return 0;
 }
 
-static int omap3_clkdm_sleep(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-	return 0;
-}
-
-static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-	return 0;
-}
-
-static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
-{
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_add_autodeps(clkdm);
-
-	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-}
-
-static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
-{
-	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
-				clkdm->clktrctrl_mask);
-
-	if (atomic_read(&clkdm->usecount) > 0)
-		_clkdm_del_autodeps(clkdm);
-}
-
 struct clkdm_ops omap2_clkdm_operations = {
 	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
 	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 762f2cc..6fc6155 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->prcm_partition)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		omap4_clkdm_allow_idle(clkdm);
+		return 0;
+	}
+
 	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index 56089c4..933a35c 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
 	.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
- */
 static struct clockdomain emu_clkdm = {
 	.name		= "emu_clkdm",
 	.pwrdm		= { .name = "emu_pwrdm" },
-	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
+	.flags		= (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
+			   CLKDM_MISSING_IDLE_REPORTING),
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
 };
 
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 63d60a7..b56d06b 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
-	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+	.flags		  = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
+			     CLKDM_MISSING_IDLE_REPORTING),
 };
 
 static struct clockdomain l3_dma_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6ca8e51..36f0603 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1857,7 +1857,8 @@ static int _enable(struct omap_hwmod *oh)
 		 * completely the module. The clockdomain can be set
 		 * in HW_AUTO only when the module become ready.
 		 */
-		hwsup = clkdm_in_hwsup(oh->clkdm);
+		hwsup = clkdm_in_hwsup(oh->clkdm) &&
+			!clkdm_missing_idle_reporting(oh->clkdm);
 		r = clkdm_hwmod_enable(oh->clkdm, oh);
 		if (r) {
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
-- 
1.7.10

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-12 21:17     ` Paul Walmsley
@ 2012-07-13 13:54       ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-13 13:54 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hi Paul,

On 07/12/2012 04:17 PM, Paul Walmsley wrote:
> Hello Jon
> 
> On Thu, 7 Jun 2012, Jon Hunter wrote:
> 
>> By removing the CLKDM_CAN_ENABLE_AUTO flag, the EMU clock domain will always
>> remain on and hence, this will break low-power modes. The EMU clock domain only
>> support the SW_WKUP and HW_AUTO transition modes (for more details refer to the
>> OMAP4430 TRM) and power down the EMU power domain we need to place the EMU
>> clock domain back into the HW_AUTO mode. This can be accomplished by setting
>> the CLKDM_CAN_FORCE_SLEEP flag, which for an OMAP4 device will enable the
>> HW_AUTO mode.
> 
> Hmm, it would be nice if we could keep the CLKDM_CAN_* flags matching the 
> hardware capabilities.  Looking at the 4430 TRM Rev X Table 3-744 
> "CM_EMU_CLKSTCTRL", the CLKTRCTRL field isn't documented as supporting the 
> SW_SLEEP mode (which CLKDM_CAN_FORCE_SLEEP will set).

Right, however, this was part of the recommendation from Benoit. In
patch #7 of this series we actually made the following modification ...

"By eliminating the SW_SLEEP mode the the mapping of the flags for OMAP4
devices can becomes ...

CLKDM_CAN_DISABLE_AUTO	--> NO_SLEEP
CLKDM_CAN_ENABLE_AUTO	--> HW_AUTO
CLKDM_CAN_FORCE_SLEEP	--> HW_AUTO
CLKDM_CAN_FORCE_WAKEUP	--> SW_WKUP"

So now, by setting CLKDM_CAN_FORCE_SLEEP we are actually enabling
HW_AUTO and not SW_SLEEP (for OMAP4). This was the purpose of patch #7
was to remove the SW_SLEEP for OMAP4 as it is equivalent to HW_AUTO when
using it to disable the module. Unfortunately, although this works it
does make the flags a bit less clearer. The upside is the solution is
simpler.

> Maybe the CLKDM_CAN_* flags should be moved to a separate u8...
> 
> Anyway, what do you think about the following approach?  It uses a 
> special flag to indicate that the EMU clockdomain is behaving in an 
> unexpected way.  If you think it's reasonable, perhaps you could try your 
> PMU tests with it?  It applies on top of linux-omap master 
> (cb07e3394573a419147a1783f3bd7ef13045353c) plus the clockdomain patch 
> posted earlier at:
> 
> http://marc.info/?l=linux-omap&m=134209072829531&w=2
> 
> But these patches may need to be applied on Kevin's 'pm' branch for 
> meaningful PM testing:
> 
> http://marc.info/?l=linux-omap&m=134196493819792&w=2
> 
> 
> 
> - Paul
> 
> From: Paul Walmsley <paul@pwsan.com>
> Date: Thu, 12 Jul 2012 14:58:43 -0600
> Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
>  clockdomain idle problems
> 
> The idle status of the IP blocks and clocks inside the EMU clockdomain
> isn't taken into account by the PRCM hardware when deciding whether
> the clockdomain is idle.  Add a workaround flag, CLKDM_MISSING_IDLE_REPORTING,
> to deal with this problem, and add the code necessary to support it.
> 
> XXX Add more description of what this flag actually does
> 
> XXX Jon, Ming, Will
> ---
>  arch/arm/mach-omap2/clockdomain.c           |   17 ++++++
>  arch/arm/mach-omap2/clockdomain.h           |   20 ++++++-
>  arch/arm/mach-omap2/clockdomain2xxx_3xxx.c  |   86 +++++++++++++++++----------
>  arch/arm/mach-omap2/clockdomain44xx.c       |   11 ++++
>  arch/arm/mach-omap2/clockdomains3xxx_data.c |    7 +--
>  arch/arm/mach-omap2/clockdomains44xx_data.c |    3 +-
>  arch/arm/mach-omap2/omap_hwmod.c            |    3 +-
>  7 files changed, 105 insertions(+), 42 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
> index b851ba4..17b1d32 100644
> --- a/arch/arm/mach-omap2/clockdomain.c
> +++ b/arch/arm/mach-omap2/clockdomain.c
> @@ -914,6 +914,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
>  	return ret;
>  }
>  
> +/**
> + * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
> + * @clkdm: struct clockdomain *
> + *
> + * Returns true if clockdomain @clkdm has the
> + * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
> + * null.  More information is available in the documentation for the
> + * CLKDM_MISSING_IDLE_REPORTING macro.
> + */
> +bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
> +{
> +	if (!clkdm)
> +		return false;
> +
> +	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
> +}
> +
>  /* Clockdomain-to-clock/hwmod framework interface code */
>  
>  static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
> diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
> index 7b3c1d2..fb5d37f 100644
> --- a/arch/arm/mach-omap2/clockdomain.h
> +++ b/arch/arm/mach-omap2/clockdomain.h
> @@ -1,9 +1,7 @@
>  /*
> - * arch/arm/plat-omap/include/mach/clockdomain.h
> - *
>   * OMAP2/3 clockdomain framework functions
>   *
> - * Copyright (C) 2008 Texas Instruments, Inc.
> + * Copyright (C) 2008, 2012 Texas Instruments, Inc.
>   * Copyright (C) 2008-2011 Nokia Corporation
>   *
>   * Paul Walmsley
> @@ -34,6 +32,20 @@
>   * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
>   *     active whenever the MPU is active.  True for interconnects and
>   *     the WKUP clockdomains.
> + * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
> + *     clocks inside this clockdomain are not taken into account by
> + *     the PRCM when determining whether the clockdomain is idle.
> + *     Without this flag, if the clockdomain is set to
> + *     hardware-supervised idle mode, the PRCM may transition the
> + *     enclosing powerdomain to a low power state, even when devices
> + *     inside the clockdomain and powerdomain are in use.  (An example
> + *     of such a clockdomain is the EMU clockdomain on OMAP3/4.)  If
> + *     this flag is set, and the clockdomain does not support the
> + *     force-sleep mode, then the HW_AUTO mode will be used to put the
> + *     clockdomain to sleep.  Similarly, if the clockdomain supports
> + *     the force-wakeup mode, then it will be used whenever a clock or
> + *     IP block inside the clockdomain is active, rather than the
> + *     HW_AUTO mode.

I am not sure if it is really a matter of the clock domain missing the
idle reporting, but more of a problem that the EMU power domain power
state is programmed in HW to OFF and cannot be changed by software. (see
POWER_STATE field of PM_EMU_PWRSTCTRL register description in the TRM).

This means that when the EMU clock domain does idle, the EMU power
domain can transition to OFF and hence we loss the EMU logic context. So
we need to keep the EMU CLKDM on to keep the EMU PWRDM on, but it is
really the lack of control we have over the PWRDM that is the problem. I
would not say this is a HW bug but more of a design choice probably to
keep the design simpler at the expense of power.

I believe that this problem would happen to all power domains if they
were programmed for the OFF power state when the clock domain idled. For
other power domains we avoid this by programming them to the ON state
when we are using them.

Therefore, we need to keep the EMU CLKDM ON while active to prevent the
PWRDM transitioning to OFF, when the CLKDM idles. So I would see this
problem as more like the CLKDM_CANNOT_IDLE_WHILE_ACTIVE vs
CLKDM_MISSING_IDLE_REPORTING.

>   */
>  #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
>  #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
> @@ -41,6 +53,7 @@
>  #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
>  #define CLKDM_NO_AUTODEPS			(1 << 4)
>  #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
> +#define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
>  
>  #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
>  #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
> @@ -188,6 +201,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
>  void clkdm_allow_idle(struct clockdomain *clkdm);
>  void clkdm_deny_idle(struct clockdomain *clkdm);
>  bool clkdm_in_hwsup(struct clockdomain *clkdm);
> +bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
>  
>  int clkdm_wakeup(struct clockdomain *clkdm);
>  int clkdm_sleep(struct clockdomain *clkdm);
> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> index a0d68db..09385a9 100644
> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> @@ -162,6 +162,37 @@ static void _disable_hwsup(struct clockdomain *clkdm)
>  						clkdm->clktrctrl_mask);
>  }
>  
> +static int omap3_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
> +				      clkdm->clktrctrl_mask);
> +	return 0;
> +}
> +
> +static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
> +				       clkdm->clktrctrl_mask);
> +	return 0;
> +}
> +
> +static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +	if (atomic_read(&clkdm->usecount) > 0)
> +		_clkdm_add_autodeps(clkdm);
> +
> +	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +				       clkdm->clktrctrl_mask);
> +}
> +
> +static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					clkdm->clktrctrl_mask);
> +
> +	if (atomic_read(&clkdm->usecount) > 0)
> +		_clkdm_del_autodeps(clkdm);
> +}
>  
>  static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>  {
> @@ -170,6 +201,18 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & (CLKDM_MISSING_IDLE_REPORTING |
> +			    CLKDM_CAN_FORCE_WAKEUP)) {
> +		(cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
> +			omap3_clkdm_wakeup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);
>  
> @@ -193,6 +236,17 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +		_enable_hwsup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);
>  
> @@ -209,38 +263,6 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
>  	return 0;
>  }
>  
> -static int omap3_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -	return 0;
> -}
> -
> -static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -	return 0;
> -}
> -
> -static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -	if (atomic_read(&clkdm->usecount) > 0)
> -		_clkdm_add_autodeps(clkdm);
> -
> -	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -}
> -
> -static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -
> -	if (atomic_read(&clkdm->usecount) > 0)
> -		_clkdm_del_autodeps(clkdm);
> -}
> -
>  struct clkdm_ops omap2_clkdm_operations = {
>  	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
>  	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
> diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
> index 762f2cc..6fc6155 100644
> --- a/arch/arm/mach-omap2/clockdomain44xx.c
> +++ b/arch/arm/mach-omap2/clockdomain44xx.c
> @@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
>  	if (!clkdm->prcm_partition)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +		omap4_clkdm_allow_idle(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
>  					clkdm->cm_inst, clkdm->clkdm_offs);
>  
> diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> index 56089c4..933a35c 100644
> --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
> +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> @@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
>  	.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
> - */
>  static struct clockdomain emu_clkdm = {
>  	.name		= "emu_clkdm",
>  	.pwrdm		= { .name = "emu_pwrdm" },
> -	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
> +	.flags		= (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
> +			   CLKDM_MISSING_IDLE_REPORTING),
>  	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
>  };
>  
> diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
> index 63d60a7..b56d06b 100644
> --- a/arch/arm/mach-omap2/clockdomains44xx_data.c
> +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
> @@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
>  	.prcm_partition	  = OMAP4430_PRM_PARTITION,
>  	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
>  	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
> -	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
> +	.flags		  = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
> +			     CLKDM_MISSING_IDLE_REPORTING),
>  };
>  
>  static struct clockdomain l3_dma_44xx_clkdm = {
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 6ca8e51..36f0603 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -1857,7 +1857,8 @@ static int _enable(struct omap_hwmod *oh)
>  		 * completely the module. The clockdomain can be set
>  		 * in HW_AUTO only when the module become ready.
>  		 */
> -		hwsup = clkdm_in_hwsup(oh->clkdm);
> +		hwsup = clkdm_in_hwsup(oh->clkdm) &&
> +			!clkdm_missing_idle_reporting(oh->clkdm);
>  		r = clkdm_hwmod_enable(oh->clkdm, oh);
>  		if (r) {
>  			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
> 

Thanks for the detailed suggestion! Adding a flag to prevent programming
the HW_AUTO while the CLKDM is active could definitely work (although I
may change the name/description of the flag a little).

Another proposal I also thought of is re-working the flags to describe
the HW mode to be used when turning on the CLKDM, when the CLKDM is
active and when the CLKDM is shut down. So instead of saying what modes
the CLKDM supports, specify what modes should be used for pre-ON (i.e.
turn ON), ON and OFF. Right now software is trying to decide for us by
what is available (which is ideal) but makes working around such nuances
a little more painful.

By the way, I did do some testing on OMAP3, but I don't recall now
whether I was having such problems with OMAP3. I need to go back and
test perf again on OMAP3 to see if such a flag is needed.

Cheers
Jon

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-13 13:54       ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-13 13:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/12/2012 04:17 PM, Paul Walmsley wrote:
> Hello Jon
> 
> On Thu, 7 Jun 2012, Jon Hunter wrote:
> 
>> By removing the CLKDM_CAN_ENABLE_AUTO flag, the EMU clock domain will always
>> remain on and hence, this will break low-power modes. The EMU clock domain only
>> support the SW_WKUP and HW_AUTO transition modes (for more details refer to the
>> OMAP4430 TRM) and power down the EMU power domain we need to place the EMU
>> clock domain back into the HW_AUTO mode. This can be accomplished by setting
>> the CLKDM_CAN_FORCE_SLEEP flag, which for an OMAP4 device will enable the
>> HW_AUTO mode.
> 
> Hmm, it would be nice if we could keep the CLKDM_CAN_* flags matching the 
> hardware capabilities.  Looking at the 4430 TRM Rev X Table 3-744 
> "CM_EMU_CLKSTCTRL", the CLKTRCTRL field isn't documented as supporting the 
> SW_SLEEP mode (which CLKDM_CAN_FORCE_SLEEP will set).

Right, however, this was part of the recommendation from Benoit. In
patch #7 of this series we actually made the following modification ...

"By eliminating the SW_SLEEP mode the the mapping of the flags for OMAP4
devices can becomes ...

CLKDM_CAN_DISABLE_AUTO	--> NO_SLEEP
CLKDM_CAN_ENABLE_AUTO	--> HW_AUTO
CLKDM_CAN_FORCE_SLEEP	--> HW_AUTO
CLKDM_CAN_FORCE_WAKEUP	--> SW_WKUP"

So now, by setting CLKDM_CAN_FORCE_SLEEP we are actually enabling
HW_AUTO and not SW_SLEEP (for OMAP4). This was the purpose of patch #7
was to remove the SW_SLEEP for OMAP4 as it is equivalent to HW_AUTO when
using it to disable the module. Unfortunately, although this works it
does make the flags a bit less clearer. The upside is the solution is
simpler.

> Maybe the CLKDM_CAN_* flags should be moved to a separate u8...
> 
> Anyway, what do you think about the following approach?  It uses a 
> special flag to indicate that the EMU clockdomain is behaving in an 
> unexpected way.  If you think it's reasonable, perhaps you could try your 
> PMU tests with it?  It applies on top of linux-omap master 
> (cb07e3394573a419147a1783f3bd7ef13045353c) plus the clockdomain patch 
> posted earlier at:
> 
> http://marc.info/?l=linux-omap&m=134209072829531&w=2
> 
> But these patches may need to be applied on Kevin's 'pm' branch for 
> meaningful PM testing:
> 
> http://marc.info/?l=linux-omap&m=134196493819792&w=2
> 
> 
> 
> - Paul
> 
> From: Paul Walmsley <paul@pwsan.com>
> Date: Thu, 12 Jul 2012 14:58:43 -0600
> Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
>  clockdomain idle problems
> 
> The idle status of the IP blocks and clocks inside the EMU clockdomain
> isn't taken into account by the PRCM hardware when deciding whether
> the clockdomain is idle.  Add a workaround flag, CLKDM_MISSING_IDLE_REPORTING,
> to deal with this problem, and add the code necessary to support it.
> 
> XXX Add more description of what this flag actually does
> 
> XXX Jon, Ming, Will
> ---
>  arch/arm/mach-omap2/clockdomain.c           |   17 ++++++
>  arch/arm/mach-omap2/clockdomain.h           |   20 ++++++-
>  arch/arm/mach-omap2/clockdomain2xxx_3xxx.c  |   86 +++++++++++++++++----------
>  arch/arm/mach-omap2/clockdomain44xx.c       |   11 ++++
>  arch/arm/mach-omap2/clockdomains3xxx_data.c |    7 +--
>  arch/arm/mach-omap2/clockdomains44xx_data.c |    3 +-
>  arch/arm/mach-omap2/omap_hwmod.c            |    3 +-
>  7 files changed, 105 insertions(+), 42 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
> index b851ba4..17b1d32 100644
> --- a/arch/arm/mach-omap2/clockdomain.c
> +++ b/arch/arm/mach-omap2/clockdomain.c
> @@ -914,6 +914,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
>  	return ret;
>  }
>  
> +/**
> + * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
> + * @clkdm: struct clockdomain *
> + *
> + * Returns true if clockdomain @clkdm has the
> + * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
> + * null.  More information is available in the documentation for the
> + * CLKDM_MISSING_IDLE_REPORTING macro.
> + */
> +bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
> +{
> +	if (!clkdm)
> +		return false;
> +
> +	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
> +}
> +
>  /* Clockdomain-to-clock/hwmod framework interface code */
>  
>  static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
> diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
> index 7b3c1d2..fb5d37f 100644
> --- a/arch/arm/mach-omap2/clockdomain.h
> +++ b/arch/arm/mach-omap2/clockdomain.h
> @@ -1,9 +1,7 @@
>  /*
> - * arch/arm/plat-omap/include/mach/clockdomain.h
> - *
>   * OMAP2/3 clockdomain framework functions
>   *
> - * Copyright (C) 2008 Texas Instruments, Inc.
> + * Copyright (C) 2008, 2012 Texas Instruments, Inc.
>   * Copyright (C) 2008-2011 Nokia Corporation
>   *
>   * Paul Walmsley
> @@ -34,6 +32,20 @@
>   * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
>   *     active whenever the MPU is active.  True for interconnects and
>   *     the WKUP clockdomains.
> + * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
> + *     clocks inside this clockdomain are not taken into account by
> + *     the PRCM when determining whether the clockdomain is idle.
> + *     Without this flag, if the clockdomain is set to
> + *     hardware-supervised idle mode, the PRCM may transition the
> + *     enclosing powerdomain to a low power state, even when devices
> + *     inside the clockdomain and powerdomain are in use.  (An example
> + *     of such a clockdomain is the EMU clockdomain on OMAP3/4.)  If
> + *     this flag is set, and the clockdomain does not support the
> + *     force-sleep mode, then the HW_AUTO mode will be used to put the
> + *     clockdomain to sleep.  Similarly, if the clockdomain supports
> + *     the force-wakeup mode, then it will be used whenever a clock or
> + *     IP block inside the clockdomain is active, rather than the
> + *     HW_AUTO mode.

I am not sure if it is really a matter of the clock domain missing the
idle reporting, but more of a problem that the EMU power domain power
state is programmed in HW to OFF and cannot be changed by software. (see
POWER_STATE field of PM_EMU_PWRSTCTRL register description in the TRM).

This means that when the EMU clock domain does idle, the EMU power
domain can transition to OFF and hence we loss the EMU logic context. So
we need to keep the EMU CLKDM on to keep the EMU PWRDM on, but it is
really the lack of control we have over the PWRDM that is the problem. I
would not say this is a HW bug but more of a design choice probably to
keep the design simpler at the expense of power.

I believe that this problem would happen to all power domains if they
were programmed for the OFF power state when the clock domain idled. For
other power domains we avoid this by programming them to the ON state
when we are using them.

Therefore, we need to keep the EMU CLKDM ON while active to prevent the
PWRDM transitioning to OFF, when the CLKDM idles. So I would see this
problem as more like the CLKDM_CANNOT_IDLE_WHILE_ACTIVE vs
CLKDM_MISSING_IDLE_REPORTING.

>   */
>  #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
>  #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
> @@ -41,6 +53,7 @@
>  #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
>  #define CLKDM_NO_AUTODEPS			(1 << 4)
>  #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
> +#define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
>  
>  #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
>  #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
> @@ -188,6 +201,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
>  void clkdm_allow_idle(struct clockdomain *clkdm);
>  void clkdm_deny_idle(struct clockdomain *clkdm);
>  bool clkdm_in_hwsup(struct clockdomain *clkdm);
> +bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
>  
>  int clkdm_wakeup(struct clockdomain *clkdm);
>  int clkdm_sleep(struct clockdomain *clkdm);
> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> index a0d68db..09385a9 100644
> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> @@ -162,6 +162,37 @@ static void _disable_hwsup(struct clockdomain *clkdm)
>  						clkdm->clktrctrl_mask);
>  }
>  
> +static int omap3_clkdm_sleep(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
> +				      clkdm->clktrctrl_mask);
> +	return 0;
> +}
> +
> +static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
> +				       clkdm->clktrctrl_mask);
> +	return 0;
> +}
> +
> +static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
> +{
> +	if (atomic_read(&clkdm->usecount) > 0)
> +		_clkdm_add_autodeps(clkdm);
> +
> +	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +				       clkdm->clktrctrl_mask);
> +}
> +
> +static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
> +{
> +	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> +					clkdm->clktrctrl_mask);
> +
> +	if (atomic_read(&clkdm->usecount) > 0)
> +		_clkdm_del_autodeps(clkdm);
> +}
>  
>  static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>  {
> @@ -170,6 +201,18 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & (CLKDM_MISSING_IDLE_REPORTING |
> +			    CLKDM_CAN_FORCE_WAKEUP)) {
> +		(cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
> +			omap3_clkdm_wakeup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);
>  
> @@ -193,6 +236,17 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +		_enable_hwsup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);
>  
> @@ -209,38 +263,6 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
>  	return 0;
>  }
>  
> -static int omap3_clkdm_sleep(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -	return 0;
> -}
> -
> -static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -	return 0;
> -}
> -
> -static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
> -{
> -	if (atomic_read(&clkdm->usecount) > 0)
> -		_clkdm_add_autodeps(clkdm);
> -
> -	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -}
> -
> -static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
> -{
> -	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
> -				clkdm->clktrctrl_mask);
> -
> -	if (atomic_read(&clkdm->usecount) > 0)
> -		_clkdm_del_autodeps(clkdm);
> -}
> -
>  struct clkdm_ops omap2_clkdm_operations = {
>  	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,
>  	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep,
> diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
> index 762f2cc..6fc6155 100644
> --- a/arch/arm/mach-omap2/clockdomain44xx.c
> +++ b/arch/arm/mach-omap2/clockdomain44xx.c
> @@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
>  	if (!clkdm->prcm_partition)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +		omap4_clkdm_allow_idle(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
>  					clkdm->cm_inst, clkdm->clkdm_offs);
>  
> diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> index 56089c4..933a35c 100644
> --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
> +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
> @@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
>  	.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
> - */
>  static struct clockdomain emu_clkdm = {
>  	.name		= "emu_clkdm",
>  	.pwrdm		= { .name = "emu_pwrdm" },
> -	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
> +	.flags		= (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
> +			   CLKDM_MISSING_IDLE_REPORTING),
>  	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
>  };
>  
> diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
> index 63d60a7..b56d06b 100644
> --- a/arch/arm/mach-omap2/clockdomains44xx_data.c
> +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
> @@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
>  	.prcm_partition	  = OMAP4430_PRM_PARTITION,
>  	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
>  	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
> -	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
> +	.flags		  = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
> +			     CLKDM_MISSING_IDLE_REPORTING),
>  };
>  
>  static struct clockdomain l3_dma_44xx_clkdm = {
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 6ca8e51..36f0603 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -1857,7 +1857,8 @@ static int _enable(struct omap_hwmod *oh)
>  		 * completely the module. The clockdomain can be set
>  		 * in HW_AUTO only when the module become ready.
>  		 */
> -		hwsup = clkdm_in_hwsup(oh->clkdm);
> +		hwsup = clkdm_in_hwsup(oh->clkdm) &&
> +			!clkdm_missing_idle_reporting(oh->clkdm);
>  		r = clkdm_hwmod_enable(oh->clkdm, oh);
>  		if (r) {
>  			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
> 

Thanks for the detailed suggestion! Adding a flag to prevent programming
the HW_AUTO while the CLKDM is active could definitely work (although I
may change the name/description of the flag a little).

Another proposal I also thought of is re-working the flags to describe
the HW mode to be used when turning on the CLKDM, when the CLKDM is
active and when the CLKDM is shut down. So instead of saying what modes
the CLKDM supports, specify what modes should be used for pre-ON (i.e.
turn ON), ON and OFF. Right now software is trying to decide for us by
what is available (which is ideal) but makes working around such nuances
a little more painful.

By the way, I did do some testing on OMAP3, but I don't recall now
whether I was having such problems with OMAP3. I need to go back and
test perf again on OMAP3 to see if such a flag is needed.

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-13 13:54       ` Jon Hunter
@ 2012-07-13 14:00         ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-13 14:00 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Paul Walmsley, linux-omap, linux-arm, Ming Lei, Benoit Cousson,
	Kevin Hilman

Jon,

[cutting out realms of context!]

On Fri, Jul 13, 2012 at 02:54:59PM +0100, Jon Hunter wrote:
> Another proposal I also thought of is re-working the flags to describe
> the HW mode to be used when turning on the CLKDM, when the CLKDM is
> active and when the CLKDM is shut down. So instead of saying what modes
> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
> turn ON), ON and OFF. Right now software is trying to decide for us by
> what is available (which is ideal) but makes working around such nuances
> a little more painful.
> 
> By the way, I did do some testing on OMAP3, but I don't recall now
> whether I was having such problems with OMAP3. I need to go back and
> test perf again on OMAP3 to see if such a flag is needed.

If you do test on OMAP3, please kill the OMAP3_EMU option as I think this
has the effect of keeping the EMU power domain up via the etm code (look at
etb_probe).

Will

---8<---

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91009c..d02054c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1139,8 +1139,7 @@ config XSCALE_PMU
        default y
 
 config CPU_HAS_PMU
-       depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
-                  (!ARCH_OMAP3 || OMAP3_EMU)
+       depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU)
        default y
        bool
 

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-13 14:00         ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-13 14:00 UTC (permalink / raw)
  To: linux-arm-kernel

Jon,

[cutting out realms of context!]

On Fri, Jul 13, 2012 at 02:54:59PM +0100, Jon Hunter wrote:
> Another proposal I also thought of is re-working the flags to describe
> the HW mode to be used when turning on the CLKDM, when the CLKDM is
> active and when the CLKDM is shut down. So instead of saying what modes
> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
> turn ON), ON and OFF. Right now software is trying to decide for us by
> what is available (which is ideal) but makes working around such nuances
> a little more painful.
> 
> By the way, I did do some testing on OMAP3, but I don't recall now
> whether I was having such problems with OMAP3. I need to go back and
> test perf again on OMAP3 to see if such a flag is needed.

If you do test on OMAP3, please kill the OMAP3_EMU option as I think this
has the effect of keeping the EMU power domain up via the etm code (look at
etb_probe).

Will

---8<---

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91009c..d02054c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1139,8 +1139,7 @@ config XSCALE_PMU
        default y
 
 config CPU_HAS_PMU
-       depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
-                  (!ARCH_OMAP3 || OMAP3_EMU)
+       depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU)
        default y
        bool
 

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-13 14:00         ` Will Deacon
@ 2012-07-13 14:07           ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-13 14:07 UTC (permalink / raw)
  To: Will Deacon
  Cc: Paul Walmsley, linux-omap, linux-arm, Ming Lei, Benoit Cousson,
	Kevin Hilman

Hi Will,

On 07/13/2012 09:00 AM, Will Deacon wrote:
> Jon,
> 
> [cutting out realms of context!]

Thanks! My inbox thanks you too ;-)

> On Fri, Jul 13, 2012 at 02:54:59PM +0100, Jon Hunter wrote:
>> Another proposal I also thought of is re-working the flags to describe
>> the HW mode to be used when turning on the CLKDM, when the CLKDM is
>> active and when the CLKDM is shut down. So instead of saying what modes
>> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
>> turn ON), ON and OFF. Right now software is trying to decide for us by
>> what is available (which is ideal) but makes working around such nuances
>> a little more painful.
>>
>> By the way, I did do some testing on OMAP3, but I don't recall now
>> whether I was having such problems with OMAP3. I need to go back and
>> test perf again on OMAP3 to see if such a flag is needed.
> 
> If you do test on OMAP3, please kill the OMAP3_EMU option as I think this
> has the effect of keeping the EMU power domain up via the etm code (look at
> etb_probe).
> 
> Will
> 
> ---8<---
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index a91009c..d02054c 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1139,8 +1139,7 @@ config XSCALE_PMU
>         default y
>  
>  config CPU_HAS_PMU
> -       depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
> -                  (!ARCH_OMAP3 || OMAP3_EMU)
> +       depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU)
>         default y
>         bool

Ah-ha! May be this is why is worked without issue. I will look at that
and check the power states. I must admit that my testing was quick to
ensure no breakages but no thorough to check what was going on with power.

Cheers
Jon




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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-13 14:07           ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-13 14:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 07/13/2012 09:00 AM, Will Deacon wrote:
> Jon,
> 
> [cutting out realms of context!]

Thanks! My inbox thanks you too ;-)

> On Fri, Jul 13, 2012 at 02:54:59PM +0100, Jon Hunter wrote:
>> Another proposal I also thought of is re-working the flags to describe
>> the HW mode to be used when turning on the CLKDM, when the CLKDM is
>> active and when the CLKDM is shut down. So instead of saying what modes
>> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
>> turn ON), ON and OFF. Right now software is trying to decide for us by
>> what is available (which is ideal) but makes working around such nuances
>> a little more painful.
>>
>> By the way, I did do some testing on OMAP3, but I don't recall now
>> whether I was having such problems with OMAP3. I need to go back and
>> test perf again on OMAP3 to see if such a flag is needed.
> 
> If you do test on OMAP3, please kill the OMAP3_EMU option as I think this
> has the effect of keeping the EMU power domain up via the etm code (look at
> etb_probe).
> 
> Will
> 
> ---8<---
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index a91009c..d02054c 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1139,8 +1139,7 @@ config XSCALE_PMU
>         default y
>  
>  config CPU_HAS_PMU
> -       depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
> -                  (!ARCH_OMAP3 || OMAP3_EMU)
> +       depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU)
>         default y
>         bool

Ah-ha! May be this is why is worked without issue. I will look at that
and check the power states. I must admit that my testing was quick to
ensure no breakages but no thorough to check what was going on with power.

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-13 13:54       ` Jon Hunter
@ 2012-07-13 21:00         ` Paul Walmsley
  -1 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-07-13 21:00 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hi Jon

On Fri, 13 Jul 2012, Jon Hunter wrote:

> On 07/12/2012 04:17 PM, Paul Walmsley wrote:
> > On Thu, 7 Jun 2012, Jon Hunter wrote:
> > 
> > Hmm, it would be nice if we could keep the CLKDM_CAN_* flags matching the 
> > hardware capabilities.  Looking at the 4430 TRM Rev X Table 3-744 
> > "CM_EMU_CLKSTCTRL", the CLKTRCTRL field isn't documented as supporting the 
> > SW_SLEEP mode (which CLKDM_CAN_FORCE_SLEEP will set).
> 
> Right, however, this was part of the recommendation from Benoit. In
> patch #7 of this series we actually made the following modification ...

[ ... ]

> So now, by setting CLKDM_CAN_FORCE_SLEEP we are actually enabling
> HW_AUTO and not SW_SLEEP (for OMAP4). This was the purpose of patch #7
> was to remove the SW_SLEEP for OMAP4 as it is equivalent to HW_AUTO when
> using it to disable the module. 

OK, that's right.

> Unfortunately, although this works it does make the flags a bit less 
> clearer. The upside is the solution is simpler.

Yeah, the problem is the clockdomain CLKDM_CAN_* flags are just intended 
to represent the available bits from the register bitfield, rather than a 
higher-level concept.  Among other things, it allows the maintainers and 
users of this code to verify it by comparing it to the TRM.  Changing the 
CLKDM_CAN_* flags in the kernel is not actually that simple since it 
involves overriding the hardware data for the EMU clockdomain for every 
applicable chip.  In other words, it just moves the complexity 
elsewhere.

> I am not sure if it is really a matter of the clock domain missing the
> idle reporting, but more of a problem that the EMU power domain power
> state is programmed in HW to OFF and cannot be changed by software. (see
> POWER_STATE field of PM_EMU_PWRSTCTRL register description in the TRM).
> 
> This means that when the EMU clock domain does idle, the EMU power
> domain can transition to OFF and hence we loss the EMU logic context. So
> we need to keep the EMU CLKDM on to keep the EMU PWRDM on, but it is
> really the lack of control we have over the PWRDM that is the problem. I
> would not say this is a HW bug but more of a design choice probably to
> keep the design simpler at the expense of power.

I really wonder how much more difficult it would have been to add the 
ON state to the EMU powerdomain next-power-state control bitfields...

> I believe that this problem would happen to all power domains if they
> were programmed for the OFF power state when the clock domain idled. For
> other power domains we avoid this by programming them to the ON state
> when we are using them.

Hmm.  In the case of most other clockdomains, we have some way to indicate 
to the PRCM whether the IP block/clock is in use or not: functional clock 
control bits or modulemode control bits or CLKACTIVITY bits or (in the 
worst case) SIDLEMODE bits.  We don't really have any of these control 
mechanisms for most of the EMU clockdomain IP blocks/clocks.

>From a theoretical perspective, assigning the problem solely to the 
powerdomain next-power-state bits might also ignore the impact on 
clockdomain dependencies.  These take effect based on the clockdomain 
activity state, rather than powerdomain next-power-states.  Although, for 
the specific case of the EMU clockdomains on OMAP3/4, it looks like this 
is not a practical problem according to the TRM.

> Thanks for the detailed suggestion! Adding a flag to prevent programming
> the HW_AUTO while the CLKDM is active could definitely work (although I
> may change the name/description of the flag a little).

Sure, let me know what you think of the above reasoning.

> Another proposal I also thought of is re-working the flags to describe
> the HW mode to be used when turning on the CLKDM, when the CLKDM is
> active and when the CLKDM is shut down. So instead of saying what modes
> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
> turn ON), ON and OFF. Right now software is trying to decide for us by
> what is available (which is ideal) but makes working around such nuances
> a little more painful.

With the hardware data, it would be good to keep it something that can be 
generated with as little human intervention as possible, except in the 
case of bug workarounds or departures from standard practice.  The idea is 
to reduce the amount of human interaction needed to generate data to 
support new chips, when everything works as it should.  It also allows us 
software forks to explicitly mark unusual quirks or bugs that we'd like 
the hardware people to change for future revisions :-)


- Paul

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-13 21:00         ` Paul Walmsley
  0 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-07-13 21:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon

On Fri, 13 Jul 2012, Jon Hunter wrote:

> On 07/12/2012 04:17 PM, Paul Walmsley wrote:
> > On Thu, 7 Jun 2012, Jon Hunter wrote:
> > 
> > Hmm, it would be nice if we could keep the CLKDM_CAN_* flags matching the 
> > hardware capabilities.  Looking at the 4430 TRM Rev X Table 3-744 
> > "CM_EMU_CLKSTCTRL", the CLKTRCTRL field isn't documented as supporting the 
> > SW_SLEEP mode (which CLKDM_CAN_FORCE_SLEEP will set).
> 
> Right, however, this was part of the recommendation from Benoit. In
> patch #7 of this series we actually made the following modification ...

[ ... ]

> So now, by setting CLKDM_CAN_FORCE_SLEEP we are actually enabling
> HW_AUTO and not SW_SLEEP (for OMAP4). This was the purpose of patch #7
> was to remove the SW_SLEEP for OMAP4 as it is equivalent to HW_AUTO when
> using it to disable the module. 

OK, that's right.

> Unfortunately, although this works it does make the flags a bit less 
> clearer. The upside is the solution is simpler.

Yeah, the problem is the clockdomain CLKDM_CAN_* flags are just intended 
to represent the available bits from the register bitfield, rather than a 
higher-level concept.  Among other things, it allows the maintainers and 
users of this code to verify it by comparing it to the TRM.  Changing the 
CLKDM_CAN_* flags in the kernel is not actually that simple since it 
involves overriding the hardware data for the EMU clockdomain for every 
applicable chip.  In other words, it just moves the complexity 
elsewhere.

> I am not sure if it is really a matter of the clock domain missing the
> idle reporting, but more of a problem that the EMU power domain power
> state is programmed in HW to OFF and cannot be changed by software. (see
> POWER_STATE field of PM_EMU_PWRSTCTRL register description in the TRM).
> 
> This means that when the EMU clock domain does idle, the EMU power
> domain can transition to OFF and hence we loss the EMU logic context. So
> we need to keep the EMU CLKDM on to keep the EMU PWRDM on, but it is
> really the lack of control we have over the PWRDM that is the problem. I
> would not say this is a HW bug but more of a design choice probably to
> keep the design simpler at the expense of power.

I really wonder how much more difficult it would have been to add the 
ON state to the EMU powerdomain next-power-state control bitfields...

> I believe that this problem would happen to all power domains if they
> were programmed for the OFF power state when the clock domain idled. For
> other power domains we avoid this by programming them to the ON state
> when we are using them.

Hmm.  In the case of most other clockdomains, we have some way to indicate 
to the PRCM whether the IP block/clock is in use or not: functional clock 
control bits or modulemode control bits or CLKACTIVITY bits or (in the 
worst case) SIDLEMODE bits.  We don't really have any of these control 
mechanisms for most of the EMU clockdomain IP blocks/clocks.

>From a theoretical perspective, assigning the problem solely to the 
powerdomain next-power-state bits might also ignore the impact on 
clockdomain dependencies.  These take effect based on the clockdomain 
activity state, rather than powerdomain next-power-states.  Although, for 
the specific case of the EMU clockdomains on OMAP3/4, it looks like this 
is not a practical problem according to the TRM.

> Thanks for the detailed suggestion! Adding a flag to prevent programming
> the HW_AUTO while the CLKDM is active could definitely work (although I
> may change the name/description of the flag a little).

Sure, let me know what you think of the above reasoning.

> Another proposal I also thought of is re-working the flags to describe
> the HW mode to be used when turning on the CLKDM, when the CLKDM is
> active and when the CLKDM is shut down. So instead of saying what modes
> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
> turn ON), ON and OFF. Right now software is trying to decide for us by
> what is available (which is ideal) but makes working around such nuances
> a little more painful.

With the hardware data, it would be good to keep it something that can be 
generated with as little human intervention as possible, except in the 
case of bug workarounds or departures from standard practice.  The idea is 
to reduce the amount of human interaction needed to generate data to 
support new chips, when everything works as it should.  It also allows us 
software forks to explicitly mark unusual quirks or bugs that we'd like 
the hardware people to change for future revisions :-)


- Paul

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-13 21:00         ` Paul Walmsley
@ 2012-07-16 18:27           ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-16 18:27 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hi Paul,

On 07/13/2012 04:00 PM, Paul Walmsley wrote:

[...]

>> Unfortunately, although this works it does make the flags a bit less 
>> clearer. The upside is the solution is simpler.
> 
> Yeah, the problem is the clockdomain CLKDM_CAN_* flags are just intended 
> to represent the available bits from the register bitfield, rather than a 
> higher-level concept.  Among other things, it allows the maintainers and 
> users of this code to verify it by comparing it to the TRM.  Changing the 
> CLKDM_CAN_* flags in the kernel is not actually that simple since it 
> involves overriding the hardware data for the EMU clockdomain for every 
> applicable chip.  In other words, it just moves the complexity 
> elsewhere.

Yes I see that makes sense. However, patch #7 has already changed the
mapping of the flags. I had intended that patch #7 and #8 would be
applied together. However, I could see that patch #7 can be taken just
to eliminate using the SW_SLEEP state. So basically, what I am saying is
does patch #7 have any value without #8?

>> I am not sure if it is really a matter of the clock domain missing the
>> idle reporting, but more of a problem that the EMU power domain power
>> state is programmed in HW to OFF and cannot be changed by software. (see
>> POWER_STATE field of PM_EMU_PWRSTCTRL register description in the TRM).
>>
>> This means that when the EMU clock domain does idle, the EMU power
>> domain can transition to OFF and hence we loss the EMU logic context. So
>> we need to keep the EMU CLKDM on to keep the EMU PWRDM on, but it is
>> really the lack of control we have over the PWRDM that is the problem. I
>> would not say this is a HW bug but more of a design choice probably to
>> keep the design simpler at the expense of power.
> 
> I really wonder how much more difficult it would have been to add the 
> ON state to the EMU powerdomain next-power-state control bitfields...

True, probably a good area for us to provide some feedback to the
designers.

>> I believe that this problem would happen to all power domains if they
>> were programmed for the OFF power state when the clock domain idled. For
>> other power domains we avoid this by programming them to the ON state
>> when we are using them.
> 
> Hmm.  In the case of most other clockdomains, we have some way to indicate 
> to the PRCM whether the IP block/clock is in use or not: functional clock 
> control bits or modulemode control bits or CLKACTIVITY bits or (in the 
> worst case) SIDLEMODE bits.  We don't really have any of these control 
> mechanisms for most of the EMU clockdomain IP blocks/clocks.
> 
> From a theoretical perspective, assigning the problem solely to the 
> powerdomain next-power-state bits might also ignore the impact on 
> clockdomain dependencies.  These take effect based on the clockdomain 
> activity state, rather than powerdomain next-power-states.  Although, for 
> the specific case of the EMU clockdomains on OMAP3/4, it looks like this 
> is not a practical problem according to the TRM.

Ok, yes I understand your point of view.

>> Thanks for the detailed suggestion! Adding a flag to prevent programming
>> the HW_AUTO while the CLKDM is active could definitely work (although I
>> may change the name/description of the flag a little).
> 
> Sure, let me know what you think of the above reasoning.

I would say it is fair (with limited knowledge of the h/w design
decisions made here).

>> Another proposal I also thought of is re-working the flags to describe
>> the HW mode to be used when turning on the CLKDM, when the CLKDM is
>> active and when the CLKDM is shut down. So instead of saying what modes
>> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
>> turn ON), ON and OFF. Right now software is trying to decide for us by
>> what is available (which is ideal) but makes working around such nuances
>> a little more painful.
> 
> With the hardware data, it would be good to keep it something that can be 
> generated with as little human intervention as possible, except in the 
> case of bug workarounds or departures from standard practice.  The idea is 
> to reduce the amount of human interaction needed to generate data to 
> support new chips, when everything works as it should.  It also allows us 
> software forks to explicitly mark unusual quirks or bugs that we'd like 
> the hardware people to change for future revisions :-)

That's fine with me. We can always workaround such issues by adding flags.

I can give this a try this week and let you know how it goes.

I think that Benoit is out until the end of the month. I am not sure if
he will have any inputs.

Cheers
Jon

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-16 18:27           ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-16 18:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/13/2012 04:00 PM, Paul Walmsley wrote:

[...]

>> Unfortunately, although this works it does make the flags a bit less 
>> clearer. The upside is the solution is simpler.
> 
> Yeah, the problem is the clockdomain CLKDM_CAN_* flags are just intended 
> to represent the available bits from the register bitfield, rather than a 
> higher-level concept.  Among other things, it allows the maintainers and 
> users of this code to verify it by comparing it to the TRM.  Changing the 
> CLKDM_CAN_* flags in the kernel is not actually that simple since it 
> involves overriding the hardware data for the EMU clockdomain for every 
> applicable chip.  In other words, it just moves the complexity 
> elsewhere.

Yes I see that makes sense. However, patch #7 has already changed the
mapping of the flags. I had intended that patch #7 and #8 would be
applied together. However, I could see that patch #7 can be taken just
to eliminate using the SW_SLEEP state. So basically, what I am saying is
does patch #7 have any value without #8?

>> I am not sure if it is really a matter of the clock domain missing the
>> idle reporting, but more of a problem that the EMU power domain power
>> state is programmed in HW to OFF and cannot be changed by software. (see
>> POWER_STATE field of PM_EMU_PWRSTCTRL register description in the TRM).
>>
>> This means that when the EMU clock domain does idle, the EMU power
>> domain can transition to OFF and hence we loss the EMU logic context. So
>> we need to keep the EMU CLKDM on to keep the EMU PWRDM on, but it is
>> really the lack of control we have over the PWRDM that is the problem. I
>> would not say this is a HW bug but more of a design choice probably to
>> keep the design simpler at the expense of power.
> 
> I really wonder how much more difficult it would have been to add the 
> ON state to the EMU powerdomain next-power-state control bitfields...

True, probably a good area for us to provide some feedback to the
designers.

>> I believe that this problem would happen to all power domains if they
>> were programmed for the OFF power state when the clock domain idled. For
>> other power domains we avoid this by programming them to the ON state
>> when we are using them.
> 
> Hmm.  In the case of most other clockdomains, we have some way to indicate 
> to the PRCM whether the IP block/clock is in use or not: functional clock 
> control bits or modulemode control bits or CLKACTIVITY bits or (in the 
> worst case) SIDLEMODE bits.  We don't really have any of these control 
> mechanisms for most of the EMU clockdomain IP blocks/clocks.
> 
> From a theoretical perspective, assigning the problem solely to the 
> powerdomain next-power-state bits might also ignore the impact on 
> clockdomain dependencies.  These take effect based on the clockdomain 
> activity state, rather than powerdomain next-power-states.  Although, for 
> the specific case of the EMU clockdomains on OMAP3/4, it looks like this 
> is not a practical problem according to the TRM.

Ok, yes I understand your point of view.

>> Thanks for the detailed suggestion! Adding a flag to prevent programming
>> the HW_AUTO while the CLKDM is active could definitely work (although I
>> may change the name/description of the flag a little).
> 
> Sure, let me know what you think of the above reasoning.

I would say it is fair (with limited knowledge of the h/w design
decisions made here).

>> Another proposal I also thought of is re-working the flags to describe
>> the HW mode to be used when turning on the CLKDM, when the CLKDM is
>> active and when the CLKDM is shut down. So instead of saying what modes
>> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
>> turn ON), ON and OFF. Right now software is trying to decide for us by
>> what is available (which is ideal) but makes working around such nuances
>> a little more painful.
> 
> With the hardware data, it would be good to keep it something that can be 
> generated with as little human intervention as possible, except in the 
> case of bug workarounds or departures from standard practice.  The idea is 
> to reduce the amount of human interaction needed to generate data to 
> support new chips, when everything works as it should.  It also allows us 
> software forks to explicitly mark unusual quirks or bugs that we'd like 
> the hardware people to change for future revisions :-)

That's fine with me. We can always workaround such issues by adding flags.

I can give this a try this week and let you know how it goes.

I think that Benoit is out until the end of the month. I am not sure if
he will have any inputs.

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-16 18:27           ` Jon Hunter
@ 2012-07-16 18:38             ` Paul Walmsley
  -1 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-07-16 18:38 UTC (permalink / raw)
  To: Jon Hunter
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1405 bytes --]

Hi Jon,

On Mon, 16 Jul 2012, Jon Hunter wrote:

> Yes I see that makes sense. However, patch #7 has already changed the
> mapping of the flags. I had intended that patch #7 and #8 would be
> applied together. However, I could see that patch #7 can be taken just
> to eliminate using the SW_SLEEP state. So basically, what I am saying is
> does patch #7 have any value without #8?

Certainly not as much value as it had before.  But my understanding, which 
is possibly incorrect, matches what you wrote in patch #7's description:

"For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is 
equivalent to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP 
for OMAP4 devices is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt 
status is set in case of SW_SLEEP transition, and not set in case of 
HW_AUTO transition."

We don't use that PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt bit.  So if 
SW_SLEEP and HW_AUTO really have identical meanings otherwise, then I 
suppose we might as well use the one that does what we need with no 
extraneous side-effects?  My recollection from a conversation with Benoît 
a few months ago was that this was his view as well.

> That's fine with me. We can always workaround such issues by adding flags.
> 
> I can give this a try this week and let you know how it goes.

Okay, great.  No rush on my account.


- Paul

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-16 18:38             ` Paul Walmsley
  0 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-07-16 18:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

On Mon, 16 Jul 2012, Jon Hunter wrote:

> Yes I see that makes sense. However, patch #7 has already changed the
> mapping of the flags. I had intended that patch #7 and #8 would be
> applied together. However, I could see that patch #7 can be taken just
> to eliminate using the SW_SLEEP state. So basically, what I am saying is
> does patch #7 have any value without #8?

Certainly not as much value as it had before.  But my understanding, which 
is possibly incorrect, matches what you wrote in patch #7's description:

"For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is 
equivalent to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP 
for OMAP4 devices is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt 
status is set in case of SW_SLEEP transition, and not set in case of 
HW_AUTO transition."

We don't use that PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt bit.  So if 
SW_SLEEP and HW_AUTO really have identical meanings otherwise, then I 
suppose we might as well use the one that does what we need with no 
extraneous side-effects?  My recollection from a conversation with Beno?t 
a few months ago was that this was his view as well.

> That's fine with me. We can always workaround such issues by adding flags.
> 
> I can give this a try this week and let you know how it goes.

Okay, great.  No rush on my account.


- Paul

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-16 18:38             ` Paul Walmsley
@ 2012-07-16 19:38               ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-16 19:38 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hi Paul,

On 07/16/2012 01:38 PM, Paul Walmsley wrote:
> Hi Jon,
> 
> On Mon, 16 Jul 2012, Jon Hunter wrote:
> 
>> Yes I see that makes sense. However, patch #7 has already changed the
>> mapping of the flags. I had intended that patch #7 and #8 would be
>> applied together. However, I could see that patch #7 can be taken just
>> to eliminate using the SW_SLEEP state. So basically, what I am saying is
>> does patch #7 have any value without #8?
> 
> Certainly not as much value as it had before.  But my understanding, which 
> is possibly incorrect, matches what you wrote in patch #7's description:
> 
> "For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is 
> equivalent to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP 
> for OMAP4 devices is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt 
> status is set in case of SW_SLEEP transition, and not set in case of 
> HW_AUTO transition."
> 
> We don't use that PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt bit.  So if 
> SW_SLEEP and HW_AUTO really have identical meanings otherwise, then I 
> suppose we might as well use the one that does what we need with no 
> extraneous side-effects?  My recollection from a conversation with Benoît 
> a few months ago was that this was his view as well.

Yes that is my understanding too. So from that standpoint it is fine to
keep. However, I just wanted to make sure I understood your thinking here.

>> That's fine with me. We can always workaround such issues by adding flags.
>>
>> I can give this a try this week and let you know how it goes.
> 
> Okay, great.  No rush on my account.

Ok. I have a few items on my plate that keep preventing me from getting
back to this, but what to get this done.

Jon
--
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] 118+ messages in thread

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-16 19:38               ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-16 19:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/16/2012 01:38 PM, Paul Walmsley wrote:
> Hi Jon,
> 
> On Mon, 16 Jul 2012, Jon Hunter wrote:
> 
>> Yes I see that makes sense. However, patch #7 has already changed the
>> mapping of the flags. I had intended that patch #7 and #8 would be
>> applied together. However, I could see that patch #7 can be taken just
>> to eliminate using the SW_SLEEP state. So basically, what I am saying is
>> does patch #7 have any value without #8?
> 
> Certainly not as much value as it had before.  But my understanding, which 
> is possibly incorrect, matches what you wrote in patch #7's description:
> 
> "For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is 
> equivalent to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP 
> for OMAP4 devices is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt 
> status is set in case of SW_SLEEP transition, and not set in case of 
> HW_AUTO transition."
> 
> We don't use that PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt bit.  So if 
> SW_SLEEP and HW_AUTO really have identical meanings otherwise, then I 
> suppose we might as well use the one that does what we need with no 
> extraneous side-effects?  My recollection from a conversation with Beno?t 
> a few months ago was that this was his view as well.

Yes that is my understanding too. So from that standpoint it is fine to
keep. However, I just wanted to make sure I understood your thinking here.

>> That's fine with me. We can always workaround such issues by adding flags.
>>
>> I can give this a try this week and let you know how it goes.
> 
> Okay, great.  No rush on my account.

Ok. I have a few items on my plate that keep preventing me from getting
back to this, but what to get this done.

Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-16 18:38             ` Paul Walmsley
@ 2012-07-20 22:24               ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-20 22:24 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hi Paul,

On 07/16/2012 01:38 PM, Paul Walmsley wrote:
> Hi Jon,
> 
> On Mon, 16 Jul 2012, Jon Hunter wrote:
> 
>> Yes I see that makes sense. However, patch #7 has already changed the
>> mapping of the flags. I had intended that patch #7 and #8 would be
>> applied together. However, I could see that patch #7 can be taken just
>> to eliminate using the SW_SLEEP state. So basically, what I am saying is
>> does patch #7 have any value without #8?
> 
> Certainly not as much value as it had before.  But my understanding, which 
> is possibly incorrect, matches what you wrote in patch #7's description:
> 
> "For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is 
> equivalent to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP 
> for OMAP4 devices is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt 
> status is set in case of SW_SLEEP transition, and not set in case of 
> HW_AUTO transition."
> 
> We don't use that PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt bit.  So if 
> SW_SLEEP and HW_AUTO really have identical meanings otherwise, then I 
> suppose we might as well use the one that does what we need with no 
> extraneous side-effects?  My recollection from a conversation with Benoît 
> a few months ago was that this was his view as well.
> 
>> That's fine with me. We can always workaround such issues by adding flags.
>>
>> I can give this a try this week and let you know how it goes.
> 
> Okay, great.  No rush on my account.

I have been testing this today and is working well for OMAP4. However, I
noticed that this is not working for OMAP3. The problem for OMAP3 is
that we don't have hwmod support for the debugss in OMAP3 and so the
flag CLKDM_CAN_ENABLE_AUTO is shutting down the EMU PD on boot. To be
honest it is clear to me now that PMU support on OMAP3 needs some work
as it is dependent on the ETM driver as highlighted by Will.

So I think that this patch will work but I need to create a hwmod for
OMAP3's debugss. Are you able to generate this or just Benoit? I could
probably create something by hand but did not know if we could
auto-generate.

Cheers
Jon
--
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] 118+ messages in thread

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-20 22:24               ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-20 22:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/16/2012 01:38 PM, Paul Walmsley wrote:
> Hi Jon,
> 
> On Mon, 16 Jul 2012, Jon Hunter wrote:
> 
>> Yes I see that makes sense. However, patch #7 has already changed the
>> mapping of the flags. I had intended that patch #7 and #8 would be
>> applied together. However, I could see that patch #7 can be taken just
>> to eliminate using the SW_SLEEP state. So basically, what I am saying is
>> does patch #7 have any value without #8?
> 
> Certainly not as much value as it had before.  But my understanding, which 
> is possibly incorrect, matches what you wrote in patch #7's description:
> 
> "For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is 
> equivalent to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP 
> for OMAP4 devices is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt 
> status is set in case of SW_SLEEP transition, and not set in case of 
> HW_AUTO transition."
> 
> We don't use that PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt bit.  So if 
> SW_SLEEP and HW_AUTO really have identical meanings otherwise, then I 
> suppose we might as well use the one that does what we need with no 
> extraneous side-effects?  My recollection from a conversation with Beno?t 
> a few months ago was that this was his view as well.
> 
>> That's fine with me. We can always workaround such issues by adding flags.
>>
>> I can give this a try this week and let you know how it goes.
> 
> Okay, great.  No rush on my account.

I have been testing this today and is working well for OMAP4. However, I
noticed that this is not working for OMAP3. The problem for OMAP3 is
that we don't have hwmod support for the debugss in OMAP3 and so the
flag CLKDM_CAN_ENABLE_AUTO is shutting down the EMU PD on boot. To be
honest it is clear to me now that PMU support on OMAP3 needs some work
as it is dependent on the ETM driver as highlighted by Will.

So I think that this patch will work but I need to create a hwmod for
OMAP3's debugss. Are you able to generate this or just Benoit? I could
probably create something by hand but did not know if we could
auto-generate.

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-13 14:00         ` Will Deacon
@ 2012-07-20 22:24           ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-20 22:24 UTC (permalink / raw)
  To: Will Deacon
  Cc: Paul Walmsley, linux-omap, linux-arm, Ming Lei, Benoit Cousson,
	Kevin Hilman

Hi Will,

On 07/13/2012 09:00 AM, Will Deacon wrote:
> Jon,
> 
> [cutting out realms of context!]
> 
> On Fri, Jul 13, 2012 at 02:54:59PM +0100, Jon Hunter wrote:
>> Another proposal I also thought of is re-working the flags to describe
>> the HW mode to be used when turning on the CLKDM, when the CLKDM is
>> active and when the CLKDM is shut down. So instead of saying what modes
>> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
>> turn ON), ON and OFF. Right now software is trying to decide for us by
>> what is available (which is ideal) but makes working around such nuances
>> a little more painful.
>>
>> By the way, I did do some testing on OMAP3, but I don't recall now
>> whether I was having such problems with OMAP3. I need to go back and
>> test perf again on OMAP3 to see if such a flag is needed.
> 
> If you do test on OMAP3, please kill the OMAP3_EMU option as I think this
> has the effect of keeping the EMU power domain up via the etm code (look at
> etb_probe).

You are right. Removing that options breaks PMU on OMAP3. I need to add
hwmod support for the debugss on OMAP3.

Cheers
Jon

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-20 22:24           ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-20 22:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 07/13/2012 09:00 AM, Will Deacon wrote:
> Jon,
> 
> [cutting out realms of context!]
> 
> On Fri, Jul 13, 2012 at 02:54:59PM +0100, Jon Hunter wrote:
>> Another proposal I also thought of is re-working the flags to describe
>> the HW mode to be used when turning on the CLKDM, when the CLKDM is
>> active and when the CLKDM is shut down. So instead of saying what modes
>> the CLKDM supports, specify what modes should be used for pre-ON (i.e.
>> turn ON), ON and OFF. Right now software is trying to decide for us by
>> what is available (which is ideal) but makes working around such nuances
>> a little more painful.
>>
>> By the way, I did do some testing on OMAP3, but I don't recall now
>> whether I was having such problems with OMAP3. I need to go back and
>> test perf again on OMAP3 to see if such a flag is needed.
> 
> If you do test on OMAP3, please kill the OMAP3_EMU option as I think this
> has the effect of keeping the EMU power domain up via the etm code (look at
> etb_probe).

You are right. Removing that options breaks PMU on OMAP3. I need to add
hwmod support for the debugss on OMAP3.

Cheers
Jon

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-06  0:40                           ` Jon Hunter
@ 2012-07-26  0:41                             ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-26  0:41 UTC (permalink / raw)
  To: Will Deacon
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

Hi Will,

On 07/05/2012 07:40 PM, Jon Hunter wrote:
> Hi Will,
> 
> On 07/02/2012 05:01 PM, Will Deacon wrote:
>> On Mon, Jul 02, 2012 at 05:50:38PM +0100, Jon Hunter wrote:
>>> On 07/02/2012 04:55 AM, Will Deacon wrote:
>>>>
>>>> Did you have any luck getting to the bottom of this?
>>>
>>> I am still waiting for feedback from design. They were trying to confirm
>>> my observations. Unfortunately, it is taking some time. I will ping them
>>> again.
>>
>> Ok, thanks. If pinging doesn't work, bribery can be quite effective with
>> hardware guys :)
> 
> Yes looks like I am going to need to get creative :-)
> 
>>>> It would be good to take your PMU suspend/resume patches once we know that
>>>> they will get used.
>>>
>>> Yes that would be good. I could drop the 4460 specific changes for now
>>> and make 4460 work in the same way as 4430 (using CTI) for the time
>>> being and see if we can get these in. However, I recall that was not
>>> working for you, but it was working fine for me.
>>
>> Indeed, that hack didn't help me and I'd rather not commit it if it only
>> partially fixes the problem. A better bet might just be to go with your
>> original approach and see how many bug reports we receive. That might also
>> help us narrow down the problem, but it's your call.
> 
> Ok, I think that that is best.
> 
>> In the meantime, I pushed what I think is the latest drop of your series to
>> a new branch on kernel.org:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git perf/omap4-dev
> 
> Looks good.

I just wanted to let you know that I have been updating the PMU patches
for OMAP. Latest can be found here [1]. I have not included Paul's patch
[2] in this series at the moment, because although it works well for
OMAP4, I need to create the HWMOD structures for OMAP3. Without these
structures it breaks OMAP3 PMU support. Once this is done we should be
able to get rid for the OMAP3 dependency on ETM. Unfortunately, Benoit
(Mr HWMOD) is out on his holidays but should be back next week and then
maybe he can give me some guidance on this HWMOD stuff.

Cheers
Jon

[1] https://gitorious.org/linux-omap-dev dev-pmu
[2] http://marc.info/?l=linux-omap&m=134212809112530&w=2

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-26  0:41                             ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-26  0:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Will,

On 07/05/2012 07:40 PM, Jon Hunter wrote:
> Hi Will,
> 
> On 07/02/2012 05:01 PM, Will Deacon wrote:
>> On Mon, Jul 02, 2012 at 05:50:38PM +0100, Jon Hunter wrote:
>>> On 07/02/2012 04:55 AM, Will Deacon wrote:
>>>>
>>>> Did you have any luck getting to the bottom of this?
>>>
>>> I am still waiting for feedback from design. They were trying to confirm
>>> my observations. Unfortunately, it is taking some time. I will ping them
>>> again.
>>
>> Ok, thanks. If pinging doesn't work, bribery can be quite effective with
>> hardware guys :)
> 
> Yes looks like I am going to need to get creative :-)
> 
>>>> It would be good to take your PMU suspend/resume patches once we know that
>>>> they will get used.
>>>
>>> Yes that would be good. I could drop the 4460 specific changes for now
>>> and make 4460 work in the same way as 4430 (using CTI) for the time
>>> being and see if we can get these in. However, I recall that was not
>>> working for you, but it was working fine for me.
>>
>> Indeed, that hack didn't help me and I'd rather not commit it if it only
>> partially fixes the problem. A better bet might just be to go with your
>> original approach and see how many bug reports we receive. That might also
>> help us narrow down the problem, but it's your call.
> 
> Ok, I think that that is best.
> 
>> In the meantime, I pushed what I think is the latest drop of your series to
>> a new branch on kernel.org:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git perf/omap4-dev
> 
> Looks good.

I just wanted to let you know that I have been updating the PMU patches
for OMAP. Latest can be found here [1]. I have not included Paul's patch
[2] in this series at the moment, because although it works well for
OMAP4, I need to create the HWMOD structures for OMAP3. Without these
structures it breaks OMAP3 PMU support. Once this is done we should be
able to get rid for the OMAP3 dependency on ETM. Unfortunately, Benoit
(Mr HWMOD) is out on his holidays but should be back next week and then
maybe he can give me some guidance on this HWMOD stuff.

Cheers
Jon

[1] https://gitorious.org/linux-omap-dev dev-pmu
[2] http://marc.info/?l=linux-omap&m=134212809112530&w=2

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-26  0:41                             ` Jon Hunter
@ 2012-07-26 15:05                               ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-26 15:05 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

On Thu, Jul 26, 2012 at 01:41:23AM +0100, Jon Hunter wrote:
> Hi Will,

Hi Jon,

> On 07/05/2012 07:40 PM, Jon Hunter wrote:
> I just wanted to let you know that I have been updating the PMU patches
> for OMAP. Latest can be found here [1]. I have not included Paul's patch
> [2] in this series at the moment, because although it works well for
> OMAP4, I need to create the HWMOD structures for OMAP3. Without these
> structures it breaks OMAP3 PMU support. Once this is done we should be
> able to get rid for the OMAP3 dependency on ETM. Unfortunately, Benoit
> (Mr HWMOD) is out on his holidays but should be back next week and then
> maybe he can give me some guidance on this HWMOD stuff.

Ok, thanks for updating me. I've pushed the patches out onto my
perf/omap4-dev branch as that seems to be a good place to collate the
current state of things. I've not tried doing anything with it yet though.

Do you know when Benoit will be back online?

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-26 15:05                               ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-26 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jul 26, 2012 at 01:41:23AM +0100, Jon Hunter wrote:
> Hi Will,

Hi Jon,

> On 07/05/2012 07:40 PM, Jon Hunter wrote:
> I just wanted to let you know that I have been updating the PMU patches
> for OMAP. Latest can be found here [1]. I have not included Paul's patch
> [2] in this series at the moment, because although it works well for
> OMAP4, I need to create the HWMOD structures for OMAP3. Without these
> structures it breaks OMAP3 PMU support. Once this is done we should be
> able to get rid for the OMAP3 dependency on ETM. Unfortunately, Benoit
> (Mr HWMOD) is out on his holidays but should be back next week and then
> maybe he can give me some guidance on this HWMOD stuff.

Ok, thanks for updating me. I've pushed the patches out onto my
perf/omap4-dev branch as that seems to be a good place to collate the
current state of things. I've not tried doing anything with it yet though.

Do you know when Benoit will be back online?

Will

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-26 15:05                               ` Will Deacon
@ 2012-07-26 15:16                                 ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-26 15:16 UTC (permalink / raw)
  To: Will Deacon
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm


On 07/26/2012 10:05 AM, Will Deacon wrote:
> On Thu, Jul 26, 2012 at 01:41:23AM +0100, Jon Hunter wrote:
>> Hi Will,
> 
> Hi Jon,
> 
>> On 07/05/2012 07:40 PM, Jon Hunter wrote:
>> I just wanted to let you know that I have been updating the PMU patches
>> for OMAP. Latest can be found here [1]. I have not included Paul's patch
>> [2] in this series at the moment, because although it works well for
>> OMAP4, I need to create the HWMOD structures for OMAP3. Without these
>> structures it breaks OMAP3 PMU support. Once this is done we should be
>> able to get rid for the OMAP3 dependency on ETM. Unfortunately, Benoit
>> (Mr HWMOD) is out on his holidays but should be back next week and then
>> maybe he can give me some guidance on this HWMOD stuff.
> 
> Ok, thanks for updating me. I've pushed the patches out onto my
> perf/omap4-dev branch as that seems to be a good place to collate the
> current state of things. I've not tried doing anything with it yet though.

Ok, great. Let me know if you have any problems. I have ran some initial
testing on omap3430, omap4430 and omap4460 and it seems ok (AFAICT).

> Do you know when Benoit will be back online?

I *believe* Monday. However, I am sure he will have a lot of catching up
to do. Anything particular or you just want to get this stuff
finalised/done?

Cheers
Jon

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-26 15:16                                 ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-26 15:16 UTC (permalink / raw)
  To: linux-arm-kernel


On 07/26/2012 10:05 AM, Will Deacon wrote:
> On Thu, Jul 26, 2012 at 01:41:23AM +0100, Jon Hunter wrote:
>> Hi Will,
> 
> Hi Jon,
> 
>> On 07/05/2012 07:40 PM, Jon Hunter wrote:
>> I just wanted to let you know that I have been updating the PMU patches
>> for OMAP. Latest can be found here [1]. I have not included Paul's patch
>> [2] in this series at the moment, because although it works well for
>> OMAP4, I need to create the HWMOD structures for OMAP3. Without these
>> structures it breaks OMAP3 PMU support. Once this is done we should be
>> able to get rid for the OMAP3 dependency on ETM. Unfortunately, Benoit
>> (Mr HWMOD) is out on his holidays but should be back next week and then
>> maybe he can give me some guidance on this HWMOD stuff.
> 
> Ok, thanks for updating me. I've pushed the patches out onto my
> perf/omap4-dev branch as that seems to be a good place to collate the
> current state of things. I've not tried doing anything with it yet though.

Ok, great. Let me know if you have any problems. I have ran some initial
testing on omap3430, omap4430 and omap4460 and it seems ok (AFAICT).

> Do you know when Benoit will be back online?

I *believe* Monday. However, I am sure he will have a lot of catching up
to do. Anything particular or you just want to get this stuff
finalised/done?

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-16 18:38             ` Paul Walmsley
@ 2012-07-30 23:26               ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-30 23:26 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hi Paul,

On 07/16/2012 01:38 PM, Paul Walmsley wrote:
> Hi Jon,
> 
> On Mon, 16 Jul 2012, Jon Hunter wrote:
> 
>> Yes I see that makes sense. However, patch #7 has already changed the
>> mapping of the flags. I had intended that patch #7 and #8 would be
>> applied together. However, I could see that patch #7 can be taken just
>> to eliminate using the SW_SLEEP state. So basically, what I am saying is
>> does patch #7 have any value without #8?
> 
> Certainly not as much value as it had before.  But my understanding, which 
> is possibly incorrect, matches what you wrote in patch #7's description:
> 
> "For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is 
> equivalent to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP 
> for OMAP4 devices is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt 
> status is set in case of SW_SLEEP transition, and not set in case of 
> HW_AUTO transition."
> 
> We don't use that PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt bit.  So if 
> SW_SLEEP and HW_AUTO really have identical meanings otherwise, then I 
> suppose we might as well use the one that does what we need with no 
> extraneous side-effects?  My recollection from a conversation with Benoît 
> a few months ago was that this was his view as well.
> 
>> That's fine with me. We can always workaround such issues by adding flags.
>>
>> I can give this a try this week and let you know how it goes.
> 
> Okay, great.  No rush on my account.

I have been testing your patch [1] on OMAP3 and found that the EMU
clock domain was not being disabled for two reasons. 

1. When HWMOD attempts to disable the clock domain for OMAP2/3 devices 
   we simply return without doing anything. Not sure if it is safe to 
   remove this but I can do some more testing on OMAP2/3. 

commit a0307bd539ecef976793679a1c4ff0d47b22c4bd
Author: Jon Hunter <jon-hunter@ti.com>
Date:   Mon Jul 30 18:04:06 2012 -0500

    ARM: OMAP2/3: Allow HWMOD to disable clock domains
    
    Currently when HWMOD attempts to disable a clock domain on OMAP2/3 devices we
    will return from the function clkdm_hwmod_disable() without actually disabling
    the clock domain. Per the comment this is deliberate because initially HWMOD
    OMAP2/3 devices did not support clock domains. However, clock domains are now
    supported by HWMOD for these devices and so allow HWMOD to disable the clock
    domains.
    
    XXX - Tested on OMAP3430 beagle board, but needs more testing on OMAP2/3

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 011186f..8f7a941 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -1075,10 +1075,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
  */
 int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
 {
-       /* The clkdm attribute does not exist yet prior OMAP4 */
-       if (cpu_is_omap24xx() || cpu_is_omap34xx())
-               return 0;
-
        /*
         * XXX Rewrite this code to maintain a list of enabled
         * downstream hwmods for debugging purposes?


2. I need to make the following changes to your patch. The change to
   omap2_clkdm_clk_disable() was needed to get the EMU to turn off.
   At the same time I thought we should make the same change to
   omap2_clkdm_clk_enable().

diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index 09385a9..c94b2fb 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -223,7 +223,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
                _enable_hwsup(clkdm);
        } else {
                if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-                       omap2_clkdm_wakeup(clkdm);
+                       (cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
+                               omap3_clkdm_wakeup(clkdm);
        }
 
        return 0;
@@ -257,7 +258,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
                _enable_hwsup(clkdm);
        } else {
                if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
-                       omap2_clkdm_sleep(clkdm);
+                       (cpu_is_omap24xx()) ? omap2_clkdm_sleep(clkdm) :
+                               omap3_clkdm_sleep(clkdm);
        }


I need to do more testing but wanted to give you this feedback and
get your comments.

Cheers
Jon

[1] http://marc.info/?l=linux-arm-kernel&m=134212814812557&w=2
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-30 23:26               ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-30 23:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/16/2012 01:38 PM, Paul Walmsley wrote:
> Hi Jon,
> 
> On Mon, 16 Jul 2012, Jon Hunter wrote:
> 
>> Yes I see that makes sense. However, patch #7 has already changed the
>> mapping of the flags. I had intended that patch #7 and #8 would be
>> applied together. However, I could see that patch #7 can be taken just
>> to eliminate using the SW_SLEEP state. So basically, what I am saying is
>> does patch #7 have any value without #8?
> 
> Certainly not as much value as it had before.  But my understanding, which 
> is possibly incorrect, matches what you wrote in patch #7's description:
> 
> "For OMAP4 devices, SW_SLEEP is equivalent to HW_AUTO and NO_SLEEP is 
> equivalent to SW_WKUP. The only difference between HW_AUTO and SW_SLEEP 
> for OMAP4 devices is that the PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt 
> status is set in case of SW_SLEEP transition, and not set in case of 
> HW_AUTO transition."
> 
> We don't use that PRM_IRQSTATUS_MPU.TRANSITION_ST interrupt bit.  So if 
> SW_SLEEP and HW_AUTO really have identical meanings otherwise, then I 
> suppose we might as well use the one that does what we need with no 
> extraneous side-effects?  My recollection from a conversation with Beno?t 
> a few months ago was that this was his view as well.
> 
>> That's fine with me. We can always workaround such issues by adding flags.
>>
>> I can give this a try this week and let you know how it goes.
> 
> Okay, great.  No rush on my account.

I have been testing your patch [1] on OMAP3 and found that the EMU
clock domain was not being disabled for two reasons. 

1. When HWMOD attempts to disable the clock domain for OMAP2/3 devices 
   we simply return without doing anything. Not sure if it is safe to 
   remove this but I can do some more testing on OMAP2/3. 

commit a0307bd539ecef976793679a1c4ff0d47b22c4bd
Author: Jon Hunter <jon-hunter@ti.com>
Date:   Mon Jul 30 18:04:06 2012 -0500

    ARM: OMAP2/3: Allow HWMOD to disable clock domains
    
    Currently when HWMOD attempts to disable a clock domain on OMAP2/3 devices we
    will return from the function clkdm_hwmod_disable() without actually disabling
    the clock domain. Per the comment this is deliberate because initially HWMOD
    OMAP2/3 devices did not support clock domains. However, clock domains are now
    supported by HWMOD for these devices and so allow HWMOD to disable the clock
    domains.
    
    XXX - Tested on OMAP3430 beagle board, but needs more testing on OMAP2/3

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 011186f..8f7a941 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -1075,10 +1075,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
  */
 int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
 {
-       /* The clkdm attribute does not exist yet prior OMAP4 */
-       if (cpu_is_omap24xx() || cpu_is_omap34xx())
-               return 0;
-
        /*
         * XXX Rewrite this code to maintain a list of enabled
         * downstream hwmods for debugging purposes?


2. I need to make the following changes to your patch. The change to
   omap2_clkdm_clk_disable() was needed to get the EMU to turn off.
   At the same time I thought we should make the same change to
   omap2_clkdm_clk_enable().

diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index 09385a9..c94b2fb 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -223,7 +223,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
                _enable_hwsup(clkdm);
        } else {
                if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
-                       omap2_clkdm_wakeup(clkdm);
+                       (cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
+                               omap3_clkdm_wakeup(clkdm);
        }
 
        return 0;
@@ -257,7 +258,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
                _enable_hwsup(clkdm);
        } else {
                if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
-                       omap2_clkdm_sleep(clkdm);
+                       (cpu_is_omap24xx()) ? omap2_clkdm_sleep(clkdm) :
+                               omap3_clkdm_sleep(clkdm);
        }


I need to do more testing but wanted to give you this feedback and
get your comments.

Cheers
Jon

[1] http://marc.info/?l=linux-arm-kernel&m=134212814812557&w=2

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-30 23:26               ` Jon Hunter
@ 2012-07-31  4:36                 ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-31  4:36 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon, linux-omap,
	linux-arm

Hi Paul,

On 07/30/2012 06:26 PM, Jon Hunter wrote:

[...]

> 1. When HWMOD attempts to disable the clock domain for OMAP2/3 devices 
>    we simply return without doing anything. Not sure if it is safe to 
>    remove this but I can do some more testing on OMAP2/3. 
> 
> commit a0307bd539ecef976793679a1c4ff0d47b22c4bd
> Author: Jon Hunter <jon-hunter@ti.com>
> Date:   Mon Jul 30 18:04:06 2012 -0500
> 
>     ARM: OMAP2/3: Allow HWMOD to disable clock domains
>     
>     Currently when HWMOD attempts to disable a clock domain on OMAP2/3 devices we
>     will return from the function clkdm_hwmod_disable() without actually disabling
>     the clock domain. Per the comment this is deliberate because initially HWMOD
>     OMAP2/3 devices did not support clock domains. However, clock domains are now
>     supported by HWMOD for these devices and so allow HWMOD to disable the clock
>     domains.
>     
>     XXX - Tested on OMAP3430 beagle board, but needs more testing on OMAP2/3
> 
> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
> index 011186f..8f7a941 100644
> --- a/arch/arm/mach-omap2/clockdomain.c
> +++ b/arch/arm/mach-omap2/clockdomain.c
> @@ -1075,10 +1075,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
>   */
>  int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
>  {
> -       /* The clkdm attribute does not exist yet prior OMAP4 */
> -       if (cpu_is_omap24xx() || cpu_is_omap34xx())
> -               return 0;
> -
>         /*
>          * XXX Rewrite this code to maintain a list of enabled
>          * downstream hwmods for debugging purposes?
> 
> 
> 2. I need to make the following changes to your patch. The change to
>    omap2_clkdm_clk_disable() was needed to get the EMU to turn off.
>    At the same time I thought we should make the same change to
>    omap2_clkdm_clk_enable().
> 
> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> index 09385a9..c94b2fb 100644
> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> @@ -223,7 +223,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>                 _enable_hwsup(clkdm);
>         } else {
>                 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -                       omap2_clkdm_wakeup(clkdm);
> +                       (cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
> +                               omap3_clkdm_wakeup(clkdm);
>         }
>  
>         return 0;
> @@ -257,7 +258,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
>                 _enable_hwsup(clkdm);
>         } else {
>                 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> -                       omap2_clkdm_sleep(clkdm);
> +                       (cpu_is_omap24xx()) ? omap2_clkdm_sleep(clkdm) :
> +                               omap3_clkdm_sleep(clkdm);
>         }

I just remembered you sending out a patch [1] to address #2 above. Let
me know your thoughts about change #1.

Cheers
Jon

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

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-31  4:36                 ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-31  4:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/30/2012 06:26 PM, Jon Hunter wrote:

[...]

> 1. When HWMOD attempts to disable the clock domain for OMAP2/3 devices 
>    we simply return without doing anything. Not sure if it is safe to 
>    remove this but I can do some more testing on OMAP2/3. 
> 
> commit a0307bd539ecef976793679a1c4ff0d47b22c4bd
> Author: Jon Hunter <jon-hunter@ti.com>
> Date:   Mon Jul 30 18:04:06 2012 -0500
> 
>     ARM: OMAP2/3: Allow HWMOD to disable clock domains
>     
>     Currently when HWMOD attempts to disable a clock domain on OMAP2/3 devices we
>     will return from the function clkdm_hwmod_disable() without actually disabling
>     the clock domain. Per the comment this is deliberate because initially HWMOD
>     OMAP2/3 devices did not support clock domains. However, clock domains are now
>     supported by HWMOD for these devices and so allow HWMOD to disable the clock
>     domains.
>     
>     XXX - Tested on OMAP3430 beagle board, but needs more testing on OMAP2/3
> 
> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
> index 011186f..8f7a941 100644
> --- a/arch/arm/mach-omap2/clockdomain.c
> +++ b/arch/arm/mach-omap2/clockdomain.c
> @@ -1075,10 +1075,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
>   */
>  int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
>  {
> -       /* The clkdm attribute does not exist yet prior OMAP4 */
> -       if (cpu_is_omap24xx() || cpu_is_omap34xx())
> -               return 0;
> -
>         /*
>          * XXX Rewrite this code to maintain a list of enabled
>          * downstream hwmods for debugging purposes?
> 
> 
> 2. I need to make the following changes to your patch. The change to
>    omap2_clkdm_clk_disable() was needed to get the EMU to turn off.
>    At the same time I thought we should make the same change to
>    omap2_clkdm_clk_enable().
> 
> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> index 09385a9..c94b2fb 100644
> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> @@ -223,7 +223,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>                 _enable_hwsup(clkdm);
>         } else {
>                 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
> -                       omap2_clkdm_wakeup(clkdm);
> +                       (cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
> +                               omap3_clkdm_wakeup(clkdm);
>         }
>  
>         return 0;
> @@ -257,7 +258,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
>                 _enable_hwsup(clkdm);
>         } else {
>                 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
> -                       omap2_clkdm_sleep(clkdm);
> +                       (cpu_is_omap24xx()) ? omap2_clkdm_sleep(clkdm) :
> +                               omap3_clkdm_sleep(clkdm);
>         }

I just remembered you sending out a patch [1] to address #2 above. Let
me know your thoughts about change #1.

Cheers
Jon

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

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-26 15:16                                 ` Jon Hunter
@ 2012-07-31 15:14                                   ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-31 15:14 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

On Thu, Jul 26, 2012 at 04:16:15PM +0100, Jon Hunter wrote:
> On 07/26/2012 10:05 AM, Will Deacon wrote:
> > Ok, thanks for updating me. I've pushed the patches out onto my
> > perf/omap4-dev branch as that seems to be a good place to collate the
> > current state of things. I've not tried doing anything with it yet though.
> 
> Ok, great. Let me know if you have any problems. I have ran some initial
> testing on omap3430, omap4430 and omap4460 and it seems ok (AFAICT).

Just an FYI that I gave up maintaining the old perf/omap4 branch and instead
moved everything from perf/omap4-dev onto that as the rebase was getting
painful.

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-31 15:14                                   ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-07-31 15:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jul 26, 2012 at 04:16:15PM +0100, Jon Hunter wrote:
> On 07/26/2012 10:05 AM, Will Deacon wrote:
> > Ok, thanks for updating me. I've pushed the patches out onto my
> > perf/omap4-dev branch as that seems to be a good place to collate the
> > current state of things. I've not tried doing anything with it yet though.
> 
> Ok, great. Let me know if you have any problems. I have ran some initial
> testing on omap3430, omap4430 and omap4460 and it seems ok (AFAICT).

Just an FYI that I gave up maintaining the old perf/omap4 branch and instead
moved everything from perf/omap4-dev onto that as the rebase was getting
painful.

Will

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-31  4:36                 ` Jon Hunter
@ 2012-07-31 18:16                   ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-31 18:16 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon, linux-omap,
	linux-arm

Hi Paul,

On 07/30/2012 11:36 PM, Jon Hunter wrote:
> Hi Paul,
> 
> On 07/30/2012 06:26 PM, Jon Hunter wrote:
> 
> [...]
> 
>> 1. When HWMOD attempts to disable the clock domain for OMAP2/3 devices 
>>    we simply return without doing anything. Not sure if it is safe to 
>>    remove this but I can do some more testing on OMAP2/3. 
>>
>> commit a0307bd539ecef976793679a1c4ff0d47b22c4bd
>> Author: Jon Hunter <jon-hunter@ti.com>
>> Date:   Mon Jul 30 18:04:06 2012 -0500
>>
>>     ARM: OMAP2/3: Allow HWMOD to disable clock domains
>>     
>>     Currently when HWMOD attempts to disable a clock domain on OMAP2/3 devices we
>>     will return from the function clkdm_hwmod_disable() without actually disabling
>>     the clock domain. Per the comment this is deliberate because initially HWMOD
>>     OMAP2/3 devices did not support clock domains. However, clock domains are now
>>     supported by HWMOD for these devices and so allow HWMOD to disable the clock
>>     domains.
>>     
>>     XXX - Tested on OMAP3430 beagle board, but needs more testing on OMAP2/3
>>
>> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
>> index 011186f..8f7a941 100644
>> --- a/arch/arm/mach-omap2/clockdomain.c
>> +++ b/arch/arm/mach-omap2/clockdomain.c
>> @@ -1075,10 +1075,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
>>   */
>>  int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
>>  {
>> -       /* The clkdm attribute does not exist yet prior OMAP4 */
>> -       if (cpu_is_omap24xx() || cpu_is_omap34xx())
>> -               return 0;
>> -
>>         /*
>>          * XXX Rewrite this code to maintain a list of enabled
>>          * downstream hwmods for debugging purposes?
>>
>>
>> 2. I need to make the following changes to your patch. The change to
>>    omap2_clkdm_clk_disable() was needed to get the EMU to turn off.
>>    At the same time I thought we should make the same change to
>>    omap2_clkdm_clk_enable().
>>
>> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>> index 09385a9..c94b2fb 100644
>> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>> @@ -223,7 +223,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>>                 _enable_hwsup(clkdm);
>>         } else {
>>                 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
>> -                       omap2_clkdm_wakeup(clkdm);
>> +                       (cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
>> +                               omap3_clkdm_wakeup(clkdm);
>>         }
>>  
>>         return 0;
>> @@ -257,7 +258,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
>>                 _enable_hwsup(clkdm);
>>         } else {
>>                 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
>> -                       omap2_clkdm_sleep(clkdm);
>> +                       (cpu_is_omap24xx()) ? omap2_clkdm_sleep(clkdm) :
>> +                               omap3_clkdm_sleep(clkdm);
>>         }
> 
> I just remembered you sending out a patch [1] to address #2 above. Let
> me know your thoughts about change #1.

So scratch item #1 above. As Rajendra pointed out in another thread this
is not right. The only other comment I have with your patch is maybe we
need to add the following to prevent the EMU PD being idled during
boot-up if enabled early in the boot process. 

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 011186f..84d3fbc 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -825,7 +825,8 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
        if (!clkdm)
                return;
 
-       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
+       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO) ||
+                       (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) {
                pr_debug("clock: automatic idle transitions cannot be enabled "
                         "on clockdomain %s\n", clkdm->name);
                return;

Cheers
Jon

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-31 18:16                   ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-31 18:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/30/2012 11:36 PM, Jon Hunter wrote:
> Hi Paul,
> 
> On 07/30/2012 06:26 PM, Jon Hunter wrote:
> 
> [...]
> 
>> 1. When HWMOD attempts to disable the clock domain for OMAP2/3 devices 
>>    we simply return without doing anything. Not sure if it is safe to 
>>    remove this but I can do some more testing on OMAP2/3. 
>>
>> commit a0307bd539ecef976793679a1c4ff0d47b22c4bd
>> Author: Jon Hunter <jon-hunter@ti.com>
>> Date:   Mon Jul 30 18:04:06 2012 -0500
>>
>>     ARM: OMAP2/3: Allow HWMOD to disable clock domains
>>     
>>     Currently when HWMOD attempts to disable a clock domain on OMAP2/3 devices we
>>     will return from the function clkdm_hwmod_disable() without actually disabling
>>     the clock domain. Per the comment this is deliberate because initially HWMOD
>>     OMAP2/3 devices did not support clock domains. However, clock domains are now
>>     supported by HWMOD for these devices and so allow HWMOD to disable the clock
>>     domains.
>>     
>>     XXX - Tested on OMAP3430 beagle board, but needs more testing on OMAP2/3
>>
>> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
>> index 011186f..8f7a941 100644
>> --- a/arch/arm/mach-omap2/clockdomain.c
>> +++ b/arch/arm/mach-omap2/clockdomain.c
>> @@ -1075,10 +1075,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
>>   */
>>  int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
>>  {
>> -       /* The clkdm attribute does not exist yet prior OMAP4 */
>> -       if (cpu_is_omap24xx() || cpu_is_omap34xx())
>> -               return 0;
>> -
>>         /*
>>          * XXX Rewrite this code to maintain a list of enabled
>>          * downstream hwmods for debugging purposes?
>>
>>
>> 2. I need to make the following changes to your patch. The change to
>>    omap2_clkdm_clk_disable() was needed to get the EMU to turn off.
>>    At the same time I thought we should make the same change to
>>    omap2_clkdm_clk_enable().
>>
>> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>> index 09385a9..c94b2fb 100644
>> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
>> @@ -223,7 +223,8 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>>                 _enable_hwsup(clkdm);
>>         } else {
>>                 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
>> -                       omap2_clkdm_wakeup(clkdm);
>> +                       (cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
>> +                               omap3_clkdm_wakeup(clkdm);
>>         }
>>  
>>         return 0;
>> @@ -257,7 +258,8 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
>>                 _enable_hwsup(clkdm);
>>         } else {
>>                 if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
>> -                       omap2_clkdm_sleep(clkdm);
>> +                       (cpu_is_omap24xx()) ? omap2_clkdm_sleep(clkdm) :
>> +                               omap3_clkdm_sleep(clkdm);
>>         }
> 
> I just remembered you sending out a patch [1] to address #2 above. Let
> me know your thoughts about change #1.

So scratch item #1 above. As Rajendra pointed out in another thread this
is not right. The only other comment I have with your patch is maybe we
need to add the following to prevent the EMU PD being idled during
boot-up if enabled early in the boot process. 

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 011186f..84d3fbc 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -825,7 +825,8 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
        if (!clkdm)
                return;
 
-       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
+       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO) ||
+                       (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) {
                pr_debug("clock: automatic idle transitions cannot be enabled "
                         "on clockdomain %s\n", clkdm->name);
                return;

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-12 21:17     ` Paul Walmsley
@ 2012-07-31 20:56       ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-31 20:56 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: linux-omap, linux-arm, Ming Lei, Will Deacon, Benoit Cousson,
	Kevin Hilman

Hi Paul,

On 07/12/2012 04:17 PM, Paul Walmsley wrote:

[snip]

> @@ -170,6 +201,18 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & (CLKDM_MISSING_IDLE_REPORTING |
> +			    CLKDM_CAN_FORCE_WAKEUP)) {
> +		(cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
> +			omap3_clkdm_wakeup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);

I think that the above needs to be ...

diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index e5bb219..d2b081d 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -253,8 +253,8 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
         * more details on the unpleasant problem this is working
         * around
         */
-       if (clkdm->flags & (CLKDM_MISSING_IDLE_REPORTING |
-                           CLKDM_CAN_FORCE_WAKEUP)) {
+       if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+                               (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
                omap3_clkdm_wakeup(clkdm);
                return 0;

... otherwise I see other clkdm such as MPU being put in force-wakeup state 
although they don't have CLKDM_MISSING_IDLE_REPORTING set.

Cheers
Jon

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-07-31 20:56       ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-31 20:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/12/2012 04:17 PM, Paul Walmsley wrote:

[snip]

> @@ -170,6 +201,18 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & (CLKDM_MISSING_IDLE_REPORTING |
> +			    CLKDM_CAN_FORCE_WAKEUP)) {
> +		(cpu_is_omap24xx()) ? omap2_clkdm_wakeup(clkdm) :
> +			omap3_clkdm_wakeup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);

I think that the above needs to be ...

diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index e5bb219..d2b081d 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -253,8 +253,8 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
         * more details on the unpleasant problem this is working
         * around
         */
-       if (clkdm->flags & (CLKDM_MISSING_IDLE_REPORTING |
-                           CLKDM_CAN_FORCE_WAKEUP)) {
+       if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+                               (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
                omap3_clkdm_wakeup(clkdm);
                return 0;

... otherwise I see other clkdm such as MPU being put in force-wakeup state 
although they don't have CLKDM_MISSING_IDLE_REPORTING set.

Cheers
Jon

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-31 15:14                                   ` Will Deacon
@ 2012-07-31 23:07                                     ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-31 23:07 UTC (permalink / raw)
  To: Will Deacon
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

Hi  Will,

On 07/31/2012 10:14 AM, Will Deacon wrote:
> On Thu, Jul 26, 2012 at 04:16:15PM +0100, Jon Hunter wrote:
>> On 07/26/2012 10:05 AM, Will Deacon wrote:
>>> Ok, thanks for updating me. I've pushed the patches out onto my
>>> perf/omap4-dev branch as that seems to be a good place to collate the
>>> current state of things. I've not tried doing anything with it yet though.
>>
>> Ok, great. Let me know if you have any problems. I have ran some initial
>> testing on omap3430, omap4430 and omap4460 and it seems ok (AFAICT).
> 
> Just an FYI that I gave up maintaining the old perf/omap4 branch and instead
> moved everything from perf/omap4-dev onto that as the rebase was getting
> painful.

I have just updated my pmu branch for omap3/4. You can pull my latest
patches from [1].

In the latest series I have:
1. Pulled in an omap3 clock domain fix from Paul [2]
2. Rebased Paul's patch [3] on top of [2]. I have also made a couple
   updates to this patch and I need to get Paul's feedback.
3. I have removed the OMAP3 PMU dependency on ETM from the Kconfig.

I have tested this on OMAP3430, OMAP4430 and OMAP4460. Seems to be
working well my end so let me know if you have chance to try.

I will probably send out the series once I align with Paul on the above
changes and the HWMOD stuff I have added for OMAP3 with Benoit.

Cheers
Jon

[1] git@gitorious.org:linux-omap-dev/linux-omap-dev.git -b dev-pmu
[2] http://marc.info/?l=linux-omap&m=134333691309305&w=2
[3] http://marc.info/?l=linux-omap&m=134212809112530&w=2

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-07-31 23:07                                     ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-07-31 23:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi  Will,

On 07/31/2012 10:14 AM, Will Deacon wrote:
> On Thu, Jul 26, 2012 at 04:16:15PM +0100, Jon Hunter wrote:
>> On 07/26/2012 10:05 AM, Will Deacon wrote:
>>> Ok, thanks for updating me. I've pushed the patches out onto my
>>> perf/omap4-dev branch as that seems to be a good place to collate the
>>> current state of things. I've not tried doing anything with it yet though.
>>
>> Ok, great. Let me know if you have any problems. I have ran some initial
>> testing on omap3430, omap4430 and omap4460 and it seems ok (AFAICT).
> 
> Just an FYI that I gave up maintaining the old perf/omap4 branch and instead
> moved everything from perf/omap4-dev onto that as the rebase was getting
> painful.

I have just updated my pmu branch for omap3/4. You can pull my latest
patches from [1].

In the latest series I have:
1. Pulled in an omap3 clock domain fix from Paul [2]
2. Rebased Paul's patch [3] on top of [2]. I have also made a couple
   updates to this patch and I need to get Paul's feedback.
3. I have removed the OMAP3 PMU dependency on ETM from the Kconfig.

I have tested this on OMAP3430, OMAP4430 and OMAP4460. Seems to be
working well my end so let me know if you have chance to try.

I will probably send out the series once I align with Paul on the above
changes and the HWMOD stuff I have added for OMAP3 with Benoit.

Cheers
Jon

[1] git at gitorious.org:linux-omap-dev/linux-omap-dev.git -b dev-pmu
[2] http://marc.info/?l=linux-omap&m=134333691309305&w=2
[3] http://marc.info/?l=linux-omap&m=134212809112530&w=2

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-07-31 18:16                   ` Jon Hunter
@ 2012-08-01  0:20                     ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-08-01  0:20 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon, linux-omap,
	linux-arm

Hi Paul,

On 07/31/2012 01:16 PM, Jon Hunter wrote:

[snip]

> So scratch item #1 above. As Rajendra pointed out in another thread this
> is not right. The only other comment I have with your patch is maybe we
> need to add the following to prevent the EMU PD being idled during
> boot-up if enabled early in the boot process. 
> 
> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
> index 011186f..84d3fbc 100644
> --- a/arch/arm/mach-omap2/clockdomain.c
> +++ b/arch/arm/mach-omap2/clockdomain.c
> @@ -825,7 +825,8 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
>         if (!clkdm)
>                 return;
>  
> -       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
> +       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO) ||
> +                       (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) {
>                 pr_debug("clock: automatic idle transitions cannot be enabled "
>                          "on clockdomain %s\n", clkdm->name);
>                 return;

Sorry for all the emails. However, I wanted to get this out to you as
I am due to be out for a couple weeks. 

So I have updated your patch [1] with the following changes ...

1. Re-based on top of your omap3 clock domain fix [2]
2. Modified the above change I mentioned to check for
   CLKDM_MISSING_IDLE_REPORTING in omap_pm_clkdms_setup() instead of
   the omap2_clkdm_clk_enable(). This is to prevent the clock domain
   being placed in HW_AUTO on boot if enabled early.
3. Made the other change I mentioned earlier [3].

This is now working well for me on OMAP3/4.

Let me know your thoughts.

Cheers
Jon

[1] http://marc.info/?l=linux-omap&m=134212809112530&w=2
[2] http://marc.info/?l=linux-omap&m=134333691309305&w=2
[3] http://marc.info/?l=linux-arm-kernel&m=134376848803220&w=2

>From c0b0077192239f7c03e39e8292bd74575d74f7d8 Mon Sep 17 00:00:00 2001
From: Paul Walmsley <paul@pwsan.com>
Date: Thu, 12 Jul 2012 14:58:43 -0600
Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
 clockdomain idle problems

The idle status of the IP blocks and clocks inside the EMU clockdomain
isn't taken into account by the PRCM hardware when deciding whether
the clockdomain is idle.  Add a workaround flag, CLKDM_MISSING_IDLE_REPORTING,
to deal with this problem, and add the code necessary to support it.

XXX Add more description of what this flag actually does

XXX Jon, Ming, Will
---
 arch/arm/mach-omap2/clockdomain.c           |   17 +++++++++++++++++
 arch/arm/mach-omap2/clockdomain.h           |   20 +++++++++++++++++---
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c  |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/clockdomain44xx.c       |   11 +++++++++++
 arch/arm/mach-omap2/clockdomains3xxx_data.c |    7 ++-----
 arch/arm/mach-omap2/clockdomains44xx_data.c |    3 ++-
 arch/arm/mach-omap2/omap_hwmod.c            |    3 ++-
 arch/arm/mach-omap2/pm.c                    |    3 ++-
 8 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 8664f5a..011186f 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -905,6 +905,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
 	return ret;
 }
 
+/**
+ * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm has the
+ * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
+ * null.  More information is available in the documentation for the
+ * CLKDM_MISSING_IDLE_REPORTING macro.
+ */
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
+{
+	if (!clkdm)
+		return false;
+
+	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
+}
+
 /* Clockdomain-to-clock/hwmod framework interface code */
 
 static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 5601dc1..629576b 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -1,9 +1,7 @@
 /*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
  * OMAP2/3 clockdomain framework functions
  *
- * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008, 2012 Texas Instruments, Inc.
  * Copyright (C) 2008-2011 Nokia Corporation
  *
  * Paul Walmsley
@@ -34,6 +32,20 @@
  * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
  *     active whenever the MPU is active.  True for interconnects and
  *     the WKUP clockdomains.
+ * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
+ *     clocks inside this clockdomain are not taken into account by
+ *     the PRCM when determining whether the clockdomain is idle.
+ *     Without this flag, if the clockdomain is set to
+ *     hardware-supervised idle mode, the PRCM may transition the
+ *     enclosing powerdomain to a low power state, even when devices
+ *     inside the clockdomain and powerdomain are in use.  (An example
+ *     of such a clockdomain is the EMU clockdomain on OMAP3/4.)  If
+ *     this flag is set, and the clockdomain does not support the
+ *     force-sleep mode, then the HW_AUTO mode will be used to put the
+ *     clockdomain to sleep.  Similarly, if the clockdomain supports
+ *     the force-wakeup mode, then it will be used whenever a clock or
+ *     IP block inside the clockdomain is active, rather than the
+ *     HW_AUTO mode.
  */
 #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
 #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
@@ -41,6 +53,7 @@
 #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
 #define CLKDM_NO_AUTODEPS			(1 << 4)
 #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
+#define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
 
 #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
 #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@ -187,6 +200,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
 void clkdm_allow_idle(struct clockdomain *clkdm);
 void clkdm_deny_idle(struct clockdomain *clkdm);
 bool clkdm_in_hwsup(struct clockdomain *clkdm);
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
 
 int clkdm_wakeup(struct clockdomain *clkdm);
 int clkdm_sleep(struct clockdomain *clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index f99e65c..d2b081d 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -248,6 +248,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+				(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+		omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -271,6 +282,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 762f2cc..6fc6155 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->prcm_partition)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		omap4_clkdm_allow_idle(clkdm);
+		return 0;
+	}
+
 	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index 56089c4..933a35c 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
 	.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
- */
 static struct clockdomain emu_clkdm = {
 	.name		= "emu_clkdm",
 	.pwrdm		= { .name = "emu_pwrdm" },
-	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
+	.flags		= (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
+			   CLKDM_MISSING_IDLE_REPORTING),
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
 };
 
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 63d60a7..b56d06b 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
-	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+	.flags		  = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
+			     CLKDM_MISSING_IDLE_REPORTING),
 };
 
 static struct clockdomain l3_dma_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6ca8e51..36f0603 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1857,7 +1857,8 @@ static int _enable(struct omap_hwmod *oh)
 		 * completely the module. The clockdomain can be set
 		 * in HW_AUTO only when the module become ready.
 		 */
-		hwsup = clkdm_in_hwsup(oh->clkdm);
+		hwsup = clkdm_in_hwsup(oh->clkdm) &&
+			!clkdm_missing_idle_reporting(oh->clkdm);
 		r = clkdm_hwmod_enable(oh->clkdm, oh);
 		if (r) {
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 9cb5ced..0747300 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -80,7 +80,8 @@ static void __init omap2_init_processor_devices(void)
 
 int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
-	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+	if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
+			!(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
 		clkdm_allow_idle(clkdm);
 	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
 		 atomic_read(&clkdm->usecount) == 0)
-- 
1.7.9.5


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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-08-01  0:20                     ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-08-01  0:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 07/31/2012 01:16 PM, Jon Hunter wrote:

[snip]

> So scratch item #1 above. As Rajendra pointed out in another thread this
> is not right. The only other comment I have with your patch is maybe we
> need to add the following to prevent the EMU PD being idled during
> boot-up if enabled early in the boot process. 
> 
> diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
> index 011186f..84d3fbc 100644
> --- a/arch/arm/mach-omap2/clockdomain.c
> +++ b/arch/arm/mach-omap2/clockdomain.c
> @@ -825,7 +825,8 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
>         if (!clkdm)
>                 return;
>  
> -       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
> +       if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO) ||
> +                       (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) {
>                 pr_debug("clock: automatic idle transitions cannot be enabled "
>                          "on clockdomain %s\n", clkdm->name);
>                 return;

Sorry for all the emails. However, I wanted to get this out to you as
I am due to be out for a couple weeks. 

So I have updated your patch [1] with the following changes ...

1. Re-based on top of your omap3 clock domain fix [2]
2. Modified the above change I mentioned to check for
   CLKDM_MISSING_IDLE_REPORTING in omap_pm_clkdms_setup() instead of
   the omap2_clkdm_clk_enable(). This is to prevent the clock domain
   being placed in HW_AUTO on boot if enabled early.
3. Made the other change I mentioned earlier [3].

This is now working well for me on OMAP3/4.

Let me know your thoughts.

Cheers
Jon

[1] http://marc.info/?l=linux-omap&m=134212809112530&w=2
[2] http://marc.info/?l=linux-omap&m=134333691309305&w=2
[3] http://marc.info/?l=linux-arm-kernel&m=134376848803220&w=2

>From c0b0077192239f7c03e39e8292bd74575d74f7d8 Mon Sep 17 00:00:00 2001
From: Paul Walmsley <paul@pwsan.com>
Date: Thu, 12 Jul 2012 14:58:43 -0600
Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
 clockdomain idle problems

The idle status of the IP blocks and clocks inside the EMU clockdomain
isn't taken into account by the PRCM hardware when deciding whether
the clockdomain is idle.  Add a workaround flag, CLKDM_MISSING_IDLE_REPORTING,
to deal with this problem, and add the code necessary to support it.

XXX Add more description of what this flag actually does

XXX Jon, Ming, Will
---
 arch/arm/mach-omap2/clockdomain.c           |   17 +++++++++++++++++
 arch/arm/mach-omap2/clockdomain.h           |   20 +++++++++++++++++---
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c  |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/clockdomain44xx.c       |   11 +++++++++++
 arch/arm/mach-omap2/clockdomains3xxx_data.c |    7 ++-----
 arch/arm/mach-omap2/clockdomains44xx_data.c |    3 ++-
 arch/arm/mach-omap2/omap_hwmod.c            |    3 ++-
 arch/arm/mach-omap2/pm.c                    |    3 ++-
 8 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 8664f5a..011186f 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -905,6 +905,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
 	return ret;
 }
 
+/**
+ * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm has the
+ * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
+ * null.  More information is available in the documentation for the
+ * CLKDM_MISSING_IDLE_REPORTING macro.
+ */
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
+{
+	if (!clkdm)
+		return false;
+
+	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
+}
+
 /* Clockdomain-to-clock/hwmod framework interface code */
 
 static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 5601dc1..629576b 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -1,9 +1,7 @@
 /*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
  * OMAP2/3 clockdomain framework functions
  *
- * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008, 2012 Texas Instruments, Inc.
  * Copyright (C) 2008-2011 Nokia Corporation
  *
  * Paul Walmsley
@@ -34,6 +32,20 @@
  * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
  *     active whenever the MPU is active.  True for interconnects and
  *     the WKUP clockdomains.
+ * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
+ *     clocks inside this clockdomain are not taken into account by
+ *     the PRCM when determining whether the clockdomain is idle.
+ *     Without this flag, if the clockdomain is set to
+ *     hardware-supervised idle mode, the PRCM may transition the
+ *     enclosing powerdomain to a low power state, even when devices
+ *     inside the clockdomain and powerdomain are in use.  (An example
+ *     of such a clockdomain is the EMU clockdomain on OMAP3/4.)  If
+ *     this flag is set, and the clockdomain does not support the
+ *     force-sleep mode, then the HW_AUTO mode will be used to put the
+ *     clockdomain to sleep.  Similarly, if the clockdomain supports
+ *     the force-wakeup mode, then it will be used whenever a clock or
+ *     IP block inside the clockdomain is active, rather than the
+ *     HW_AUTO mode.
  */
 #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
 #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
@@ -41,6 +53,7 @@
 #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
 #define CLKDM_NO_AUTODEPS			(1 << 4)
 #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
+#define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
 
 #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
 #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@ -187,6 +200,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
 void clkdm_allow_idle(struct clockdomain *clkdm);
 void clkdm_deny_idle(struct clockdomain *clkdm);
 bool clkdm_in_hwsup(struct clockdomain *clkdm);
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
 
 int clkdm_wakeup(struct clockdomain *clkdm);
 int clkdm_sleep(struct clockdomain *clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index f99e65c..d2b081d 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -248,6 +248,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+				(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+		omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -271,6 +282,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 762f2cc..6fc6155 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->prcm_partition)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		omap4_clkdm_allow_idle(clkdm);
+		return 0;
+	}
+
 	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index 56089c4..933a35c 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
 	.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
- */
 static struct clockdomain emu_clkdm = {
 	.name		= "emu_clkdm",
 	.pwrdm		= { .name = "emu_pwrdm" },
-	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
+	.flags		= (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
+			   CLKDM_MISSING_IDLE_REPORTING),
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
 };
 
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 63d60a7..b56d06b 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
-	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+	.flags		  = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
+			     CLKDM_MISSING_IDLE_REPORTING),
 };
 
 static struct clockdomain l3_dma_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6ca8e51..36f0603 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1857,7 +1857,8 @@ static int _enable(struct omap_hwmod *oh)
 		 * completely the module. The clockdomain can be set
 		 * in HW_AUTO only when the module become ready.
 		 */
-		hwsup = clkdm_in_hwsup(oh->clkdm);
+		hwsup = clkdm_in_hwsup(oh->clkdm) &&
+			!clkdm_missing_idle_reporting(oh->clkdm);
 		r = clkdm_hwmod_enable(oh->clkdm, oh);
 		if (r) {
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 9cb5ced..0747300 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -80,7 +80,8 @@ static void __init omap2_init_processor_devices(void)
 
 int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
-	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+	if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
+			!(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
 		clkdm_allow_idle(clkdm);
 	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
 		 atomic_read(&clkdm->usecount) == 0)
-- 
1.7.9.5

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-08-01  0:20                     ` Jon Hunter
@ 2012-08-01 15:08                       ` Paul Walmsley
  -1 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-08-01 15:08 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon, linux-omap,
	linux-arm

Hi Jon,

On Tue, 31 Jul 2012, Jon Hunter wrote:

> Sorry for all the emails. However, I wanted to get this out to you as
> I am due to be out for a couple weeks. 
> 
> So I have updated your patch [1] with the following changes ...
> 
> 1. Re-based on top of your omap3 clock domain fix [2]
> 2. Modified the above change I mentioned to check for
>    CLKDM_MISSING_IDLE_REPORTING in omap_pm_clkdms_setup() instead of
>    the omap2_clkdm_clk_enable(). This is to prevent the clock domain
>    being placed in HW_AUTO on boot if enabled early.
> 3. Made the other change I mentioned earlier [3].
> 
> This is now working well for me on OMAP3/4.

Your changes look good to me.  Do you have a strong preference as to 
whether that patch should go in as part of 3.6-rc or 3.7?  I'd be inclined 
to queue it for 3.7 based on the size of the patch.


- Paul

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-08-01 15:08                       ` Paul Walmsley
  0 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-08-01 15:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

On Tue, 31 Jul 2012, Jon Hunter wrote:

> Sorry for all the emails. However, I wanted to get this out to you as
> I am due to be out for a couple weeks. 
> 
> So I have updated your patch [1] with the following changes ...
> 
> 1. Re-based on top of your omap3 clock domain fix [2]
> 2. Modified the above change I mentioned to check for
>    CLKDM_MISSING_IDLE_REPORTING in omap_pm_clkdms_setup() instead of
>    the omap2_clkdm_clk_enable(). This is to prevent the clock domain
>    being placed in HW_AUTO on boot if enabled early.
> 3. Made the other change I mentioned earlier [3].
> 
> This is now working well for me on OMAP3/4.

Your changes look good to me.  Do you have a strong preference as to 
whether that patch should go in as part of 3.6-rc or 3.7?  I'd be inclined 
to queue it for 3.7 based on the size of the patch.


- Paul

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-08-01  0:20                     ` Jon Hunter
@ 2012-08-01 15:36                       ` Paul Walmsley
  -1 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-08-01 15:36 UTC (permalink / raw)
  To: Jon Hunter, Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon,
	Madhav Vij
  Cc: linux-omap, linux-arm

[-- Attachment #1: Type: TEXT/PLAIN, Size: 10652 bytes --]

Hi Jon et al,

Here's what I'm planning to queue here.  The only changes from what Jon
posted are the patch changelog and some checkpatch fixes.  If anyone
has any final comments, please let me know.


- Paul

From: Paul Walmsley <paul@pwsan.com>
Date: Wed, 1 Aug 2012 09:11:20 -0600
Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
 clockdomain idle problems

The idle status of the IP blocks and clocks inside the EMU clockdomain
isn't taken into account by the PRCM hardware when deciding whether
the clockdomain is idle.  Add a workaround flag in the clockdomain
code, CLKDM_MISSING_IDLE_REPORTING, to deal with this problem, and add
the code necessary to support it.

If CLKDM_MISSING_IDLE_REPORTING is set on a clockdomain, the
clockdomain will be forced active whenever an IP block inside that
clockdomain is in use, even if the clockdomain supports
hardware-supervised idle.  When the kernel indicates that the last
active IP block inside the clockdomain is no longer used, the
clockdomain will be forced idle, or, if that mode is not supported in
the hardware, it will be placed into hardware-supervised idle.

This patch is an equal collaboration with Jon Hunter
<jon-hunter@ti.com>.  Ming Lei <ming.lei@canonical.com>, Will Deacon
<will.deacon@arm.com>, Madhav Vij <mvij@ti.com>, Kevin Hilman
<khilman@ti.com>, Benoît Cousson <b-cousson@ti.com>, and Santosh
Shilimkar <santosh.shilimkar@ti.com> all made essential contributions
to the understanding of EMU clockdomain power management on OMAP.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Jon Hunter <jon-hunter@ti.com>
Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Madhav Vij <mvij@ti.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/clockdomain.c           |   17 +++++++++++++++++
 arch/arm/mach-omap2/clockdomain.h           |   20 +++++++++++++++++---
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c  |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/clockdomain44xx.c       |   11 +++++++++++
 arch/arm/mach-omap2/clockdomains3xxx_data.c |    7 ++-----
 arch/arm/mach-omap2/clockdomains44xx_data.c |    3 ++-
 arch/arm/mach-omap2/omap_hwmod.c            |    3 ++-
 arch/arm/mach-omap2/pm.c                    |    3 ++-
 8 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index b851ba4..17b1d32 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -914,6 +914,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
 	return ret;
 }
 
+/**
+ * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm has the
+ * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
+ * null.  More information is available in the documentation for the
+ * CLKDM_MISSING_IDLE_REPORTING macro.
+ */
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
+{
+	if (!clkdm)
+		return false;
+
+	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
+}
+
 /* Clockdomain-to-clock/hwmod framework interface code */
 
 static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 7b3c1d2..fb5d37f 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -1,9 +1,7 @@
 /*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
  * OMAP2/3 clockdomain framework functions
  *
- * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008, 2012 Texas Instruments, Inc.
  * Copyright (C) 2008-2011 Nokia Corporation
  *
  * Paul Walmsley
@@ -34,6 +32,20 @@
  * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
  *     active whenever the MPU is active.  True for interconnects and
  *     the WKUP clockdomains.
+ * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
+ *     clocks inside this clockdomain are not taken into account by
+ *     the PRCM when determining whether the clockdomain is idle.
+ *     Without this flag, if the clockdomain is set to
+ *     hardware-supervised idle mode, the PRCM may transition the
+ *     enclosing powerdomain to a low power state, even when devices
+ *     inside the clockdomain and powerdomain are in use.  (An example
+ *     of such a clockdomain is the EMU clockdomain on OMAP3/4.)  If
+ *     this flag is set, and the clockdomain does not support the
+ *     force-sleep mode, then the HW_AUTO mode will be used to put the
+ *     clockdomain to sleep.  Similarly, if the clockdomain supports
+ *     the force-wakeup mode, then it will be used whenever a clock or
+ *     IP block inside the clockdomain is active, rather than the
+ *     HW_AUTO mode.
  */
 #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
 #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
@@ -41,6 +53,7 @@
 #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
 #define CLKDM_NO_AUTODEPS			(1 << 4)
 #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
+#define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
 
 #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
 #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@ -188,6 +201,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
 void clkdm_allow_idle(struct clockdomain *clkdm);
 void clkdm_deny_idle(struct clockdomain *clkdm);
 bool clkdm_in_hwsup(struct clockdomain *clkdm);
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
 
 int clkdm_wakeup(struct clockdomain *clkdm);
 int clkdm_sleep(struct clockdomain *clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index f99e65c..3f4b04b 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -248,6 +248,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+		omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -271,6 +282,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 762f2cc..6fc6155 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->prcm_partition)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		omap4_clkdm_allow_idle(clkdm);
+		return 0;
+	}
+
 	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index 56089c4..933a35c 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
 	.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
- */
 static struct clockdomain emu_clkdm = {
 	.name		= "emu_clkdm",
 	.pwrdm		= { .name = "emu_pwrdm" },
-	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
+	.flags		= (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
+			   CLKDM_MISSING_IDLE_REPORTING),
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
 };
 
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 63d60a7..b56d06b 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
-	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+	.flags		  = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
+			     CLKDM_MISSING_IDLE_REPORTING),
 };
 
 static struct clockdomain l3_dma_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6ca8e51..36f0603 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1857,7 +1857,8 @@ static int _enable(struct omap_hwmod *oh)
 		 * completely the module. The clockdomain can be set
 		 * in HW_AUTO only when the module become ready.
 		 */
-		hwsup = clkdm_in_hwsup(oh->clkdm);
+		hwsup = clkdm_in_hwsup(oh->clkdm) &&
+			!clkdm_missing_idle_reporting(oh->clkdm);
 		r = clkdm_hwmod_enable(oh->clkdm, oh);
 		if (r) {
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 9cb5ced..4182564 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -80,7 +80,8 @@ static void __init omap2_init_processor_devices(void)
 
 int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
-	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+	if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
+	    !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
 		clkdm_allow_idle(clkdm);
 	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
 		 atomic_read(&clkdm->usecount) == 0)
-- 
1.7.10.4

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-08-01 15:36                       ` Paul Walmsley
  0 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-08-01 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon et al,

Here's what I'm planning to queue here.  The only changes from what Jon
posted are the patch changelog and some checkpatch fixes.  If anyone
has any final comments, please let me know.


- Paul

From: Paul Walmsley <paul@pwsan.com>
Date: Wed, 1 Aug 2012 09:11:20 -0600
Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
 clockdomain idle problems

The idle status of the IP blocks and clocks inside the EMU clockdomain
isn't taken into account by the PRCM hardware when deciding whether
the clockdomain is idle.  Add a workaround flag in the clockdomain
code, CLKDM_MISSING_IDLE_REPORTING, to deal with this problem, and add
the code necessary to support it.

If CLKDM_MISSING_IDLE_REPORTING is set on a clockdomain, the
clockdomain will be forced active whenever an IP block inside that
clockdomain is in use, even if the clockdomain supports
hardware-supervised idle.  When the kernel indicates that the last
active IP block inside the clockdomain is no longer used, the
clockdomain will be forced idle, or, if that mode is not supported in
the hardware, it will be placed into hardware-supervised idle.

This patch is an equal collaboration with Jon Hunter
<jon-hunter@ti.com>.  Ming Lei <ming.lei@canonical.com>, Will Deacon
<will.deacon@arm.com>, Madhav Vij <mvij@ti.com>, Kevin Hilman
<khilman@ti.com>, Beno?t Cousson <b-cousson@ti.com>, and Santosh
Shilimkar <santosh.shilimkar@ti.com> all made essential contributions
to the understanding of EMU clockdomain power management on OMAP.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Jon Hunter <jon-hunter@ti.com>
Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Madhav Vij <mvij@ti.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Beno?t Cousson <b-cousson@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/clockdomain.c           |   17 +++++++++++++++++
 arch/arm/mach-omap2/clockdomain.h           |   20 +++++++++++++++++---
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c  |   22 ++++++++++++++++++++++
 arch/arm/mach-omap2/clockdomain44xx.c       |   11 +++++++++++
 arch/arm/mach-omap2/clockdomains3xxx_data.c |    7 ++-----
 arch/arm/mach-omap2/clockdomains44xx_data.c |    3 ++-
 arch/arm/mach-omap2/omap_hwmod.c            |    3 ++-
 arch/arm/mach-omap2/pm.c                    |    3 ++-
 8 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index b851ba4..17b1d32 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -914,6 +914,23 @@ bool clkdm_in_hwsup(struct clockdomain *clkdm)
 	return ret;
 }
 
+/**
+ * clkdm_missing_idle_reporting - can @clkdm enter autoidle even if in use?
+ * @clkdm: struct clockdomain *
+ *
+ * Returns true if clockdomain @clkdm has the
+ * CLKDM_MISSING_IDLE_REPORTING flag set, or false if not or @clkdm is
+ * null.  More information is available in the documentation for the
+ * CLKDM_MISSING_IDLE_REPORTING macro.
+ */
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)
+{
+	if (!clkdm)
+		return false;
+
+	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;
+}
+
 /* Clockdomain-to-clock/hwmod framework interface code */
 
 static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 7b3c1d2..fb5d37f 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -1,9 +1,7 @@
 /*
- * arch/arm/plat-omap/include/mach/clockdomain.h
- *
  * OMAP2/3 clockdomain framework functions
  *
- * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008, 2012 Texas Instruments, Inc.
  * Copyright (C) 2008-2011 Nokia Corporation
  *
  * Paul Walmsley
@@ -34,6 +32,20 @@
  * CLKDM_ACTIVE_WITH_MPU: The PRCM guarantees that this clockdomain is
  *     active whenever the MPU is active.  True for interconnects and
  *     the WKUP clockdomains.
+ * CLKDM_MISSING_IDLE_REPORTING: The idle status of the IP blocks and
+ *     clocks inside this clockdomain are not taken into account by
+ *     the PRCM when determining whether the clockdomain is idle.
+ *     Without this flag, if the clockdomain is set to
+ *     hardware-supervised idle mode, the PRCM may transition the
+ *     enclosing powerdomain to a low power state, even when devices
+ *     inside the clockdomain and powerdomain are in use.  (An example
+ *     of such a clockdomain is the EMU clockdomain on OMAP3/4.)  If
+ *     this flag is set, and the clockdomain does not support the
+ *     force-sleep mode, then the HW_AUTO mode will be used to put the
+ *     clockdomain to sleep.  Similarly, if the clockdomain supports
+ *     the force-wakeup mode, then it will be used whenever a clock or
+ *     IP block inside the clockdomain is active, rather than the
+ *     HW_AUTO mode.
  */
 #define CLKDM_CAN_FORCE_SLEEP			(1 << 0)
 #define CLKDM_CAN_FORCE_WAKEUP			(1 << 1)
@@ -41,6 +53,7 @@
 #define CLKDM_CAN_DISABLE_AUTO			(1 << 3)
 #define CLKDM_NO_AUTODEPS			(1 << 4)
 #define CLKDM_ACTIVE_WITH_MPU			(1 << 5)
+#define CLKDM_MISSING_IDLE_REPORTING		(1 << 6)
 
 #define CLKDM_CAN_HWSUP		(CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
 #define CLKDM_CAN_SWSUP		(CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
@@ -188,6 +201,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
 void clkdm_allow_idle(struct clockdomain *clkdm);
 void clkdm_deny_idle(struct clockdomain *clkdm);
 bool clkdm_in_hwsup(struct clockdomain *clkdm);
+bool clkdm_missing_idle_reporting(struct clockdomain *clkdm);
 
 int clkdm_wakeup(struct clockdomain *clkdm);
 int clkdm_sleep(struct clockdomain *clkdm);
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index f99e65c..3f4b04b 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -248,6 +248,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+		omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -271,6 +282,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index 762f2cc..6fc6155 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -113,6 +113,17 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->prcm_partition)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		omap4_clkdm_allow_idle(clkdm);
+		return 0;
+	}
+
 	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
 					clkdm->cm_inst, clkdm->clkdm_offs);
 
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
index 56089c4..933a35c 100644
--- a/arch/arm/mach-omap2/clockdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -387,14 +387,11 @@ static struct clockdomain per_am35x_clkdm = {
 	.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
- */
 static struct clockdomain emu_clkdm = {
 	.name		= "emu_clkdm",
 	.pwrdm		= { .name = "emu_pwrdm" },
-	.flags		= /* CLKDM_CAN_ENABLE_AUTO |  */CLKDM_CAN_SWSUP,
+	.flags		= (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP |
+			   CLKDM_MISSING_IDLE_REPORTING),
 	.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
 };
 
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index 63d60a7..b56d06b 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -390,7 +390,8 @@ static struct clockdomain emu_sys_44xx_clkdm = {
 	.prcm_partition	  = OMAP4430_PRM_PARTITION,
 	.cm_inst	  = OMAP4430_PRM_EMU_CM_INST,
 	.clkdm_offs	  = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
-	.flags		  = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP,
+	.flags		  = (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP |
+			     CLKDM_MISSING_IDLE_REPORTING),
 };
 
 static struct clockdomain l3_dma_44xx_clkdm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6ca8e51..36f0603 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1857,7 +1857,8 @@ static int _enable(struct omap_hwmod *oh)
 		 * completely the module. The clockdomain can be set
 		 * in HW_AUTO only when the module become ready.
 		 */
-		hwsup = clkdm_in_hwsup(oh->clkdm);
+		hwsup = clkdm_in_hwsup(oh->clkdm) &&
+			!clkdm_missing_idle_reporting(oh->clkdm);
 		r = clkdm_hwmod_enable(oh->clkdm, oh);
 		if (r) {
 			WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 9cb5ced..4182564 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -80,7 +80,8 @@ static void __init omap2_init_processor_devices(void)
 
 int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
-	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+	if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
+	    !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
 		clkdm_allow_idle(clkdm);
 	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
 		 atomic_read(&clkdm->usecount) == 0)
-- 
1.7.10.4

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-08-01 15:08                       ` Paul Walmsley
@ 2012-08-01 18:17                         ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-08-01 18:17 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon, linux-omap,
	linux-arm

Hi Paul,

On 08/01/2012 10:08 AM, Paul Walmsley wrote:
> Hi Jon,
> 
> On Tue, 31 Jul 2012, Jon Hunter wrote:
> 
>> Sorry for all the emails. However, I wanted to get this out to you as
>> I am due to be out for a couple weeks. 
>>
>> So I have updated your patch [1] with the following changes ...
>>
>> 1. Re-based on top of your omap3 clock domain fix [2]
>> 2. Modified the above change I mentioned to check for
>>    CLKDM_MISSING_IDLE_REPORTING in omap_pm_clkdms_setup() instead of
>>    the omap2_clkdm_clk_enable(). This is to prevent the clock domain
>>    being placed in HW_AUTO on boot if enabled early.
>> 3. Made the other change I mentioned earlier [3].
>>
>> This is now working well for me on OMAP3/4.
> 
> Your changes look good to me.  Do you have a strong preference as to 
> whether that patch should go in as part of 3.6-rc or 3.7?  I'd be inclined 
> to queue it for 3.7 based on the size of the patch.

Thanks for the feedback. 3.7 is fine with me, I don't expect the PMU
changes I have will be in before that.

Cheers
Jon

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-08-01 18:17                         ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-08-01 18:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 08/01/2012 10:08 AM, Paul Walmsley wrote:
> Hi Jon,
> 
> On Tue, 31 Jul 2012, Jon Hunter wrote:
> 
>> Sorry for all the emails. However, I wanted to get this out to you as
>> I am due to be out for a couple weeks. 
>>
>> So I have updated your patch [1] with the following changes ...
>>
>> 1. Re-based on top of your omap3 clock domain fix [2]
>> 2. Modified the above change I mentioned to check for
>>    CLKDM_MISSING_IDLE_REPORTING in omap_pm_clkdms_setup() instead of
>>    the omap2_clkdm_clk_enable(). This is to prevent the clock domain
>>    being placed in HW_AUTO on boot if enabled early.
>> 3. Made the other change I mentioned earlier [3].
>>
>> This is now working well for me on OMAP3/4.
> 
> Your changes look good to me.  Do you have a strong preference as to 
> whether that patch should go in as part of 3.6-rc or 3.7?  I'd be inclined 
> to queue it for 3.7 based on the size of the patch.

Thanks for the feedback. 3.7 is fine with me, I don't expect the PMU
changes I have will be in before that.

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-08-01 15:36                       ` Paul Walmsley
@ 2012-08-01 19:41                         ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-08-01 19:41 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon, Madhav Vij,
	Santosh Shilimkar, linux-omap, linux-arm

Hi Paul,

On 08/01/2012 10:36 AM, Paul Walmsley wrote:
> Hi Jon et al,
> 
> Here's what I'm planning to queue here.  The only changes from what Jon
> posted are the patch changelog and some checkpatch fixes.  If anyone
> has any final comments, please let me know.
> 
> 
> - Paul
> 
> From: Paul Walmsley <paul@pwsan.com>
> Date: Wed, 1 Aug 2012 09:11:20 -0600
> Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
>  clockdomain idle problems
> 
> The idle status of the IP blocks and clocks inside the EMU clockdomain
> isn't taken into account by the PRCM hardware when deciding whether
> the clockdomain is idle.  Add a workaround flag in the clockdomain
> code, CLKDM_MISSING_IDLE_REPORTING, to deal with this problem, and add
> the code necessary to support it.
> 
> If CLKDM_MISSING_IDLE_REPORTING is set on a clockdomain, the
> clockdomain will be forced active whenever an IP block inside that
> clockdomain is in use, even if the clockdomain supports
> hardware-supervised idle.  When the kernel indicates that the last
> active IP block inside the clockdomain is no longer used, the
> clockdomain will be forced idle, or, if that mode is not supported in
> the hardware, it will be placed into hardware-supervised idle.
> 
> This patch is an equal collaboration with Jon Hunter
> <jon-hunter@ti.com>.  Ming Lei <ming.lei@canonical.com>, Will Deacon
> <will.deacon@arm.com>, Madhav Vij <mvij@ti.com>, Kevin Hilman
> <khilman@ti.com>, Benoît Cousson <b-cousson@ti.com>, and Santosh
> Shilimkar <santosh.shilimkar@ti.com> all made essential contributions
> to the understanding of EMU clockdomain power management on OMAP.
> 
> Signed-off-by: Paul Walmsley <paul@pwsan.com>

Thanks for sending out. You can add my ...

Tested-by: Jon Hunter <jon-hunter@ti.com>

I have tested this on omap3430 (beagle), omap4430 (blaze) and omap4460
(panda) with perf and my PMU series [1]. I have verified that the EMU
power domain is transitioning correctly on these platforms. For OMAP3430
I checked that CORE retention is still being achieved with this change.

Cheers
Jon

[1] git@gitorious.org:linux-omap-dev/linux-omap-dev.git -b dev-pmu
--
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] 118+ messages in thread

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-08-01 19:41                         ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-08-01 19:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 08/01/2012 10:36 AM, Paul Walmsley wrote:
> Hi Jon et al,
> 
> Here's what I'm planning to queue here.  The only changes from what Jon
> posted are the patch changelog and some checkpatch fixes.  If anyone
> has any final comments, please let me know.
> 
> 
> - Paul
> 
> From: Paul Walmsley <paul@pwsan.com>
> Date: Wed, 1 Aug 2012 09:11:20 -0600
> Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
>  clockdomain idle problems
> 
> The idle status of the IP blocks and clocks inside the EMU clockdomain
> isn't taken into account by the PRCM hardware when deciding whether
> the clockdomain is idle.  Add a workaround flag in the clockdomain
> code, CLKDM_MISSING_IDLE_REPORTING, to deal with this problem, and add
> the code necessary to support it.
> 
> If CLKDM_MISSING_IDLE_REPORTING is set on a clockdomain, the
> clockdomain will be forced active whenever an IP block inside that
> clockdomain is in use, even if the clockdomain supports
> hardware-supervised idle.  When the kernel indicates that the last
> active IP block inside the clockdomain is no longer used, the
> clockdomain will be forced idle, or, if that mode is not supported in
> the hardware, it will be placed into hardware-supervised idle.
> 
> This patch is an equal collaboration with Jon Hunter
> <jon-hunter@ti.com>.  Ming Lei <ming.lei@canonical.com>, Will Deacon
> <will.deacon@arm.com>, Madhav Vij <mvij@ti.com>, Kevin Hilman
> <khilman@ti.com>, Beno?t Cousson <b-cousson@ti.com>, and Santosh
> Shilimkar <santosh.shilimkar@ti.com> all made essential contributions
> to the understanding of EMU clockdomain power management on OMAP.
> 
> Signed-off-by: Paul Walmsley <paul@pwsan.com>

Thanks for sending out. You can add my ...

Tested-by: Jon Hunter <jon-hunter@ti.com>

I have tested this on omap3430 (beagle), omap4430 (blaze) and omap4460
(panda) with perf and my PMU series [1]. I have verified that the EMU
power domain is transitioning correctly on these platforms. For OMAP3430
I checked that CORE retention is still being achieved with this change.

Cheers
Jon

[1] git at gitorious.org:linux-omap-dev/linux-omap-dev.git -b dev-pmu

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-07-31 23:07                                     ` Jon Hunter
@ 2012-08-01 20:47                                       ` Will Deacon
  -1 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-08-01 20:47 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm

On Wed, Aug 01, 2012 at 12:07:16AM +0100, Jon Hunter wrote:
> I have just updated my pmu branch for omap3/4. You can pull my latest
> patches from [1].

Great, thanks for that. I've pushed out to perf/omap4 and I've also
included your runtime PM hooks in my perf/updates branch. I have a fair
amount of cleanup sitting in there as well, so I'll post that to the list
at -rc1 as a candidate for -next. I'll obviously leave the omap-specific
bits for others to handle, although I'll continue maintaining my branch
until that's hit mainline.

> In the latest series I have:
> 1. Pulled in an omap3 clock domain fix from Paul [2]
> 2. Rebased Paul's patch [3] on top of [2]. I have also made a couple
>    updates to this patch and I need to get Paul's feedback.
> 3. I have removed the OMAP3 PMU dependency on ETM from the Kconfig.

Fantastic! I actually already removed the OMAP3 Kconfig dependency in my
perf/updates branch as part of removing CPU_HAS_PMU entirely, so you
probably don't need to pursue that patch.

> I will probably send out the series once I align with Paul on the above
> changes and the HWMOD stuff I have added for OMAP3 with Benoit.

Okey doke. If you need me to update my copy of your runtime PM patch,
please shout (that seems to be a done deal afaict).

Will

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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-08-01 20:47                                       ` Will Deacon
  0 siblings, 0 replies; 118+ messages in thread
From: Will Deacon @ 2012-08-01 20:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 01, 2012 at 12:07:16AM +0100, Jon Hunter wrote:
> I have just updated my pmu branch for omap3/4. You can pull my latest
> patches from [1].

Great, thanks for that. I've pushed out to perf/omap4 and I've also
included your runtime PM hooks in my perf/updates branch. I have a fair
amount of cleanup sitting in there as well, so I'll post that to the list
at -rc1 as a candidate for -next. I'll obviously leave the omap-specific
bits for others to handle, although I'll continue maintaining my branch
until that's hit mainline.

> In the latest series I have:
> 1. Pulled in an omap3 clock domain fix from Paul [2]
> 2. Rebased Paul's patch [3] on top of [2]. I have also made a couple
>    updates to this patch and I need to get Paul's feedback.
> 3. I have removed the OMAP3 PMU dependency on ETM from the Kconfig.

Fantastic! I actually already removed the OMAP3 Kconfig dependency in my
perf/updates branch as part of removing CPU_HAS_PMU entirely, so you
probably don't need to pursue that patch.

> I will probably send out the series once I align with Paul on the above
> changes and the HWMOD stuff I have added for OMAP3 with Benoit.

Okey doke. If you need me to update my copy of your runtime PM patch,
please shout (that seems to be a done deal afaict).

Will

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

* Re: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
  2012-08-01 20:47                                       ` Will Deacon
@ 2012-08-01 22:34                                         ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-08-01 22:34 UTC (permalink / raw)
  To: Will Deacon
  Cc: Kevin Hilman, Paul Walmsley, Benoit Cousson, Ming Lei,
	linux-omap, linux-arm


On 08/01/2012 03:47 PM, Will Deacon wrote:
> On Wed, Aug 01, 2012 at 12:07:16AM +0100, Jon Hunter wrote:
>> I have just updated my pmu branch for omap3/4. You can pull my latest
>> patches from [1].
> 
> Great, thanks for that. I've pushed out to perf/omap4 and I've also
> included your runtime PM hooks in my perf/updates branch. I have a fair
> amount of cleanup sitting in there as well, so I'll post that to the list
> at -rc1 as a candidate for -next. I'll obviously leave the omap-specific
> bits for others to handle, although I'll continue maintaining my branch
> until that's hit mainline.

I just updated today with Paul's latest patch he sent. I don't think
much changed from what I had in there yesterday.

>> In the latest series I have:
>> 1. Pulled in an omap3 clock domain fix from Paul [2]
>> 2. Rebased Paul's patch [3] on top of [2]. I have also made a couple
>>    updates to this patch and I need to get Paul's feedback.
>> 3. I have removed the OMAP3 PMU dependency on ETM from the Kconfig.
> 
> Fantastic! I actually already removed the OMAP3 Kconfig dependency in my
> perf/updates branch as part of removing CPU_HAS_PMU entirely, so you
> probably don't need to pursue that patch.

Great! Glad I don't have to worry about that.

>> I will probably send out the series once I align with Paul on the above
>> changes and the HWMOD stuff I have added for OMAP3 with Benoit.
> 
> Okey doke. If you need me to update my copy of your runtime PM patch,
> please shout (that seems to be a done deal afaict).

Yes it is good as far as I am concerned.

I am going to be out for a couple weeks, but when I get back I will get
the OMAP stuff out. I should probably doing some testing on -next too
with your latest changes.

Cheers
Jon



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

* [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
@ 2012-08-01 22:34                                         ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-08-01 22:34 UTC (permalink / raw)
  To: linux-arm-kernel


On 08/01/2012 03:47 PM, Will Deacon wrote:
> On Wed, Aug 01, 2012 at 12:07:16AM +0100, Jon Hunter wrote:
>> I have just updated my pmu branch for omap3/4. You can pull my latest
>> patches from [1].
> 
> Great, thanks for that. I've pushed out to perf/omap4 and I've also
> included your runtime PM hooks in my perf/updates branch. I have a fair
> amount of cleanup sitting in there as well, so I'll post that to the list
> at -rc1 as a candidate for -next. I'll obviously leave the omap-specific
> bits for others to handle, although I'll continue maintaining my branch
> until that's hit mainline.

I just updated today with Paul's latest patch he sent. I don't think
much changed from what I had in there yesterday.

>> In the latest series I have:
>> 1. Pulled in an omap3 clock domain fix from Paul [2]
>> 2. Rebased Paul's patch [3] on top of [2]. I have also made a couple
>>    updates to this patch and I need to get Paul's feedback.
>> 3. I have removed the OMAP3 PMU dependency on ETM from the Kconfig.
> 
> Fantastic! I actually already removed the OMAP3 Kconfig dependency in my
> perf/updates branch as part of removing CPU_HAS_PMU entirely, so you
> probably don't need to pursue that patch.

Great! Glad I don't have to worry about that.

>> I will probably send out the series once I align with Paul on the above
>> changes and the HWMOD stuff I have added for OMAP3 with Benoit.
> 
> Okey doke. If you need me to update my copy of your runtime PM patch,
> please shout (that seems to be a done deal afaict).

Yes it is good as far as I am concerned.

I am going to be out for a couple weeks, but when I get back I will get
the OMAP stuff out. I should probably doing some testing on -next too
with your latest changes.

Cheers
Jon

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-08-01 15:36                       ` Paul Walmsley
@ 2012-08-02  7:34                         ` Shilimkar, Santosh
  -1 siblings, 0 replies; 118+ messages in thread
From: Shilimkar, Santosh @ 2012-08-02  7:34 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Jon Hunter, Kevin Hilman, Ming Lei, Will Deacon, Madhav Vij,
	Benoît Cousson, linux-omap, linux-arm

On Wed, Aug 1, 2012 at 9:06 PM, Paul Walmsley <paul@pwsan.com> wrote:
>
> Hi Jon et al,
>
> Here's what I'm planning to queue here.  The only changes from what Jon
> posted are the patch changelog and some checkpatch fixes.  If anyone
> has any final comments, please let me know.
>
>
> - Paul
>
> From: Paul Walmsley <paul@pwsan.com>
> Date: Wed, 1 Aug 2012 09:11:20 -0600
> Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
>  clockdomain idle problems
>
> The idle status of the IP blocks and clocks inside the EMU clockdomain
> isn't taken into account by the PRCM hardware when deciding whether
> the clockdomain is idle.  Add a workaround flag in the clockdomain
> code, CLKDM_MISSING_IDLE_REPORTING, to deal with this problem, and add
> the code necessary to support it.
>
> If CLKDM_MISSING_IDLE_REPORTING is set on a clockdomain, the
> clockdomain will be forced active whenever an IP block inside that
> clockdomain is in use, even if the clockdomain supports
> hardware-supervised idle.  When the kernel indicates that the last
> active IP block inside the clockdomain is no longer used, the
> clockdomain will be forced idle, or, if that mode is not supported in
> the hardware, it will be placed into hardware-supervised idle.
>
> This patch is an equal collaboration with Jon Hunter
> <jon-hunter@ti.com>.  Ming Lei <ming.lei@canonical.com>, Will Deacon
> <will.deacon@arm.com>, Madhav Vij <mvij@ti.com>, Kevin Hilman
> <khilman@ti.com>, Benoît Cousson <b-cousson@ti.com>, and Santosh
> Shilimkar <santosh.shilimkar@ti.com> all made essential contributions
> to the understanding of EMU clockdomain power management on OMAP.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Jon Hunter <jon-hunter@ti.com>
> Cc: Ming Lei <ming.lei@canonical.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Madhav Vij <mvij@ti.com>
> Cc: Kevin Hilman <khilman@ti.com>
> Cc: Benoît Cousson <b-cousson@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
--
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] 118+ messages in thread

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-08-02  7:34                         ` Shilimkar, Santosh
  0 siblings, 0 replies; 118+ messages in thread
From: Shilimkar, Santosh @ 2012-08-02  7:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 1, 2012 at 9:06 PM, Paul Walmsley <paul@pwsan.com> wrote:
>
> Hi Jon et al,
>
> Here's what I'm planning to queue here.  The only changes from what Jon
> posted are the patch changelog and some checkpatch fixes.  If anyone
> has any final comments, please let me know.
>
>
> - Paul
>
> From: Paul Walmsley <paul@pwsan.com>
> Date: Wed, 1 Aug 2012 09:11:20 -0600
> Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
>  clockdomain idle problems
>
> The idle status of the IP blocks and clocks inside the EMU clockdomain
> isn't taken into account by the PRCM hardware when deciding whether
> the clockdomain is idle.  Add a workaround flag in the clockdomain
> code, CLKDM_MISSING_IDLE_REPORTING, to deal with this problem, and add
> the code necessary to support it.
>
> If CLKDM_MISSING_IDLE_REPORTING is set on a clockdomain, the
> clockdomain will be forced active whenever an IP block inside that
> clockdomain is in use, even if the clockdomain supports
> hardware-supervised idle.  When the kernel indicates that the last
> active IP block inside the clockdomain is no longer used, the
> clockdomain will be forced idle, or, if that mode is not supported in
> the hardware, it will be placed into hardware-supervised idle.
>
> This patch is an equal collaboration with Jon Hunter
> <jon-hunter@ti.com>.  Ming Lei <ming.lei@canonical.com>, Will Deacon
> <will.deacon@arm.com>, Madhav Vij <mvij@ti.com>, Kevin Hilman
> <khilman@ti.com>, Beno?t Cousson <b-cousson@ti.com>, and Santosh
> Shilimkar <santosh.shilimkar@ti.com> all made essential contributions
> to the understanding of EMU clockdomain power management on OMAP.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Jon Hunter <jon-hunter@ti.com>
> Cc: Ming Lei <ming.lei@canonical.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Madhav Vij <mvij@ti.com>
> Cc: Kevin Hilman <khilman@ti.com>
> Cc: Beno?t Cousson <b-cousson@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-08-01 15:36                       ` Paul Walmsley
@ 2012-10-08 22:24                         ` Jon Hunter
  -1 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-10-08 22:24 UTC (permalink / raw)
  To: Paul Walmsley
  Cc: Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon, Madhav Vij,
	Santosh Shilimkar, linux-omap, linux-arm

Hi Paul,

On 08/01/2012 10:36 AM, Paul Walmsley wrote:
> Hi Jon et al,
> 
> Here's what I'm planning to queue here.  The only changes from what Jon
> posted are the patch changelog and some checkpatch fixes.  If anyone
> has any final comments, please let me know.
> 
> 
> - Paul
> 
> From: Paul Walmsley <paul@pwsan.com>
> Date: Wed, 1 Aug 2012 09:11:20 -0600
> Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
>  clockdomain idle problems

[snip]

> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> index f99e65c..3f4b04b 100644
> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> @@ -248,6 +248,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
> +	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
> +		omap3_clkdm_wakeup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);
>  
> @@ -271,6 +282,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +		_enable_hwsup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);

I was looking at what got merged and it appears that the above code was
added to the omap2 clkdm enable/disable functions and not omap3. I believe
that is a mistake? If so the below fixes this.

Cheers
Jon

>From 16db11f3373bc6e03254c4d1d92ee762f69cbacc Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Wed, 1 Aug 2012 09:36:13 -0600
Subject: [PATCH] ARM: OMAP3: fix workaround for EMU clockdomain

Commit b71c721 (ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
clockdomain idle problems) added a workaround for the EMU clock domain on
OMAP3/4 devices to prevent the clock domain for transitioning while it is
in use.

In the proposed patch [1] code was added to the omap3xxx_clkdm_clk_enable()
and omap3xxx_clkdm_clk_disable() functions to check for the flag
CLKDM_MISSING_IDLE_REPORTING and perform the appropriate action. However, in the
merged patch it appears that this code was added to the omap2_clkdm_clk_enable()
and omap2_clkdm_clk_disable() functions by mistake.

[1] http://marc.info/?l=linux-arm-kernel&m=134383567112518&w=2

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c |   44 ++++++++++++++--------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index 9a7792a..70294f5 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -183,17 +183,6 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
-	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
-		_enable_hwsup(clkdm);
-		return 0;
-	}
-
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -217,17 +206,6 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
-	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
-		omap3_clkdm_wakeup(clkdm);
-		return 0;
-	}
-
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -269,6 +247,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+		omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -292,6 +281,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
-- 
1.7.9.5


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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-10-08 22:24                         ` Jon Hunter
  0 siblings, 0 replies; 118+ messages in thread
From: Jon Hunter @ 2012-10-08 22:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul,

On 08/01/2012 10:36 AM, Paul Walmsley wrote:
> Hi Jon et al,
> 
> Here's what I'm planning to queue here.  The only changes from what Jon
> posted are the patch changelog and some checkpatch fixes.  If anyone
> has any final comments, please let me know.
> 
> 
> - Paul
> 
> From: Paul Walmsley <paul@pwsan.com>
> Date: Wed, 1 Aug 2012 09:11:20 -0600
> Subject: [PATCH] ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
>  clockdomain idle problems

[snip]

> diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> index f99e65c..3f4b04b 100644
> --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
> @@ -248,6 +248,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
> +	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
> +		omap3_clkdm_wakeup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);
>  
> @@ -271,6 +282,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
>  	if (!clkdm->clktrctrl_mask)
>  		return 0;
>  
> +	/*
> +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
> +	 * more details on the unpleasant problem this is working
> +	 * around
> +	 */
> +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
> +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
> +		_enable_hwsup(clkdm);
> +		return 0;
> +	}
> +
>  	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
>  				clkdm->clktrctrl_mask);

I was looking at what got merged and it appears that the above code was
added to the omap2 clkdm enable/disable functions and not omap3. I believe
that is a mistake? If so the below fixes this.

Cheers
Jon

>From 16db11f3373bc6e03254c4d1d92ee762f69cbacc Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Wed, 1 Aug 2012 09:36:13 -0600
Subject: [PATCH] ARM: OMAP3: fix workaround for EMU clockdomain

Commit b71c721 (ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU
clockdomain idle problems) added a workaround for the EMU clock domain on
OMAP3/4 devices to prevent the clock domain for transitioning while it is
in use.

In the proposed patch [1] code was added to the omap3xxx_clkdm_clk_enable()
and omap3xxx_clkdm_clk_disable() functions to check for the flag
CLKDM_MISSING_IDLE_REPORTING and perform the appropriate action. However, in the
merged patch it appears that this code was added to the omap2_clkdm_clk_enable()
and omap2_clkdm_clk_disable() functions by mistake.

[1] http://marc.info/?l=linux-arm-kernel&m=134383567112518&w=2

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c |   44 ++++++++++++++--------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index 9a7792a..70294f5 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -183,17 +183,6 @@ static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
-	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
-		_enable_hwsup(clkdm);
-		return 0;
-	}
-
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -217,17 +206,6 @@ static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
-	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
-		omap3_clkdm_wakeup(clkdm);
-		return 0;
-	}
-
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -269,6 +247,17 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+		omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -292,6 +281,17 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
-- 
1.7.9.5

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

* Re: [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
  2012-10-08 22:24                         ` Jon Hunter
@ 2012-10-09  4:41                           ` Paul Walmsley
  -1 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-10-09  4:41 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Kevin Hilman, Benoit Cousson, Ming Lei, Will Deacon, Madhav Vij,
	Santosh Shilimkar, linux-omap, linux-arm

Hi Jon,

On Mon, 8 Oct 2012, Jon Hunter wrote:

> I was looking at what got merged and it appears that the above code was
> added to the omap2 clkdm enable/disable functions and not omap3. I believe
> that is a mistake? If so the below fixes this.

Yep looks like either a mismerge or a victim of a rebase -- queued for 
late 3.7 fixes -- thanks,

- Paul

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

* [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use
@ 2012-10-09  4:41                           ` Paul Walmsley
  0 siblings, 0 replies; 118+ messages in thread
From: Paul Walmsley @ 2012-10-09  4:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

On Mon, 8 Oct 2012, Jon Hunter wrote:

> I was looking at what got merged and it appears that the above code was
> added to the omap2 clkdm enable/disable functions and not omap3. I believe
> that is a mistake? If so the below fixes this.

Yep looks like either a mismerge or a victim of a rebase -- queued for 
late 3.7 fixes -- thanks,

- Paul

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

end of thread, other threads:[~2012-10-09  4:41 UTC | newest]

Thread overview: 118+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-07 21:22 [PATCH V2 00/10] ARM: OMAP4: Add PMU Support Jon Hunter
2012-06-07 21:22 ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 01/10] ARM: PMU: Add runtime PM Support Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-06-08  9:47   ` Will Deacon
2012-06-08  9:47     ` Will Deacon
2012-06-08 14:17     ` Jon Hunter
2012-06-08 14:17       ` Jon Hunter
2012-06-08 15:24     ` Jon Hunter
2012-06-08 15:24       ` Jon Hunter
2012-06-11 17:39       ` Will Deacon
2012-06-11 17:39         ` Will Deacon
2012-06-11 19:01         ` Jon Hunter
2012-06-11 19:01           ` Jon Hunter
2012-06-12  9:28           ` Will Deacon
2012-06-12  9:28             ` Will Deacon
2012-06-12 21:17             ` Jon Hunter
2012-06-12 21:17               ` Jon Hunter
2012-06-12 21:31               ` Will Deacon
2012-06-12 21:31                 ` Will Deacon
2012-06-12 22:41                 ` Jon Hunter
2012-06-12 22:41                   ` Jon Hunter
2012-07-02  9:55                   ` Will Deacon
2012-07-02  9:55                     ` Will Deacon
2012-07-02 16:50                     ` Jon Hunter
2012-07-02 16:50                       ` Jon Hunter
2012-07-02 22:01                       ` Will Deacon
2012-07-02 22:01                         ` Will Deacon
2012-07-06  0:40                         ` Jon Hunter
2012-07-06  0:40                           ` Jon Hunter
2012-07-26  0:41                           ` Jon Hunter
2012-07-26  0:41                             ` Jon Hunter
2012-07-26 15:05                             ` Will Deacon
2012-07-26 15:05                               ` Will Deacon
2012-07-26 15:16                               ` Jon Hunter
2012-07-26 15:16                                 ` Jon Hunter
2012-07-31 15:14                                 ` Will Deacon
2012-07-31 15:14                                   ` Will Deacon
2012-07-31 23:07                                   ` Jon Hunter
2012-07-31 23:07                                     ` Jon Hunter
2012-08-01 20:47                                     ` Will Deacon
2012-08-01 20:47                                       ` Will Deacon
2012-08-01 22:34                                       ` Jon Hunter
2012-08-01 22:34                                         ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 02/10] ARM: OMAP2+: PMU: Convert OMAP2/3 devices to use HWMOD Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-06-13  6:07   ` Pandita, Vikram
2012-06-13  6:07     ` Pandita, Vikram
2012-06-13  6:13     ` Pandita, Vikram
2012-06-13  6:13       ` Pandita, Vikram
2012-06-13  6:19       ` Shilimkar, Santosh
2012-06-13  6:19         ` Shilimkar, Santosh
2012-06-07 21:22 ` [PATCH V2 04/10] ARM: OMAP4430: Create PMU device via HWMOD Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 05/10] ARM: OMAP2+: PMU: Add runtime PM support Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 06/10] ARM: OMAP4: Route PMU IRQs to CTI IRQs Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 07/10] ARM: OMAP4: CLKDM: Update supported transition modes Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-07-04 15:38   ` Paul Walmsley
2012-07-04 15:38     ` Paul Walmsley
2012-07-05 17:14     ` Jon Hunter
2012-07-05 17:14       ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-07-12 21:17   ` Paul Walmsley
2012-07-12 21:17     ` Paul Walmsley
2012-07-13 13:54     ` Jon Hunter
2012-07-13 13:54       ` Jon Hunter
2012-07-13 14:00       ` Will Deacon
2012-07-13 14:00         ` Will Deacon
2012-07-13 14:07         ` Jon Hunter
2012-07-13 14:07           ` Jon Hunter
2012-07-20 22:24         ` Jon Hunter
2012-07-20 22:24           ` Jon Hunter
2012-07-13 21:00       ` Paul Walmsley
2012-07-13 21:00         ` Paul Walmsley
2012-07-16 18:27         ` Jon Hunter
2012-07-16 18:27           ` Jon Hunter
2012-07-16 18:38           ` Paul Walmsley
2012-07-16 18:38             ` Paul Walmsley
2012-07-16 19:38             ` Jon Hunter
2012-07-16 19:38               ` Jon Hunter
2012-07-20 22:24             ` Jon Hunter
2012-07-20 22:24               ` Jon Hunter
2012-07-30 23:26             ` Jon Hunter
2012-07-30 23:26               ` Jon Hunter
2012-07-31  4:36               ` Jon Hunter
2012-07-31  4:36                 ` Jon Hunter
2012-07-31 18:16                 ` Jon Hunter
2012-07-31 18:16                   ` Jon Hunter
2012-08-01  0:20                   ` Jon Hunter
2012-08-01  0:20                     ` Jon Hunter
2012-08-01 15:08                     ` Paul Walmsley
2012-08-01 15:08                       ` Paul Walmsley
2012-08-01 18:17                       ` Jon Hunter
2012-08-01 18:17                         ` Jon Hunter
2012-08-01 15:36                     ` Paul Walmsley
2012-08-01 15:36                       ` Paul Walmsley
2012-08-01 19:41                       ` Jon Hunter
2012-08-01 19:41                         ` Jon Hunter
2012-08-02  7:34                       ` Shilimkar, Santosh
2012-08-02  7:34                         ` Shilimkar, Santosh
2012-10-08 22:24                       ` Jon Hunter
2012-10-08 22:24                         ` Jon Hunter
2012-10-09  4:41                         ` Paul Walmsley
2012-10-09  4:41                           ` Paul Walmsley
2012-07-31 20:56     ` Jon Hunter
2012-07-31 20:56       ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 09/10] ARM: OMAP4: Enable PMU for OMAP4460/70 Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 10/10] ARM: OMAP2+: PMU: Add QoS constraint Jon Hunter
2012-06-07 21:22   ` Jon Hunter
2012-06-07 23:36 ` [PATCH V2 00/10] ARM: OMAP4: Add PMU Support Jon Hunter
2012-06-07 23:36   ` Jon Hunter

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.