linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states
@ 2019-07-30 12:51 Andrew Murray
  2019-07-30 12:51 ` [PATCH v4 1/6] coresight: etm4x: remove superfluous setting of os_unlock Andrew Murray
                   ` (6 more replies)
  0 siblings, 7 replies; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 12:51 UTC (permalink / raw)
  To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
  Cc: Al.Grant, coresight, Leo Yan, Sudeep Holla, linux-arm-kernel, Mike Leach

Some hardware will ignore bit TRCPDCR.PU which is used to signal
to hardware that power should not be removed from the trace unit.
Let's mitigate against this by conditionally saving and restoring
the trace unit state when the CPU enters low power states.

This patchset introduces a firmware property named
'arm,coresight-needs-save-restore' - when this is present the
hardware state will be conditionally saved and restored.

A module parameter 'pm_save_enable' is also introduced which can
be configured to override the firmware property.

The hardware state is only ever saved and restored when a self-hosted
coresight is in use.

Changes since v3:

 - Only save/restore when self-hosted is being used and detect this
   without relying on the coresight registers (which may not be
   available)

 - Only allocate memory for etmv4_save_state at probe time when
   configuration indicates it may be used

 - Set pm_save_enable param to 0444 such that it is static after
   boot

 - Save/restore TRCPDCR

 - Add missing comments to struct etm4_drvdata documentation

 - Rebased onto coresight/next (8f1f9857)

Changes since v2:

 - Move the PM notifier block from drvdata to file static

 - Add section names to document references

 - Add additional information to commit messages

 - Remove trcdvcvr and trcdvcmr from saved state and add a comment to
   describe why

 - Ensure TRCPDCR_PU is set after restore and add a comment to explain
   why we bother toggling TRCPDCR_PU on save/restore

 - Reword the pm_save_enable options and add comments

 - Miscellaneous style changes

 - Move device tree binding documentation to its own patch

Changes since v1:

 - Rebased onto coresight/next

 - Correcly pass bit number rather than BIT macro to coresight_timeout

 - Abort saving state if a timeout occurs

 - Fix completely broken pm_notify handling and unregister handler on error

 - Use state_needs_restore to ensure state is restored only once

 - Add module parameter description to existing boot_enable parameter
   and use module_param instead of module_param_named

 - Add firmware bindings for coresight-needs-save-restore

 - Rename 'disable_pm_save' to 'pm_save_enable' which allows for
   disabled, enabled or firmware

 - Update comment on etm4_os_lock, it incorrectly indicated that
   the code unlocks the trace registers

 - Add comments to explain use of OS lock during save/restore

 - Fix incorrect error description whilst waiting for PM stable

 - Add WARN_ON_ONCE when cpu isn't as expected during save/restore

 - Various updates to commit messages


Andrew Murray (6):
  coresight: etm4x: remove superfluous setting of os_unlock
  coresight: etm4x: use explicit barriers on enable/disable
  coresight: etm4x: use module_param instead of module_param_named
  coresight: etm4x: improve clarity of etm4_os_unlock comment
  coresight: etm4x: save/restore state across CPU low power states
  dt-bindings: arm: coresight: Add support for
    coresight-needs-save-restore

 .../devicetree/bindings/arm/coresight.txt     |   3 +
 drivers/hwtracing/coresight/coresight-etm4x.c | 346 +++++++++++++++++-
 drivers/hwtracing/coresight/coresight-etm4x.h |  64 ++++
 3 files changed, 406 insertions(+), 7 deletions(-)

-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v4 1/6] coresight: etm4x: remove superfluous setting of os_unlock
  2019-07-30 12:51 [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Andrew Murray
@ 2019-07-30 12:51 ` Andrew Murray
  2019-07-30 12:51 ` [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable Andrew Murray
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 12:51 UTC (permalink / raw)
  To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
  Cc: Al.Grant, coresight, Leo Yan, Sudeep Holla, linux-arm-kernel, Mike Leach

In addition to unlocking the OS lock, etm4_os_unlock will also
set the os_unlock flag. Therefore let's avoid unnecessarily
setting os_unlock flag outside of this function.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 28bcc0e58d7a..7ad15651e069 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1047,10 +1047,8 @@ static int etm4_starting_cpu(unsigned int cpu)
 		return 0;
 
 	spin_lock(&etmdrvdata[cpu]->spinlock);
-	if (!etmdrvdata[cpu]->os_unlock) {
+	if (!etmdrvdata[cpu]->os_unlock)
 		etm4_os_unlock(etmdrvdata[cpu]);
-		etmdrvdata[cpu]->os_unlock = true;
-	}
 
 	if (local_read(&etmdrvdata[cpu]->mode))
 		etm4_enable_hw(etmdrvdata[cpu]);
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable
  2019-07-30 12:51 [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Andrew Murray
  2019-07-30 12:51 ` [PATCH v4 1/6] coresight: etm4x: remove superfluous setting of os_unlock Andrew Murray
@ 2019-07-30 12:51 ` Andrew Murray
  2019-08-01 13:31   ` Sasha Levin
  2019-08-02 18:08   ` Sasha Levin
  2019-07-30 12:51 ` [PATCH v4 3/6] coresight: etm4x: use module_param instead of module_param_named Andrew Murray
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 12:51 UTC (permalink / raw)
  To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
  Cc: Al.Grant, coresight, Leo Yan, stable, Sudeep Holla,
	linux-arm-kernel, Mike Leach

Synchronization is recommended before disabling the trace registers
to prevent any start or stop points being speculative at the point
of disabling the unit (section 7.3.77 of ARM IHI 0064D).

Synchronization is also recommended after programming the trace
registers to ensure all updates are committed prior to normal code
resuming (section 4.3.7 of ARM IHI 0064D).

Let's ensure these syncronization points are present in the code
and clearly commented.

Note that we could rely on the barriers in CS_LOCK and
coresight_disclaim_device_unlocked or the context switch to user
space - however coresight may be of use in the kernel.

On armv8 the mb macro is defined as dsb(sy) - Given that the etm4x is
only used on armv8 let's directly use dsb(sy) instead of mb(). This
removes some ambiguity and makes it easier to correlate the code with
the TRM.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
CC: stable@vger.kernel.org
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 7ad15651e069..ec9468880c71 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -188,6 +188,13 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
 		dev_err(etm_dev,
 			"timeout while waiting for Idle Trace Status\n");
 
+	/*
+	 * As recommended by section 4.3.7 ("Synchronization when using the
+	 * memory-mapped interface") of ARM IHI 0064D
+	 */
+	dsb(sy);
+	isb();
+
 done:
 	CS_LOCK(drvdata->base);
 
@@ -453,8 +460,12 @@ static void etm4_disable_hw(void *info)
 	/* EN, bit[0] Trace unit enable bit */
 	control &= ~0x1;
 
-	/* make sure everything completes before disabling */
-	mb();
+	/*
+	 * Make sure everything completes before disabling, as recommended
+	 * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register,
+	 * SSTATUS") of ARM IHI 0064D
+	 */
+	dsb(sy);
 	isb();
 	writel_relaxed(control, drvdata->base + TRCPRGCTLR);
 
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v4 3/6] coresight: etm4x: use module_param instead of module_param_named
  2019-07-30 12:51 [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Andrew Murray
  2019-07-30 12:51 ` [PATCH v4 1/6] coresight: etm4x: remove superfluous setting of os_unlock Andrew Murray
  2019-07-30 12:51 ` [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable Andrew Murray
@ 2019-07-30 12:51 ` Andrew Murray
  2019-08-02 10:23   ` Suzuki K Poulose
  2019-07-30 12:51 ` [PATCH v4 4/6] coresight: etm4x: improve clarity of etm4_os_unlock comment Andrew Murray
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 12:51 UTC (permalink / raw)
  To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
  Cc: Al.Grant, coresight, Leo Yan, Sudeep Holla, linux-arm-kernel, Mike Leach

Given that the user-exposed module parameter for 'boot_enable' matches
the variable that it sets, let's use module_param instead of
module_param_named.

Let's also use octal permissions (checkpatch recommends this) and
provide a module parameter description.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index ec9468880c71..615bdbf7c9b7 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -34,7 +34,8 @@
 #include "coresight-etm-perf.h"
 
 static int boot_enable;
-module_param_named(boot_enable, boot_enable, int, S_IRUGO);
+module_param(boot_enable, int, 0444);
+MODULE_PARM_DESC(boot_enable, "Enable tracing on boot");
 
 /* The number of ETMv4 currently registered */
 static int etm4_count;
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v4 4/6] coresight: etm4x: improve clarity of etm4_os_unlock comment
  2019-07-30 12:51 [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Andrew Murray
                   ` (2 preceding siblings ...)
  2019-07-30 12:51 ` [PATCH v4 3/6] coresight: etm4x: use module_param instead of module_param_named Andrew Murray
@ 2019-07-30 12:51 ` Andrew Murray
  2019-07-30 12:51 ` [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states Andrew Murray
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 12:51 UTC (permalink / raw)
  To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
  Cc: Al.Grant, coresight, Leo Yan, Sudeep Holla, linux-arm-kernel, Mike Leach

To improve clarity, let's update the comment for etm4_os_unlock
to use the name of the register as per the ETM architecture
specification.

The existing comment is also misleading as it suggests any value
written to TRCOSLAR unlocks the trace registers, however it must
be '0' - let's also correct this.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 615bdbf7c9b7..a128b5063f46 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -48,7 +48,7 @@ static enum cpuhp_state hp_online;
 
 static void etm4_os_unlock(struct etmv4_drvdata *drvdata)
 {
-	/* Writing any value to ETMOSLAR unlocks the trace registers */
+	/* Writing 0 to TRCOSLAR unlocks the trace registers */
 	writel_relaxed(0x0, drvdata->base + TRCOSLAR);
 	drvdata->os_unlock = true;
 	isb();
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states
  2019-07-30 12:51 [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Andrew Murray
                   ` (3 preceding siblings ...)
  2019-07-30 12:51 ` [PATCH v4 4/6] coresight: etm4x: improve clarity of etm4_os_unlock comment Andrew Murray
@ 2019-07-30 12:51 ` Andrew Murray
  2019-07-30 21:16   ` Mathieu Poirier
  2019-08-02 10:54   ` Suzuki K Poulose
  2019-07-30 12:51 ` [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore Andrew Murray
  2019-07-30 20:12 ` [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Mathieu Poirier
  6 siblings, 2 replies; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 12:51 UTC (permalink / raw)
  To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
  Cc: Al.Grant, coresight, Leo Yan, Sudeep Holla, linux-arm-kernel, Mike Leach

Some hardware will ignore bit TRCPDCR.PU which is used to signal
to hardware that power should not be removed from the trace unit.
Let's mitigate against this by conditionally saving and restoring
the trace unit state when the CPU enters low power states.

This patchset introduces a firmware property named
'arm,coresight-needs-save-restore' - when this is present the
hardware state will be conditionally saved and restored.

A module parameter 'pm_save_enable' is also introduced which can
be configured to override the firmware property. This can be set
to never allow save/restore, to conditionally allow it, or to
do as the firmware indicates (default).

We avoid saving the hardware state when coresight isn't in use
to reduce PM latency - we can't determine this by reading the
claim tags (TRCCLAIMCLR) as these are 'trace' registers which need
power and clocking, something we can't easily provide in the PM
context. Therefore we rely on the existing drvdata->mode internal
state that is set when self-hosted coresight is used (and powered).

As we do not have a simple way of determining if an external agent
is using coresight, we don't save/restore for this use case.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 322 ++++++++++++++++++
 drivers/hwtracing/coresight/coresight-etm4x.h |  64 ++++
 2 files changed, 386 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index a128b5063f46..30f118792289 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -18,6 +18,7 @@
 #include <linux/stat.h>
 #include <linux/clk.h>
 #include <linux/cpu.h>
+#include <linux/cpu_pm.h>
 #include <linux/coresight.h>
 #include <linux/coresight-pmu.h>
 #include <linux/pm_wakeup.h>
@@ -26,6 +27,7 @@
 #include <linux/uaccess.h>
 #include <linux/perf_event.h>
 #include <linux/pm_runtime.h>
+#include <linux/property.h>
 #include <asm/sections.h>
 #include <asm/local.h>
 #include <asm/virt.h>
@@ -37,6 +39,15 @@ static int boot_enable;
 module_param(boot_enable, int, 0444);
 MODULE_PARM_DESC(boot_enable, "Enable tracing on boot");
 
+#define PARAM_PM_SAVE_NEVER	0 /* never save/restore state */
+#define PARAM_PM_SAVE_ALWAYS	1 /* always save/restore state */
+#define PARAM_PM_SAVE_FIRMWARE	2 /* only save/restore if firmware flag set */
+
+static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
+module_param(pm_save_enable, int, 0444);
+MODULE_PARM_DESC(pm_save_enable,
+	"Save/restore state on power down: 0 = never, 1 = always, 2 = firmware");
+
 /* The number of ETMv4 currently registered */
 static int etm4_count;
 static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
@@ -54,6 +65,14 @@ static void etm4_os_unlock(struct etmv4_drvdata *drvdata)
 	isb();
 }
 
+static void etm4_os_lock(struct etmv4_drvdata *drvdata)
+{
+	/* Writing 0x1 to TRCOSLAR locks the trace registers */
+	writel_relaxed(0x1, drvdata->base + TRCOSLAR);
+	drvdata->os_unlock = false;
+	isb();
+}
+
 static bool etm4_arch_supported(u8 arch)
 {
 	/* Mask out the minor version number */
@@ -1085,6 +1104,294 @@ static void etm4_init_trace_id(struct etmv4_drvdata *drvdata)
 	drvdata->trcid = coresight_get_trace_id(drvdata->cpu);
 }
 
+#ifdef CONFIG_CPU_PM
+static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
+{
+	int i, ret = 0;
+	struct etmv4_save_state *state;
+	struct device *etm_dev = &drvdata->csdev->dev;
+
+	/*
+	 * As recommended by 3.4.1 ("The procedure when powering down the PE")
+	 * of ARM IHI 0064D
+	 */
+	dsb(sy);
+	isb();
+
+	CS_UNLOCK(drvdata->base);
+
+	/* Lock the OS lock to disable trace and external debugger access */
+	etm4_os_lock(drvdata);
+
+	/* wait for TRCSTATR.PMSTABLE to go up */
+	if (coresight_timeout(drvdata->base, TRCSTATR,
+					TRCSTATR_PMSTABLE_BIT, 1)) {
+		dev_err(etm_dev,
+			"timeout while waiting for PM Stable Status\n");
+		etm4_os_unlock(drvdata);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	state = drvdata->save_state;
+
+	state->trcprgctlr = readl(drvdata->base + TRCPRGCTLR);
+	state->trcprocselr = readl(drvdata->base + TRCPROCSELR);
+	state->trcconfigr = readl(drvdata->base + TRCCONFIGR);
+	state->trcauxctlr = readl(drvdata->base + TRCAUXCTLR);
+	state->trceventctl0r = readl(drvdata->base + TRCEVENTCTL0R);
+	state->trceventctl1r = readl(drvdata->base + TRCEVENTCTL1R);
+	state->trcstallctlr = readl(drvdata->base + TRCSTALLCTLR);
+	state->trctsctlr = readl(drvdata->base + TRCTSCTLR);
+	state->trcsyncpr = readl(drvdata->base + TRCSYNCPR);
+	state->trcccctlr = readl(drvdata->base + TRCCCCTLR);
+	state->trcbbctlr = readl(drvdata->base + TRCBBCTLR);
+	state->trctraceidr = readl(drvdata->base + TRCTRACEIDR);
+	state->trcqctlr = readl(drvdata->base + TRCQCTLR);
+
+	state->trcvictlr = readl(drvdata->base + TRCVICTLR);
+	state->trcviiectlr = readl(drvdata->base + TRCVIIECTLR);
+	state->trcvissctlr = readl(drvdata->base + TRCVISSCTLR);
+	state->trcvipcssctlr = readl(drvdata->base + TRCVIPCSSCTLR);
+	state->trcvdctlr = readl(drvdata->base + TRCVDCTLR);
+	state->trcvdsacctlr = readl(drvdata->base + TRCVDSACCTLR);
+	state->trcvdarcctlr = readl(drvdata->base + TRCVDARCCTLR);
+
+	for (i = 0; i < drvdata->nrseqstate; i++)
+		state->trcseqevr[i] = readl(drvdata->base + TRCSEQEVRn(i));
+
+	state->trcseqrstevr = readl(drvdata->base + TRCSEQRSTEVR);
+	state->trcseqstr = readl(drvdata->base + TRCSEQSTR);
+	state->trcextinselr = readl(drvdata->base + TRCEXTINSELR);
+
+	for (i = 0; i < drvdata->nr_cntr; i++) {
+		state->trccntrldvr[i] = readl(drvdata->base + TRCCNTRLDVRn(i));
+		state->trccntctlr[i] = readl(drvdata->base + TRCCNTCTLRn(i));
+		state->trccntvr[i] = readl(drvdata->base + TRCCNTVRn(i));
+	}
+
+	for (i = 0; i < drvdata->nr_resource * 2; i++)
+		state->trcrsctlr[i] = readl(drvdata->base + TRCRSCTLRn(i));
+
+	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+		state->trcssccr[i] = readl(drvdata->base + TRCSSCCRn(i));
+		state->trcsscsr[i] = readl(drvdata->base + TRCSSCSRn(i));
+		state->trcsspcicr[i] = readl(drvdata->base + TRCSSPCICRn(i));
+	}
+
+	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
+		state->trcacvr[i] = readl(drvdata->base + TRCACVRn(i));
+		state->trcacatr[i] = readl(drvdata->base + TRCACATRn(i));
+	}
+
+	/*
+	 * Data trace stream is architecturally prohibited for A profile cores
+	 * so we don't save (or later restore) trcdvcvr and trcdvcmr - As per
+	 * section 1.3.4 ("Possible functional configurations of an ETMv4 trace
+	 * unit") of ARM IHI 0064D.
+	 */
+
+	for (i = 0; i < drvdata->numcidc; i++)
+		state->trccidcvr[i] = readl(drvdata->base + TRCCIDCVRn(i));
+
+	for (i = 0; i < drvdata->numvmidc; i++)
+		state->trcvmidcvr[i] = readl(drvdata->base + TRCVMIDCVRn(i));
+
+	state->trccidcctlr0 = readl(drvdata->base + TRCCIDCCTLR0);
+	state->trccidcctlr1 = readl(drvdata->base + TRCCIDCCTLR1);
+
+	state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR0);
+	state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR1);
+
+	state->trcclaimset = readl(drvdata->base + TRCCLAIMCLR);
+
+	state->trcpdcr = readl(drvdata->base + TRCPDCR);
+
+	/* wait for TRCSTATR.IDLE to go up */
+	if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT, 1)) {
+		dev_err(etm_dev,
+			"timeout while waiting for Idle Trace Status\n");
+		etm4_os_unlock(drvdata);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	drvdata->state_needs_restore = true;
+
+	/*
+	 * Power can be removed from the trace unit now. We do this to
+	 * potentially save power on systems that respect the TRCPDCR_PU
+	 * despite requesting software to save/restore state.
+	 */
+	writel_relaxed((state->trcpdcr & ~TRCPDCR_PU),
+			drvdata->base + TRCPDCR);
+
+out:
+	CS_LOCK(drvdata->base);
+	return ret;
+}
+
+static void etm4_cpu_restore(struct etmv4_drvdata *drvdata)
+{
+	int i;
+	struct etmv4_save_state *state = drvdata->save_state;
+
+	CS_UNLOCK(drvdata->base);
+
+	writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
+
+	writel_relaxed(state->trcprgctlr, drvdata->base + TRCPRGCTLR);
+	writel_relaxed(state->trcprocselr, drvdata->base + TRCPROCSELR);
+	writel_relaxed(state->trcconfigr, drvdata->base + TRCCONFIGR);
+	writel_relaxed(state->trcauxctlr, drvdata->base + TRCAUXCTLR);
+	writel_relaxed(state->trceventctl0r, drvdata->base + TRCEVENTCTL0R);
+	writel_relaxed(state->trceventctl1r, drvdata->base + TRCEVENTCTL1R);
+	writel_relaxed(state->trcstallctlr, drvdata->base + TRCSTALLCTLR);
+	writel_relaxed(state->trctsctlr, drvdata->base + TRCTSCTLR);
+	writel_relaxed(state->trcsyncpr, drvdata->base + TRCSYNCPR);
+	writel_relaxed(state->trcccctlr, drvdata->base + TRCCCCTLR);
+	writel_relaxed(state->trcbbctlr, drvdata->base + TRCBBCTLR);
+	writel_relaxed(state->trctraceidr, drvdata->base + TRCTRACEIDR);
+	writel_relaxed(state->trcqctlr, drvdata->base + TRCQCTLR);
+
+	writel_relaxed(state->trcvictlr, drvdata->base + TRCVICTLR);
+	writel_relaxed(state->trcviiectlr, drvdata->base + TRCVIIECTLR);
+	writel_relaxed(state->trcvissctlr, drvdata->base + TRCVISSCTLR);
+	writel_relaxed(state->trcvipcssctlr, drvdata->base + TRCVIPCSSCTLR);
+	writel_relaxed(state->trcvdctlr, drvdata->base + TRCVDCTLR);
+	writel_relaxed(state->trcvdsacctlr, drvdata->base + TRCVDSACCTLR);
+	writel_relaxed(state->trcvdarcctlr, drvdata->base + TRCVDARCCTLR);
+
+	for (i = 0; i < drvdata->nrseqstate; i++)
+		writel_relaxed(state->trcseqevr[i],
+					drvdata->base + TRCSEQEVRn(i));
+
+	writel_relaxed(state->trcseqrstevr, drvdata->base + TRCSEQRSTEVR);
+	writel_relaxed(state->trcseqstr, drvdata->base + TRCSEQSTR);
+	writel_relaxed(state->trcextinselr, drvdata->base + TRCEXTINSELR);
+
+	for (i = 0; i < drvdata->nr_cntr; i++) {
+		writel_relaxed(state->trccntrldvr[i],
+					drvdata->base + TRCCNTRLDVRn(i));
+		writel_relaxed(state->trccntctlr[i],
+					drvdata->base + TRCCNTCTLRn(i));
+		writel_relaxed(state->trccntvr[i],
+					drvdata->base + TRCCNTVRn(i));
+	}
+
+	for (i = 0; i < drvdata->nr_resource * 2; i++)
+		writel_relaxed(state->trcrsctlr[i],
+					drvdata->base + TRCRSCTLRn(i));
+
+	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+		writel_relaxed(state->trcssccr[i],
+					drvdata->base + TRCSSCCRn(i));
+		writel_relaxed(state->trcsscsr[i],
+					drvdata->base + TRCSSCSRn(i));
+		writel_relaxed(state->trcsspcicr[i],
+					drvdata->base + TRCSSPCICRn(i));
+	}
+
+	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
+		writel_relaxed(state->trcacvr[i],
+					drvdata->base + TRCACVRn(i));
+		writel_relaxed(state->trcacatr[i],
+					drvdata->base + TRCACATRn(i));
+	}
+
+	for (i = 0; i < drvdata->numcidc; i++)
+		writel_relaxed(state->trccidcvr[i],
+					drvdata->base + TRCCIDCVRn(i));
+
+	for (i = 0; i < drvdata->numvmidc; i++)
+		writel_relaxed(state->trcvmidcvr[i],
+					drvdata->base + TRCVMIDCVRn(i));
+
+	writel_relaxed(state->trccidcctlr0, drvdata->base + TRCCIDCCTLR0);
+	writel_relaxed(state->trccidcctlr1, drvdata->base + TRCCIDCCTLR1);
+
+	writel_relaxed(state->trcvmidcctlr0, drvdata->base + TRCVMIDCCTLR0);
+	writel_relaxed(state->trcvmidcctlr0, drvdata->base + TRCVMIDCCTLR1);
+
+	writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
+
+	writel_relaxed(state->trcpdcr, drvdata->base + TRCPDCR);
+
+	drvdata->state_needs_restore = false;
+
+	/*
+	 * As recommended by section 4.3.7 ("Synchronization when using the
+	 * memory-mapped interface") of ARM IHI 0064D
+	 */
+	dsb(sy);
+	isb();
+
+	/* Unlock the OS lock to re-enable trace and external debug access */
+	etm4_os_unlock(drvdata);
+	CS_LOCK(drvdata->base);
+}
+
+static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
+			      void *v)
+{
+	struct etmv4_drvdata *drvdata;
+	unsigned int cpu = smp_processor_id();
+
+	if (!etmdrvdata[cpu])
+		return 0;
+
+	drvdata = etmdrvdata[cpu];
+
+	if (!drvdata->save_state)
+		return NOTIFY_OK;
+
+	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
+		return NOTIFY_BAD;
+
+	switch (cmd) {
+	case CPU_PM_ENTER:
+		/* save the state if self-hosted coresight is in use */
+		if (local_read(&drvdata->mode))
+			if (etm4_cpu_save(drvdata))
+				return NOTIFY_BAD;
+		break;
+	case CPU_PM_EXIT:
+	case CPU_PM_ENTER_FAILED:
+		/* trcclaimset is set when there is state to restore */
+		if (drvdata->state_needs_restore)
+			etm4_cpu_restore(drvdata);
+		break;
+	default:
+		return NOTIFY_DONE;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block etm4_cpu_pm_nb = {
+	.notifier_call = etm4_cpu_pm_notify,
+};
+
+static int etm4_cpu_pm_register(void)
+{
+	return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
+}
+
+static void etm4_cpu_pm_unregister(void)
+{
+	cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
+}
+#else
+static int etm4_cpu_pm_register(void) { return 0; }
+static void etm4_cpu_pm_unregister(void) { }
+#endif
+
+static inline bool etm4_needs_save_restore(struct device *dev)
+{
+	return fwnode_property_present(dev->fwnode,
+				       "arm,coresight-needs-save-restore");
+}
+
 static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret;
@@ -1101,6 +1408,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 
 	dev_set_drvdata(dev, drvdata);
 
+	if (pm_save_enable == PARAM_PM_SAVE_ALWAYS ||
+	    (pm_save_enable == PARAM_PM_SAVE_FIRMWARE &&
+	     etm4_needs_save_restore(dev))) {
+		drvdata->save_state = devm_kmalloc(dev,
+				sizeof(struct etmv4_save_state), GFP_KERNEL);
+		if (!drvdata->save_state)
+			return -ENOMEM;
+	}
+
 	/* Validity for the resource is already checked by the AMBA core */
 	base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(base))
@@ -1135,6 +1451,10 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 		if (ret < 0)
 			goto err_arch_supported;
 		hp_online = ret;
+
+		ret = etm4_cpu_pm_register();
+		if (ret)
+			goto err_arch_supported;
 	}
 
 	cpus_read_unlock();
@@ -1185,6 +1505,8 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 
 err_arch_supported:
 	if (--etm4_count == 0) {
+		etm4_cpu_pm_unregister();
+
 		cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
 		if (hp_online)
 			cpuhp_remove_state_nocalls(hp_online);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 4523f10ddd0f..546d790cb01b 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -175,6 +175,7 @@
 					 ETM_MODE_EXCL_USER)
 
 #define TRCSTATR_IDLE_BIT		0
+#define TRCSTATR_PMSTABLE_BIT		1
 #define ETM_DEFAULT_ADDR_COMP		0
 
 /* PowerDown Control Register bits */
@@ -281,6 +282,65 @@ struct etmv4_config {
 	u32				ext_inp;
 };
 
+/**
+ * struct etm4_save_state - state to be preserved when ETM is without power
+ */
+struct etmv4_save_state {
+	u32	trcprgctlr;
+	u32	trcprocselr;
+	u32	trcconfigr;
+	u32	trcauxctlr;
+	u32	trceventctl0r;
+	u32	trceventctl1r;
+	u32	trcstallctlr;
+	u32	trctsctlr;
+	u32	trcsyncpr;
+	u32	trcccctlr;
+	u32	trcbbctlr;
+	u32	trctraceidr;
+	u32	trcqctlr;
+
+	u32	trcvictlr;
+	u32	trcviiectlr;
+	u32	trcvissctlr;
+	u32	trcvipcssctlr;
+	u32	trcvdctlr;
+	u32	trcvdsacctlr;
+	u32	trcvdarcctlr;
+
+	u32	trcseqevr[ETM_MAX_SEQ_STATES];
+	u32	trcseqrstevr;
+	u32	trcseqstr;
+	u32	trcextinselr;
+	u32	trccntrldvr[ETMv4_MAX_CNTR];
+	u32	trccntctlr[ETMv4_MAX_CNTR];
+	u32	trccntvr[ETMv4_MAX_CNTR];
+
+	u32	trcrsctlr[ETM_MAX_RES_SEL * 2];
+
+	u32	trcssccr[ETM_MAX_SS_CMP];
+	u32	trcsscsr[ETM_MAX_SS_CMP];
+	u32	trcsspcicr[ETM_MAX_SS_CMP];
+
+	u64	trcacvr[ETM_MAX_SINGLE_ADDR_CMP];
+	u64	trcacatr[ETM_MAX_SINGLE_ADDR_CMP];
+	u64	trccidcvr[ETMv4_MAX_CTXID_CMP];
+	u32	trcvmidcvr[ETM_MAX_VMID_CMP];
+	u32	trccidcctlr0;
+	u32	trccidcctlr1;
+	u32	trcvmidcctlr0;
+	u32	trcvmidcctlr1;
+
+	u32	trcclaimset;
+
+	u32	cntr_val[ETMv4_MAX_CNTR];
+	u32	seq_state;
+	u32	vinst_ctrl;
+	u32	ss_status[ETM_MAX_SS_CMP];
+
+	u32	trcpdcr;
+};
+
 /**
  * struct etm4_drvdata - specifics associated to an ETM component
  * @base:       Memory mapped base address for this component.
@@ -336,6 +396,8 @@ struct etmv4_config {
  * @atbtrig:	If the implementation can support ATB triggers
  * @lpoverride:	If the implementation can support low-power state over.
  * @config:	structure holding configuration parameters.
+ * @save_state:	State to be preserved across power loss
+ * @state_needs_restore: True when there is context to restore after PM exit
  */
 struct etmv4_drvdata {
 	void __iomem			*base;
@@ -381,6 +443,8 @@ struct etmv4_drvdata {
 	bool				atbtrig;
 	bool				lpoverride;
 	struct etmv4_config		config;
+	struct etmv4_save_state		*save_state;
+	bool				state_needs_restore;
 };
 
 /* Address comparator access types */
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-07-30 12:51 [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Andrew Murray
                   ` (4 preceding siblings ...)
  2019-07-30 12:51 ` [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states Andrew Murray
@ 2019-07-30 12:51 ` Andrew Murray
  2019-08-02 10:40   ` Suzuki K Poulose
  2019-07-30 20:12 ` [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Mathieu Poirier
  6 siblings, 1 reply; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 12:51 UTC (permalink / raw)
  To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
  Cc: Al.Grant, coresight, Leo Yan, Sudeep Holla, linux-arm-kernel, Mike Leach

Some coresight components, because of choices made during hardware
integration, require their state to be saved and restored across CPU low
power states.

The software has no reliable method of detecting when save/restore is
required thus let's add a binding to inform the kernel.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 Documentation/devicetree/bindings/arm/coresight.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
index fcc3bacfd8bc..7cbdb7893af8 100644
--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -92,6 +92,9 @@ its hardware characteristcs.
 	* arm,cp14: must be present if the system accesses ETM/PTM management
 	  registers via co-processor 14.
 
+	* arm,coresight-needs-save-restore: boolean. Indicates that software
+	  should save/restore state across power down.
+
 * Optional property for TMC:
 
 	* arm,buffer-size: size of contiguous buffer space for TMC ETR
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states
  2019-07-30 12:51 [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Andrew Murray
                   ` (5 preceding siblings ...)
  2019-07-30 12:51 ` [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore Andrew Murray
@ 2019-07-30 20:12 ` Mathieu Poirier
  2019-07-30 21:46   ` Andrew Murray
  6 siblings, 1 reply; 27+ messages in thread
From: Mathieu Poirier @ 2019-07-30 20:12 UTC (permalink / raw)
  To: Andrew Murray
  Cc: Al.Grant, Suzuki K Poulose, Alexander Shishkin, coresight,
	Sudeep Holla, Leo Yan, linux-arm-kernel, Mike Leach

Hi Andrew,

On Tue, Jul 30, 2019 at 01:51:51PM +0100, Andrew Murray wrote:
> Some hardware will ignore bit TRCPDCR.PU which is used to signal
> to hardware that power should not be removed from the trace unit.
> Let's mitigate against this by conditionally saving and restoring
> the trace unit state when the CPU enters low power states.
> 
> This patchset introduces a firmware property named
> 'arm,coresight-needs-save-restore' - when this is present the
> hardware state will be conditionally saved and restored.
> 
> A module parameter 'pm_save_enable' is also introduced which can
> be configured to override the firmware property.
> 
> The hardware state is only ever saved and restored when a self-hosted
> coresight is in use.
> 
> Changes since v3:
> 
>  - Only save/restore when self-hosted is being used and detect this
>    without relying on the coresight registers (which may not be
>    available)
> 
>  - Only allocate memory for etmv4_save_state at probe time when
>    configuration indicates it may be used
> 
>  - Set pm_save_enable param to 0444 such that it is static after
>    boot
> 
>  - Save/restore TRCPDCR
> 
>  - Add missing comments to struct etm4_drvdata documentation
> 
>  - Rebased onto coresight/next (8f1f9857)
> 
> Changes since v2:
> 
>  - Move the PM notifier block from drvdata to file static
> 
>  - Add section names to document references
> 
>  - Add additional information to commit messages
> 
>  - Remove trcdvcvr and trcdvcmr from saved state and add a comment to
>    describe why
> 
>  - Ensure TRCPDCR_PU is set after restore and add a comment to explain
>    why we bother toggling TRCPDCR_PU on save/restore
> 
>  - Reword the pm_save_enable options and add comments
> 
>  - Miscellaneous style changes
> 
>  - Move device tree binding documentation to its own patch
> 
> Changes since v1:
> 
>  - Rebased onto coresight/next
> 
>  - Correcly pass bit number rather than BIT macro to coresight_timeout
> 
>  - Abort saving state if a timeout occurs
> 
>  - Fix completely broken pm_notify handling and unregister handler on error
> 
>  - Use state_needs_restore to ensure state is restored only once
> 
>  - Add module parameter description to existing boot_enable parameter
>    and use module_param instead of module_param_named
> 
>  - Add firmware bindings for coresight-needs-save-restore
> 
>  - Rename 'disable_pm_save' to 'pm_save_enable' which allows for
>    disabled, enabled or firmware
> 
>  - Update comment on etm4_os_lock, it incorrectly indicated that
>    the code unlocks the trace registers
> 
>  - Add comments to explain use of OS lock during save/restore
> 
>  - Fix incorrect error description whilst waiting for PM stable
> 
>  - Add WARN_ON_ONCE when cpu isn't as expected during save/restore
> 
>  - Various updates to commit messages
> 
> 
> Andrew Murray (6):
>   coresight: etm4x: remove superfluous setting of os_unlock
>   coresight: etm4x: use explicit barriers on enable/disable
>   coresight: etm4x: use module_param instead of module_param_named
>   coresight: etm4x: improve clarity of etm4_os_unlock comment

I have picked up the first 4 patches, so no need to send them with your next
revision.  Note that for patch 2/6 I have removed the "stable" tag as the patch
doesn't apply to any of the stable tree.  Since I have another one like that in
my tree I will rework both patches and send them directly to Greg for stable
consideration.

Thanks,
Mathieu


>   coresight: etm4x: save/restore state across CPU low power states
>   dt-bindings: arm: coresight: Add support for
>     coresight-needs-save-restore
> 
>  .../devicetree/bindings/arm/coresight.txt     |   3 +
>  drivers/hwtracing/coresight/coresight-etm4x.c | 346 +++++++++++++++++-
>  drivers/hwtracing/coresight/coresight-etm4x.h |  64 ++++
>  3 files changed, 406 insertions(+), 7 deletions(-)
> 
> -- 
> 2.21.0
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states
  2019-07-30 12:51 ` [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states Andrew Murray
@ 2019-07-30 21:16   ` Mathieu Poirier
  2019-07-30 21:45     ` Andrew Murray
  2019-08-02 10:54   ` Suzuki K Poulose
  1 sibling, 1 reply; 27+ messages in thread
From: Mathieu Poirier @ 2019-07-30 21:16 UTC (permalink / raw)
  To: Andrew Murray
  Cc: Al.Grant, Suzuki K Poulose, Alexander Shishkin, coresight,
	Sudeep Holla, Leo Yan, linux-arm-kernel, Mike Leach

On Tue, Jul 30, 2019 at 01:51:56PM +0100, Andrew Murray wrote:
> Some hardware will ignore bit TRCPDCR.PU which is used to signal
> to hardware that power should not be removed from the trace unit.
> Let's mitigate against this by conditionally saving and restoring
> the trace unit state when the CPU enters low power states.
> 
> This patchset introduces a firmware property named
> 'arm,coresight-needs-save-restore' - when this is present the
> hardware state will be conditionally saved and restored.
> 
> A module parameter 'pm_save_enable' is also introduced which can
> be configured to override the firmware property. This can be set
> to never allow save/restore, to conditionally allow it, or to
> do as the firmware indicates (default).
> 
> We avoid saving the hardware state when coresight isn't in use
> to reduce PM latency - we can't determine this by reading the
> claim tags (TRCCLAIMCLR) as these are 'trace' registers which need
> power and clocking, something we can't easily provide in the PM
> context. Therefore we rely on the existing drvdata->mode internal
> state that is set when self-hosted coresight is used (and powered).
> 
> As we do not have a simple way of determining if an external agent
> is using coresight, we don't save/restore for this use case.
> 
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-etm4x.c | 322 ++++++++++++++++++
>  drivers/hwtracing/coresight/coresight-etm4x.h |  64 ++++
>  2 files changed, 386 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> index a128b5063f46..30f118792289 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> @@ -18,6 +18,7 @@
>  #include <linux/stat.h>
>  #include <linux/clk.h>
>  #include <linux/cpu.h>
> +#include <linux/cpu_pm.h>
>  #include <linux/coresight.h>
>  #include <linux/coresight-pmu.h>
>  #include <linux/pm_wakeup.h>
> @@ -26,6 +27,7 @@
>  #include <linux/uaccess.h>
>  #include <linux/perf_event.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/property.h>
>  #include <asm/sections.h>
>  #include <asm/local.h>
>  #include <asm/virt.h>
> @@ -37,6 +39,15 @@ static int boot_enable;
>  module_param(boot_enable, int, 0444);
>  MODULE_PARM_DESC(boot_enable, "Enable tracing on boot");
>  
> +#define PARAM_PM_SAVE_NEVER	0 /* never save/restore state */
> +#define PARAM_PM_SAVE_ALWAYS	1 /* always save/restore state */
> +#define PARAM_PM_SAVE_FIRMWARE	2 /* only save/restore if firmware flag set */
> +
> +static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
> +module_param(pm_save_enable, int, 0444);
> +MODULE_PARM_DESC(pm_save_enable,
> +	"Save/restore state on power down: 0 = never, 1 = always, 2 = firmware");
> +
>  /* The number of ETMv4 currently registered */
>  static int etm4_count;
>  static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
> @@ -54,6 +65,14 @@ static void etm4_os_unlock(struct etmv4_drvdata *drvdata)
>  	isb();
>  }
>  
> +static void etm4_os_lock(struct etmv4_drvdata *drvdata)
> +{
> +	/* Writing 0x1 to TRCOSLAR locks the trace registers */
> +	writel_relaxed(0x1, drvdata->base + TRCOSLAR);
> +	drvdata->os_unlock = false;
> +	isb();
> +}
> +
>  static bool etm4_arch_supported(u8 arch)
>  {
>  	/* Mask out the minor version number */
> @@ -1085,6 +1104,294 @@ static void etm4_init_trace_id(struct etmv4_drvdata *drvdata)
>  	drvdata->trcid = coresight_get_trace_id(drvdata->cpu);
>  }
>  
> +#ifdef CONFIG_CPU_PM
> +static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
> +{
> +	int i, ret = 0;
> +	struct etmv4_save_state *state;
> +	struct device *etm_dev = &drvdata->csdev->dev;
> +
> +	/*
> +	 * As recommended by 3.4.1 ("The procedure when powering down the PE")
> +	 * of ARM IHI 0064D
> +	 */
> +	dsb(sy);
> +	isb();
> +
> +	CS_UNLOCK(drvdata->base);
> +
> +	/* Lock the OS lock to disable trace and external debugger access */
> +	etm4_os_lock(drvdata);
> +
> +	/* wait for TRCSTATR.PMSTABLE to go up */
> +	if (coresight_timeout(drvdata->base, TRCSTATR,
> +					TRCSTATR_PMSTABLE_BIT, 1)) {
> +		dev_err(etm_dev,
> +			"timeout while waiting for PM Stable Status\n");
> +		etm4_os_unlock(drvdata);
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +
> +	state = drvdata->save_state;
> +
> +	state->trcprgctlr = readl(drvdata->base + TRCPRGCTLR);
> +	state->trcprocselr = readl(drvdata->base + TRCPROCSELR);
> +	state->trcconfigr = readl(drvdata->base + TRCCONFIGR);
> +	state->trcauxctlr = readl(drvdata->base + TRCAUXCTLR);
> +	state->trceventctl0r = readl(drvdata->base + TRCEVENTCTL0R);
> +	state->trceventctl1r = readl(drvdata->base + TRCEVENTCTL1R);
> +	state->trcstallctlr = readl(drvdata->base + TRCSTALLCTLR);
> +	state->trctsctlr = readl(drvdata->base + TRCTSCTLR);
> +	state->trcsyncpr = readl(drvdata->base + TRCSYNCPR);
> +	state->trcccctlr = readl(drvdata->base + TRCCCCTLR);
> +	state->trcbbctlr = readl(drvdata->base + TRCBBCTLR);
> +	state->trctraceidr = readl(drvdata->base + TRCTRACEIDR);
> +	state->trcqctlr = readl(drvdata->base + TRCQCTLR);
> +
> +	state->trcvictlr = readl(drvdata->base + TRCVICTLR);
> +	state->trcviiectlr = readl(drvdata->base + TRCVIIECTLR);
> +	state->trcvissctlr = readl(drvdata->base + TRCVISSCTLR);
> +	state->trcvipcssctlr = readl(drvdata->base + TRCVIPCSSCTLR);
> +	state->trcvdctlr = readl(drvdata->base + TRCVDCTLR);
> +	state->trcvdsacctlr = readl(drvdata->base + TRCVDSACCTLR);
> +	state->trcvdarcctlr = readl(drvdata->base + TRCVDARCCTLR);
> +
> +	for (i = 0; i < drvdata->nrseqstate; i++)
> +		state->trcseqevr[i] = readl(drvdata->base + TRCSEQEVRn(i));
> +
> +	state->trcseqrstevr = readl(drvdata->base + TRCSEQRSTEVR);
> +	state->trcseqstr = readl(drvdata->base + TRCSEQSTR);
> +	state->trcextinselr = readl(drvdata->base + TRCEXTINSELR);
> +
> +	for (i = 0; i < drvdata->nr_cntr; i++) {
> +		state->trccntrldvr[i] = readl(drvdata->base + TRCCNTRLDVRn(i));
> +		state->trccntctlr[i] = readl(drvdata->base + TRCCNTCTLRn(i));
> +		state->trccntvr[i] = readl(drvdata->base + TRCCNTVRn(i));
> +	}
> +
> +	for (i = 0; i < drvdata->nr_resource * 2; i++)
> +		state->trcrsctlr[i] = readl(drvdata->base + TRCRSCTLRn(i));
> +
> +	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> +		state->trcssccr[i] = readl(drvdata->base + TRCSSCCRn(i));
> +		state->trcsscsr[i] = readl(drvdata->base + TRCSSCSRn(i));
> +		state->trcsspcicr[i] = readl(drvdata->base + TRCSSPCICRn(i));
> +	}
> +
> +	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
> +		state->trcacvr[i] = readl(drvdata->base + TRCACVRn(i));
> +		state->trcacatr[i] = readl(drvdata->base + TRCACATRn(i));
> +	}
> +
> +	/*
> +	 * Data trace stream is architecturally prohibited for A profile cores
> +	 * so we don't save (or later restore) trcdvcvr and trcdvcmr - As per
> +	 * section 1.3.4 ("Possible functional configurations of an ETMv4 trace
> +	 * unit") of ARM IHI 0064D.
> +	 */
> +
> +	for (i = 0; i < drvdata->numcidc; i++)
> +		state->trccidcvr[i] = readl(drvdata->base + TRCCIDCVRn(i));
> +
> +	for (i = 0; i < drvdata->numvmidc; i++)
> +		state->trcvmidcvr[i] = readl(drvdata->base + TRCVMIDCVRn(i));
> +
> +	state->trccidcctlr0 = readl(drvdata->base + TRCCIDCCTLR0);
> +	state->trccidcctlr1 = readl(drvdata->base + TRCCIDCCTLR1);
> +
> +	state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR0);
> +	state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR1);
> +
> +	state->trcclaimset = readl(drvdata->base + TRCCLAIMCLR);
> +
> +	state->trcpdcr = readl(drvdata->base + TRCPDCR);
> +
> +	/* wait for TRCSTATR.IDLE to go up */
> +	if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT, 1)) {
> +		dev_err(etm_dev,
> +			"timeout while waiting for Idle Trace Status\n");
> +		etm4_os_unlock(drvdata);
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +
> +	drvdata->state_needs_restore = true;
> +
> +	/*
> +	 * Power can be removed from the trace unit now. We do this to
> +	 * potentially save power on systems that respect the TRCPDCR_PU
> +	 * despite requesting software to save/restore state.
> +	 */
> +	writel_relaxed((state->trcpdcr & ~TRCPDCR_PU),
> +			drvdata->base + TRCPDCR);
> +
> +out:
> +	CS_LOCK(drvdata->base);
> +	return ret;
> +}
> +
> +static void etm4_cpu_restore(struct etmv4_drvdata *drvdata)
> +{
> +	int i;
> +	struct etmv4_save_state *state = drvdata->save_state;
> +
> +	CS_UNLOCK(drvdata->base);
> +
> +	writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
> +
> +	writel_relaxed(state->trcprgctlr, drvdata->base + TRCPRGCTLR);
> +	writel_relaxed(state->trcprocselr, drvdata->base + TRCPROCSELR);
> +	writel_relaxed(state->trcconfigr, drvdata->base + TRCCONFIGR);
> +	writel_relaxed(state->trcauxctlr, drvdata->base + TRCAUXCTLR);
> +	writel_relaxed(state->trceventctl0r, drvdata->base + TRCEVENTCTL0R);
> +	writel_relaxed(state->trceventctl1r, drvdata->base + TRCEVENTCTL1R);
> +	writel_relaxed(state->trcstallctlr, drvdata->base + TRCSTALLCTLR);
> +	writel_relaxed(state->trctsctlr, drvdata->base + TRCTSCTLR);
> +	writel_relaxed(state->trcsyncpr, drvdata->base + TRCSYNCPR);
> +	writel_relaxed(state->trcccctlr, drvdata->base + TRCCCCTLR);
> +	writel_relaxed(state->trcbbctlr, drvdata->base + TRCBBCTLR);
> +	writel_relaxed(state->trctraceidr, drvdata->base + TRCTRACEIDR);
> +	writel_relaxed(state->trcqctlr, drvdata->base + TRCQCTLR);
> +
> +	writel_relaxed(state->trcvictlr, drvdata->base + TRCVICTLR);
> +	writel_relaxed(state->trcviiectlr, drvdata->base + TRCVIIECTLR);
> +	writel_relaxed(state->trcvissctlr, drvdata->base + TRCVISSCTLR);
> +	writel_relaxed(state->trcvipcssctlr, drvdata->base + TRCVIPCSSCTLR);
> +	writel_relaxed(state->trcvdctlr, drvdata->base + TRCVDCTLR);
> +	writel_relaxed(state->trcvdsacctlr, drvdata->base + TRCVDSACCTLR);
> +	writel_relaxed(state->trcvdarcctlr, drvdata->base + TRCVDARCCTLR);
> +
> +	for (i = 0; i < drvdata->nrseqstate; i++)
> +		writel_relaxed(state->trcseqevr[i],
> +					drvdata->base + TRCSEQEVRn(i));
> +
> +	writel_relaxed(state->trcseqrstevr, drvdata->base + TRCSEQRSTEVR);
> +	writel_relaxed(state->trcseqstr, drvdata->base + TRCSEQSTR);
> +	writel_relaxed(state->trcextinselr, drvdata->base + TRCEXTINSELR);
> +
> +	for (i = 0; i < drvdata->nr_cntr; i++) {
> +		writel_relaxed(state->trccntrldvr[i],
> +					drvdata->base + TRCCNTRLDVRn(i));
> +		writel_relaxed(state->trccntctlr[i],
> +					drvdata->base + TRCCNTCTLRn(i));
> +		writel_relaxed(state->trccntvr[i],
> +					drvdata->base + TRCCNTVRn(i));
> +	}
> +
> +	for (i = 0; i < drvdata->nr_resource * 2; i++)
> +		writel_relaxed(state->trcrsctlr[i],
> +					drvdata->base + TRCRSCTLRn(i));
> +
> +	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> +		writel_relaxed(state->trcssccr[i],
> +					drvdata->base + TRCSSCCRn(i));
> +		writel_relaxed(state->trcsscsr[i],
> +					drvdata->base + TRCSSCSRn(i));
> +		writel_relaxed(state->trcsspcicr[i],
> +					drvdata->base + TRCSSPCICRn(i));
> +	}
> +
> +	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
> +		writel_relaxed(state->trcacvr[i],
> +					drvdata->base + TRCACVRn(i));
> +		writel_relaxed(state->trcacatr[i],
> +					drvdata->base + TRCACATRn(i));
> +	}
> +
> +	for (i = 0; i < drvdata->numcidc; i++)
> +		writel_relaxed(state->trccidcvr[i],
> +					drvdata->base + TRCCIDCVRn(i));
> +
> +	for (i = 0; i < drvdata->numvmidc; i++)
> +		writel_relaxed(state->trcvmidcvr[i],
> +					drvdata->base + TRCVMIDCVRn(i));
> +
> +	writel_relaxed(state->trccidcctlr0, drvdata->base + TRCCIDCCTLR0);
> +	writel_relaxed(state->trccidcctlr1, drvdata->base + TRCCIDCCTLR1);
> +
> +	writel_relaxed(state->trcvmidcctlr0, drvdata->base + TRCVMIDCCTLR0);
> +	writel_relaxed(state->trcvmidcctlr0, drvdata->base + TRCVMIDCCTLR1);
> +
> +	writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
> +
> +	writel_relaxed(state->trcpdcr, drvdata->base + TRCPDCR);
> +
> +	drvdata->state_needs_restore = false;
> +
> +	/*
> +	 * As recommended by section 4.3.7 ("Synchronization when using the
> +	 * memory-mapped interface") of ARM IHI 0064D
> +	 */
> +	dsb(sy);
> +	isb();
> +
> +	/* Unlock the OS lock to re-enable trace and external debug access */
> +	etm4_os_unlock(drvdata);
> +	CS_LOCK(drvdata->base);
> +}
> +
> +static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
> +			      void *v)
> +{
> +	struct etmv4_drvdata *drvdata;
> +	unsigned int cpu = smp_processor_id();
> +
> +	if (!etmdrvdata[cpu])
> +		return 0;
> +
> +	drvdata = etmdrvdata[cpu];
> +
> +	if (!drvdata->save_state)
> +		return NOTIFY_OK;

The problem here is that if no memory was allocated for ->save_state at boot
time and someone does:
        $ echo 1 > /sys/module/coresight_etm4x/parameters/pm_save_enable

then they will be mislead in thinking that save/restore operations are taking
place.  To avoid the problem I suggest to use module_param_cb() where memory can
be allocated and freed as the functionality is requested by users.

Thanks,
Mathieu

> +
> +	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
> +		return NOTIFY_BAD;
> +
> +	switch (cmd) {
> +	case CPU_PM_ENTER:
> +		/* save the state if self-hosted coresight is in use */
> +		if (local_read(&drvdata->mode))
> +			if (etm4_cpu_save(drvdata))
> +				return NOTIFY_BAD;
> +		break;
> +	case CPU_PM_EXIT:
> +	case CPU_PM_ENTER_FAILED:
> +		/* trcclaimset is set when there is state to restore */
> +		if (drvdata->state_needs_restore)
> +			etm4_cpu_restore(drvdata);
> +		break;
> +	default:
> +		return NOTIFY_DONE;
> +	}
> +
> +	return NOTIFY_OK;
> +}
> +
> +static struct notifier_block etm4_cpu_pm_nb = {
> +	.notifier_call = etm4_cpu_pm_notify,
> +};
> +
> +static int etm4_cpu_pm_register(void)
> +{
> +	return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
> +}
> +
> +static void etm4_cpu_pm_unregister(void)
> +{
> +	cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
> +}
> +#else
> +static int etm4_cpu_pm_register(void) { return 0; }
> +static void etm4_cpu_pm_unregister(void) { }
> +#endif
> +
> +static inline bool etm4_needs_save_restore(struct device *dev)
> +{
> +	return fwnode_property_present(dev->fwnode,
> +				       "arm,coresight-needs-save-restore");
> +}
> +
>  static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
>  {
>  	int ret;
> @@ -1101,6 +1408,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
>  
>  	dev_set_drvdata(dev, drvdata);
>  
> +	if (pm_save_enable == PARAM_PM_SAVE_ALWAYS ||
> +	    (pm_save_enable == PARAM_PM_SAVE_FIRMWARE &&
> +	     etm4_needs_save_restore(dev))) {
> +		drvdata->save_state = devm_kmalloc(dev,
> +				sizeof(struct etmv4_save_state), GFP_KERNEL);
> +		if (!drvdata->save_state)
> +			return -ENOMEM;
> +	}
> +
>  	/* Validity for the resource is already checked by the AMBA core */
>  	base = devm_ioremap_resource(dev, res);
>  	if (IS_ERR(base))
> @@ -1135,6 +1451,10 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
>  		if (ret < 0)
>  			goto err_arch_supported;
>  		hp_online = ret;
> +
> +		ret = etm4_cpu_pm_register();
> +		if (ret)
> +			goto err_arch_supported;
>  	}
>  
>  	cpus_read_unlock();
> @@ -1185,6 +1505,8 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
>  
>  err_arch_supported:
>  	if (--etm4_count == 0) {
> +		etm4_cpu_pm_unregister();
> +
>  		cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
>  		if (hp_online)
>  			cpuhp_remove_state_nocalls(hp_online);
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 4523f10ddd0f..546d790cb01b 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -175,6 +175,7 @@
>  					 ETM_MODE_EXCL_USER)
>  
>  #define TRCSTATR_IDLE_BIT		0
> +#define TRCSTATR_PMSTABLE_BIT		1
>  #define ETM_DEFAULT_ADDR_COMP		0
>  
>  /* PowerDown Control Register bits */
> @@ -281,6 +282,65 @@ struct etmv4_config {
>  	u32				ext_inp;
>  };
>  
> +/**
> + * struct etm4_save_state - state to be preserved when ETM is without power
> + */
> +struct etmv4_save_state {
> +	u32	trcprgctlr;
> +	u32	trcprocselr;
> +	u32	trcconfigr;
> +	u32	trcauxctlr;
> +	u32	trceventctl0r;
> +	u32	trceventctl1r;
> +	u32	trcstallctlr;
> +	u32	trctsctlr;
> +	u32	trcsyncpr;
> +	u32	trcccctlr;
> +	u32	trcbbctlr;
> +	u32	trctraceidr;
> +	u32	trcqctlr;
> +
> +	u32	trcvictlr;
> +	u32	trcviiectlr;
> +	u32	trcvissctlr;
> +	u32	trcvipcssctlr;
> +	u32	trcvdctlr;
> +	u32	trcvdsacctlr;
> +	u32	trcvdarcctlr;
> +
> +	u32	trcseqevr[ETM_MAX_SEQ_STATES];
> +	u32	trcseqrstevr;
> +	u32	trcseqstr;
> +	u32	trcextinselr;
> +	u32	trccntrldvr[ETMv4_MAX_CNTR];
> +	u32	trccntctlr[ETMv4_MAX_CNTR];
> +	u32	trccntvr[ETMv4_MAX_CNTR];
> +
> +	u32	trcrsctlr[ETM_MAX_RES_SEL * 2];
> +
> +	u32	trcssccr[ETM_MAX_SS_CMP];
> +	u32	trcsscsr[ETM_MAX_SS_CMP];
> +	u32	trcsspcicr[ETM_MAX_SS_CMP];
> +
> +	u64	trcacvr[ETM_MAX_SINGLE_ADDR_CMP];
> +	u64	trcacatr[ETM_MAX_SINGLE_ADDR_CMP];
> +	u64	trccidcvr[ETMv4_MAX_CTXID_CMP];
> +	u32	trcvmidcvr[ETM_MAX_VMID_CMP];
> +	u32	trccidcctlr0;
> +	u32	trccidcctlr1;
> +	u32	trcvmidcctlr0;
> +	u32	trcvmidcctlr1;
> +
> +	u32	trcclaimset;
> +
> +	u32	cntr_val[ETMv4_MAX_CNTR];
> +	u32	seq_state;
> +	u32	vinst_ctrl;
> +	u32	ss_status[ETM_MAX_SS_CMP];
> +
> +	u32	trcpdcr;
> +};
> +
>  /**
>   * struct etm4_drvdata - specifics associated to an ETM component
>   * @base:       Memory mapped base address for this component.
> @@ -336,6 +396,8 @@ struct etmv4_config {
>   * @atbtrig:	If the implementation can support ATB triggers
>   * @lpoverride:	If the implementation can support low-power state over.
>   * @config:	structure holding configuration parameters.
> + * @save_state:	State to be preserved across power loss
> + * @state_needs_restore: True when there is context to restore after PM exit
>   */
>  struct etmv4_drvdata {
>  	void __iomem			*base;
> @@ -381,6 +443,8 @@ struct etmv4_drvdata {
>  	bool				atbtrig;
>  	bool				lpoverride;
>  	struct etmv4_config		config;
> +	struct etmv4_save_state		*save_state;
> +	bool				state_needs_restore;
>  };
>  
>  /* Address comparator access types */
> -- 
> 2.21.0
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states
  2019-07-30 21:16   ` Mathieu Poirier
@ 2019-07-30 21:45     ` Andrew Murray
  2019-07-31  8:16       ` Mike Leach
  0 siblings, 1 reply; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 21:45 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Al.Grant, Suzuki K Poulose, Alexander Shishkin, coresight,
	Sudeep Holla, Leo Yan, linux-arm-kernel, Mike Leach

On Tue, Jul 30, 2019 at 03:16:33PM -0600, Mathieu Poirier wrote:
> On Tue, Jul 30, 2019 at 01:51:56PM +0100, Andrew Murray wrote:
> > Some hardware will ignore bit TRCPDCR.PU which is used to signal
> > to hardware that power should not be removed from the trace unit.
> > Let's mitigate against this by conditionally saving and restoring
> > the trace unit state when the CPU enters low power states.
> > 
> > This patchset introduces a firmware property named
> > 'arm,coresight-needs-save-restore' - when this is present the
> > hardware state will be conditionally saved and restored.
> > 
> > A module parameter 'pm_save_enable' is also introduced which can
> > be configured to override the firmware property. This can be set
> > to never allow save/restore, to conditionally allow it, or to
> > do as the firmware indicates (default).
> > 
> > We avoid saving the hardware state when coresight isn't in use
> > to reduce PM latency - we can't determine this by reading the
> > claim tags (TRCCLAIMCLR) as these are 'trace' registers which need
> > power and clocking, something we can't easily provide in the PM
> > context. Therefore we rely on the existing drvdata->mode internal
> > state that is set when self-hosted coresight is used (and powered).
> > 
> > As we do not have a simple way of determining if an external agent
> > is using coresight, we don't save/restore for this use case.
> > 
> > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > ---
> >  drivers/hwtracing/coresight/coresight-etm4x.c | 322 ++++++++++++++++++
> >  drivers/hwtracing/coresight/coresight-etm4x.h |  64 ++++
> >  2 files changed, 386 insertions(+)
> > 
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> > index a128b5063f46..30f118792289 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> > @@ -18,6 +18,7 @@
> >  #include <linux/stat.h>
> >  #include <linux/clk.h>
> >  #include <linux/cpu.h>
> > +#include <linux/cpu_pm.h>
> >  #include <linux/coresight.h>
> >  #include <linux/coresight-pmu.h>
> >  #include <linux/pm_wakeup.h>
> > @@ -26,6 +27,7 @@
> >  #include <linux/uaccess.h>
> >  #include <linux/perf_event.h>
> >  #include <linux/pm_runtime.h>
> > +#include <linux/property.h>
> >  #include <asm/sections.h>
> >  #include <asm/local.h>
> >  #include <asm/virt.h>
> > @@ -37,6 +39,15 @@ static int boot_enable;
> >  module_param(boot_enable, int, 0444);
> >  MODULE_PARM_DESC(boot_enable, "Enable tracing on boot");
> >  
> > +#define PARAM_PM_SAVE_NEVER	0 /* never save/restore state */
> > +#define PARAM_PM_SAVE_ALWAYS	1 /* always save/restore state */
> > +#define PARAM_PM_SAVE_FIRMWARE	2 /* only save/restore if firmware flag set */
> > +
> > +static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
> > +module_param(pm_save_enable, int, 0444);
> > +MODULE_PARM_DESC(pm_save_enable,
> > +	"Save/restore state on power down: 0 = never, 1 = always, 2 = firmware");
> > +
> >  /* The number of ETMv4 currently registered */
> >  static int etm4_count;
> >  static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
> > @@ -54,6 +65,14 @@ static void etm4_os_unlock(struct etmv4_drvdata *drvdata)
> >  	isb();
> >  }
> >  
> > +static void etm4_os_lock(struct etmv4_drvdata *drvdata)
> > +{
> > +	/* Writing 0x1 to TRCOSLAR locks the trace registers */
> > +	writel_relaxed(0x1, drvdata->base + TRCOSLAR);
> > +	drvdata->os_unlock = false;
> > +	isb();
> > +}
> > +
> >  static bool etm4_arch_supported(u8 arch)
> >  {
> >  	/* Mask out the minor version number */
> > @@ -1085,6 +1104,294 @@ static void etm4_init_trace_id(struct etmv4_drvdata *drvdata)
> >  	drvdata->trcid = coresight_get_trace_id(drvdata->cpu);
> >  }
> >  
> > +#ifdef CONFIG_CPU_PM
> > +static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
> > +{
> > +	int i, ret = 0;
> > +	struct etmv4_save_state *state;
> > +	struct device *etm_dev = &drvdata->csdev->dev;
> > +
> > +	/*
> > +	 * As recommended by 3.4.1 ("The procedure when powering down the PE")
> > +	 * of ARM IHI 0064D
> > +	 */
> > +	dsb(sy);
> > +	isb();
> > +
> > +	CS_UNLOCK(drvdata->base);
> > +
> > +	/* Lock the OS lock to disable trace and external debugger access */
> > +	etm4_os_lock(drvdata);
> > +
> > +	/* wait for TRCSTATR.PMSTABLE to go up */
> > +	if (coresight_timeout(drvdata->base, TRCSTATR,
> > +					TRCSTATR_PMSTABLE_BIT, 1)) {
> > +		dev_err(etm_dev,
> > +			"timeout while waiting for PM Stable Status\n");
> > +		etm4_os_unlock(drvdata);
> > +		ret = -EBUSY;
> > +		goto out;
> > +	}
> > +
> > +	state = drvdata->save_state;
> > +
> > +	state->trcprgctlr = readl(drvdata->base + TRCPRGCTLR);
> > +	state->trcprocselr = readl(drvdata->base + TRCPROCSELR);
> > +	state->trcconfigr = readl(drvdata->base + TRCCONFIGR);
> > +	state->trcauxctlr = readl(drvdata->base + TRCAUXCTLR);
> > +	state->trceventctl0r = readl(drvdata->base + TRCEVENTCTL0R);
> > +	state->trceventctl1r = readl(drvdata->base + TRCEVENTCTL1R);
> > +	state->trcstallctlr = readl(drvdata->base + TRCSTALLCTLR);
> > +	state->trctsctlr = readl(drvdata->base + TRCTSCTLR);
> > +	state->trcsyncpr = readl(drvdata->base + TRCSYNCPR);
> > +	state->trcccctlr = readl(drvdata->base + TRCCCCTLR);
> > +	state->trcbbctlr = readl(drvdata->base + TRCBBCTLR);
> > +	state->trctraceidr = readl(drvdata->base + TRCTRACEIDR);
> > +	state->trcqctlr = readl(drvdata->base + TRCQCTLR);
> > +
> > +	state->trcvictlr = readl(drvdata->base + TRCVICTLR);
> > +	state->trcviiectlr = readl(drvdata->base + TRCVIIECTLR);
> > +	state->trcvissctlr = readl(drvdata->base + TRCVISSCTLR);
> > +	state->trcvipcssctlr = readl(drvdata->base + TRCVIPCSSCTLR);
> > +	state->trcvdctlr = readl(drvdata->base + TRCVDCTLR);
> > +	state->trcvdsacctlr = readl(drvdata->base + TRCVDSACCTLR);
> > +	state->trcvdarcctlr = readl(drvdata->base + TRCVDARCCTLR);
> > +
> > +	for (i = 0; i < drvdata->nrseqstate; i++)
> > +		state->trcseqevr[i] = readl(drvdata->base + TRCSEQEVRn(i));
> > +
> > +	state->trcseqrstevr = readl(drvdata->base + TRCSEQRSTEVR);
> > +	state->trcseqstr = readl(drvdata->base + TRCSEQSTR);
> > +	state->trcextinselr = readl(drvdata->base + TRCEXTINSELR);
> > +
> > +	for (i = 0; i < drvdata->nr_cntr; i++) {
> > +		state->trccntrldvr[i] = readl(drvdata->base + TRCCNTRLDVRn(i));
> > +		state->trccntctlr[i] = readl(drvdata->base + TRCCNTCTLRn(i));
> > +		state->trccntvr[i] = readl(drvdata->base + TRCCNTVRn(i));
> > +	}
> > +
> > +	for (i = 0; i < drvdata->nr_resource * 2; i++)
> > +		state->trcrsctlr[i] = readl(drvdata->base + TRCRSCTLRn(i));
> > +
> > +	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> > +		state->trcssccr[i] = readl(drvdata->base + TRCSSCCRn(i));
> > +		state->trcsscsr[i] = readl(drvdata->base + TRCSSCSRn(i));
> > +		state->trcsspcicr[i] = readl(drvdata->base + TRCSSPCICRn(i));
> > +	}
> > +
> > +	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
> > +		state->trcacvr[i] = readl(drvdata->base + TRCACVRn(i));
> > +		state->trcacatr[i] = readl(drvdata->base + TRCACATRn(i));
> > +	}
> > +
> > +	/*
> > +	 * Data trace stream is architecturally prohibited for A profile cores
> > +	 * so we don't save (or later restore) trcdvcvr and trcdvcmr - As per
> > +	 * section 1.3.4 ("Possible functional configurations of an ETMv4 trace
> > +	 * unit") of ARM IHI 0064D.
> > +	 */
> > +
> > +	for (i = 0; i < drvdata->numcidc; i++)
> > +		state->trccidcvr[i] = readl(drvdata->base + TRCCIDCVRn(i));
> > +
> > +	for (i = 0; i < drvdata->numvmidc; i++)
> > +		state->trcvmidcvr[i] = readl(drvdata->base + TRCVMIDCVRn(i));
> > +
> > +	state->trccidcctlr0 = readl(drvdata->base + TRCCIDCCTLR0);
> > +	state->trccidcctlr1 = readl(drvdata->base + TRCCIDCCTLR1);
> > +
> > +	state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR0);
> > +	state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR1);
> > +
> > +	state->trcclaimset = readl(drvdata->base + TRCCLAIMCLR);
> > +
> > +	state->trcpdcr = readl(drvdata->base + TRCPDCR);
> > +
> > +	/* wait for TRCSTATR.IDLE to go up */
> > +	if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT, 1)) {
> > +		dev_err(etm_dev,
> > +			"timeout while waiting for Idle Trace Status\n");
> > +		etm4_os_unlock(drvdata);
> > +		ret = -EBUSY;
> > +		goto out;
> > +	}
> > +
> > +	drvdata->state_needs_restore = true;
> > +
> > +	/*
> > +	 * Power can be removed from the trace unit now. We do this to
> > +	 * potentially save power on systems that respect the TRCPDCR_PU
> > +	 * despite requesting software to save/restore state.
> > +	 */
> > +	writel_relaxed((state->trcpdcr & ~TRCPDCR_PU),
> > +			drvdata->base + TRCPDCR);
> > +
> > +out:
> > +	CS_LOCK(drvdata->base);
> > +	return ret;
> > +}
> > +
> > +static void etm4_cpu_restore(struct etmv4_drvdata *drvdata)
> > +{
> > +	int i;
> > +	struct etmv4_save_state *state = drvdata->save_state;
> > +
> > +	CS_UNLOCK(drvdata->base);
> > +
> > +	writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
> > +
> > +	writel_relaxed(state->trcprgctlr, drvdata->base + TRCPRGCTLR);
> > +	writel_relaxed(state->trcprocselr, drvdata->base + TRCPROCSELR);
> > +	writel_relaxed(state->trcconfigr, drvdata->base + TRCCONFIGR);
> > +	writel_relaxed(state->trcauxctlr, drvdata->base + TRCAUXCTLR);
> > +	writel_relaxed(state->trceventctl0r, drvdata->base + TRCEVENTCTL0R);
> > +	writel_relaxed(state->trceventctl1r, drvdata->base + TRCEVENTCTL1R);
> > +	writel_relaxed(state->trcstallctlr, drvdata->base + TRCSTALLCTLR);
> > +	writel_relaxed(state->trctsctlr, drvdata->base + TRCTSCTLR);
> > +	writel_relaxed(state->trcsyncpr, drvdata->base + TRCSYNCPR);
> > +	writel_relaxed(state->trcccctlr, drvdata->base + TRCCCCTLR);
> > +	writel_relaxed(state->trcbbctlr, drvdata->base + TRCBBCTLR);
> > +	writel_relaxed(state->trctraceidr, drvdata->base + TRCTRACEIDR);
> > +	writel_relaxed(state->trcqctlr, drvdata->base + TRCQCTLR);
> > +
> > +	writel_relaxed(state->trcvictlr, drvdata->base + TRCVICTLR);
> > +	writel_relaxed(state->trcviiectlr, drvdata->base + TRCVIIECTLR);
> > +	writel_relaxed(state->trcvissctlr, drvdata->base + TRCVISSCTLR);
> > +	writel_relaxed(state->trcvipcssctlr, drvdata->base + TRCVIPCSSCTLR);
> > +	writel_relaxed(state->trcvdctlr, drvdata->base + TRCVDCTLR);
> > +	writel_relaxed(state->trcvdsacctlr, drvdata->base + TRCVDSACCTLR);
> > +	writel_relaxed(state->trcvdarcctlr, drvdata->base + TRCVDARCCTLR);
> > +
> > +	for (i = 0; i < drvdata->nrseqstate; i++)
> > +		writel_relaxed(state->trcseqevr[i],
> > +					drvdata->base + TRCSEQEVRn(i));
> > +
> > +	writel_relaxed(state->trcseqrstevr, drvdata->base + TRCSEQRSTEVR);
> > +	writel_relaxed(state->trcseqstr, drvdata->base + TRCSEQSTR);
> > +	writel_relaxed(state->trcextinselr, drvdata->base + TRCEXTINSELR);
> > +
> > +	for (i = 0; i < drvdata->nr_cntr; i++) {
> > +		writel_relaxed(state->trccntrldvr[i],
> > +					drvdata->base + TRCCNTRLDVRn(i));
> > +		writel_relaxed(state->trccntctlr[i],
> > +					drvdata->base + TRCCNTCTLRn(i));
> > +		writel_relaxed(state->trccntvr[i],
> > +					drvdata->base + TRCCNTVRn(i));
> > +	}
> > +
> > +	for (i = 0; i < drvdata->nr_resource * 2; i++)
> > +		writel_relaxed(state->trcrsctlr[i],
> > +					drvdata->base + TRCRSCTLRn(i));
> > +
> > +	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> > +		writel_relaxed(state->trcssccr[i],
> > +					drvdata->base + TRCSSCCRn(i));
> > +		writel_relaxed(state->trcsscsr[i],
> > +					drvdata->base + TRCSSCSRn(i));
> > +		writel_relaxed(state->trcsspcicr[i],
> > +					drvdata->base + TRCSSPCICRn(i));
> > +	}
> > +
> > +	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
> > +		writel_relaxed(state->trcacvr[i],
> > +					drvdata->base + TRCACVRn(i));
> > +		writel_relaxed(state->trcacatr[i],
> > +					drvdata->base + TRCACATRn(i));
> > +	}
> > +
> > +	for (i = 0; i < drvdata->numcidc; i++)
> > +		writel_relaxed(state->trccidcvr[i],
> > +					drvdata->base + TRCCIDCVRn(i));
> > +
> > +	for (i = 0; i < drvdata->numvmidc; i++)
> > +		writel_relaxed(state->trcvmidcvr[i],
> > +					drvdata->base + TRCVMIDCVRn(i));
> > +
> > +	writel_relaxed(state->trccidcctlr0, drvdata->base + TRCCIDCCTLR0);
> > +	writel_relaxed(state->trccidcctlr1, drvdata->base + TRCCIDCCTLR1);
> > +
> > +	writel_relaxed(state->trcvmidcctlr0, drvdata->base + TRCVMIDCCTLR0);
> > +	writel_relaxed(state->trcvmidcctlr0, drvdata->base + TRCVMIDCCTLR1);
> > +
> > +	writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
> > +
> > +	writel_relaxed(state->trcpdcr, drvdata->base + TRCPDCR);
> > +
> > +	drvdata->state_needs_restore = false;
> > +
> > +	/*
> > +	 * As recommended by section 4.3.7 ("Synchronization when using the
> > +	 * memory-mapped interface") of ARM IHI 0064D
> > +	 */
> > +	dsb(sy);
> > +	isb();
> > +
> > +	/* Unlock the OS lock to re-enable trace and external debug access */
> > +	etm4_os_unlock(drvdata);
> > +	CS_LOCK(drvdata->base);
> > +}
> > +
> > +static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
> > +			      void *v)
> > +{
> > +	struct etmv4_drvdata *drvdata;
> > +	unsigned int cpu = smp_processor_id();
> > +
> > +	if (!etmdrvdata[cpu])
> > +		return 0;
> > +
> > +	drvdata = etmdrvdata[cpu];
> > +
> > +	if (!drvdata->save_state)
> > +		return NOTIFY_OK;
> 
> The problem here is that if no memory was allocated for ->save_state at boot
> time and someone does:
>         $ echo 1 > /sys/module/coresight_etm4x/parameters/pm_save_enable
> 
> then they will be mislead in thinking that save/restore operations are taking
> place.  To avoid the problem I suggest to use module_param_cb() where memory can
> be allocated and freed as the functionality is requested by users.

Actually notice the permissions of pm_save_enable: 

> > +module_param(pm_save_enable, int, 0444);

I changed this to be readonly after boot. I initially started down the track of
module_param_cb, but allocating memory ahead of when it is needed was slightly
complex as the module_param_cb callback doesn't have drvdata and so you'd have
to figure out which of the etmdrvdata's to allocate for (perhaps all those that
are not NULL). You'd also have to allocate on probe as well.

Besides the benefit of changing the param via sysfs for testing, I'm not sure
that this is all that useful to anyone - especially as we currently don't support
save/restore for external debug. Unless there are potential coresight users
that don't have the ability to change the kernel command line or device tree?

Thanks,

Andrew Murray

> 
> Thanks,
> Mathieu
> 
> > +
> > +	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
> > +		return NOTIFY_BAD;
> > +
> > +	switch (cmd) {
> > +	case CPU_PM_ENTER:
> > +		/* save the state if self-hosted coresight is in use */
> > +		if (local_read(&drvdata->mode))
> > +			if (etm4_cpu_save(drvdata))
> > +				return NOTIFY_BAD;
> > +		break;
> > +	case CPU_PM_EXIT:
> > +	case CPU_PM_ENTER_FAILED:
> > +		/* trcclaimset is set when there is state to restore */
> > +		if (drvdata->state_needs_restore)
> > +			etm4_cpu_restore(drvdata);
> > +		break;
> > +	default:
> > +		return NOTIFY_DONE;
> > +	}
> > +
> > +	return NOTIFY_OK;
> > +}
> > +
> > +static struct notifier_block etm4_cpu_pm_nb = {
> > +	.notifier_call = etm4_cpu_pm_notify,
> > +};
> > +
> > +static int etm4_cpu_pm_register(void)
> > +{
> > +	return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
> > +}
> > +
> > +static void etm4_cpu_pm_unregister(void)
> > +{
> > +	cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
> > +}
> > +#else
> > +static int etm4_cpu_pm_register(void) { return 0; }
> > +static void etm4_cpu_pm_unregister(void) { }
> > +#endif
> > +
> > +static inline bool etm4_needs_save_restore(struct device *dev)
> > +{
> > +	return fwnode_property_present(dev->fwnode,
> > +				       "arm,coresight-needs-save-restore");
> > +}
> > +
> >  static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
> >  {
> >  	int ret;
> > @@ -1101,6 +1408,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
> >  
> >  	dev_set_drvdata(dev, drvdata);
> >  
> > +	if (pm_save_enable == PARAM_PM_SAVE_ALWAYS ||
> > +	    (pm_save_enable == PARAM_PM_SAVE_FIRMWARE &&
> > +	     etm4_needs_save_restore(dev))) {
> > +		drvdata->save_state = devm_kmalloc(dev,
> > +				sizeof(struct etmv4_save_state), GFP_KERNEL);
> > +		if (!drvdata->save_state)
> > +			return -ENOMEM;
> > +	}
> > +
> >  	/* Validity for the resource is already checked by the AMBA core */
> >  	base = devm_ioremap_resource(dev, res);
> >  	if (IS_ERR(base))
> > @@ -1135,6 +1451,10 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
> >  		if (ret < 0)
> >  			goto err_arch_supported;
> >  		hp_online = ret;
> > +
> > +		ret = etm4_cpu_pm_register();
> > +		if (ret)
> > +			goto err_arch_supported;
> >  	}
> >  
> >  	cpus_read_unlock();
> > @@ -1185,6 +1505,8 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
> >  
> >  err_arch_supported:
> >  	if (--etm4_count == 0) {
> > +		etm4_cpu_pm_unregister();
> > +
> >  		cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
> >  		if (hp_online)
> >  			cpuhp_remove_state_nocalls(hp_online);
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> > index 4523f10ddd0f..546d790cb01b 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> > @@ -175,6 +175,7 @@
> >  					 ETM_MODE_EXCL_USER)
> >  
> >  #define TRCSTATR_IDLE_BIT		0
> > +#define TRCSTATR_PMSTABLE_BIT		1
> >  #define ETM_DEFAULT_ADDR_COMP		0
> >  
> >  /* PowerDown Control Register bits */
> > @@ -281,6 +282,65 @@ struct etmv4_config {
> >  	u32				ext_inp;
> >  };
> >  
> > +/**
> > + * struct etm4_save_state - state to be preserved when ETM is without power
> > + */
> > +struct etmv4_save_state {
> > +	u32	trcprgctlr;
> > +	u32	trcprocselr;
> > +	u32	trcconfigr;
> > +	u32	trcauxctlr;
> > +	u32	trceventctl0r;
> > +	u32	trceventctl1r;
> > +	u32	trcstallctlr;
> > +	u32	trctsctlr;
> > +	u32	trcsyncpr;
> > +	u32	trcccctlr;
> > +	u32	trcbbctlr;
> > +	u32	trctraceidr;
> > +	u32	trcqctlr;
> > +
> > +	u32	trcvictlr;
> > +	u32	trcviiectlr;
> > +	u32	trcvissctlr;
> > +	u32	trcvipcssctlr;
> > +	u32	trcvdctlr;
> > +	u32	trcvdsacctlr;
> > +	u32	trcvdarcctlr;
> > +
> > +	u32	trcseqevr[ETM_MAX_SEQ_STATES];
> > +	u32	trcseqrstevr;
> > +	u32	trcseqstr;
> > +	u32	trcextinselr;
> > +	u32	trccntrldvr[ETMv4_MAX_CNTR];
> > +	u32	trccntctlr[ETMv4_MAX_CNTR];
> > +	u32	trccntvr[ETMv4_MAX_CNTR];
> > +
> > +	u32	trcrsctlr[ETM_MAX_RES_SEL * 2];
> > +
> > +	u32	trcssccr[ETM_MAX_SS_CMP];
> > +	u32	trcsscsr[ETM_MAX_SS_CMP];
> > +	u32	trcsspcicr[ETM_MAX_SS_CMP];
> > +
> > +	u64	trcacvr[ETM_MAX_SINGLE_ADDR_CMP];
> > +	u64	trcacatr[ETM_MAX_SINGLE_ADDR_CMP];
> > +	u64	trccidcvr[ETMv4_MAX_CTXID_CMP];
> > +	u32	trcvmidcvr[ETM_MAX_VMID_CMP];
> > +	u32	trccidcctlr0;
> > +	u32	trccidcctlr1;
> > +	u32	trcvmidcctlr0;
> > +	u32	trcvmidcctlr1;
> > +
> > +	u32	trcclaimset;
> > +
> > +	u32	cntr_val[ETMv4_MAX_CNTR];
> > +	u32	seq_state;
> > +	u32	vinst_ctrl;
> > +	u32	ss_status[ETM_MAX_SS_CMP];
> > +
> > +	u32	trcpdcr;
> > +};
> > +
> >  /**
> >   * struct etm4_drvdata - specifics associated to an ETM component
> >   * @base:       Memory mapped base address for this component.
> > @@ -336,6 +396,8 @@ struct etmv4_config {
> >   * @atbtrig:	If the implementation can support ATB triggers
> >   * @lpoverride:	If the implementation can support low-power state over.
> >   * @config:	structure holding configuration parameters.
> > + * @save_state:	State to be preserved across power loss
> > + * @state_needs_restore: True when there is context to restore after PM exit
> >   */
> >  struct etmv4_drvdata {
> >  	void __iomem			*base;
> > @@ -381,6 +443,8 @@ struct etmv4_drvdata {
> >  	bool				atbtrig;
> >  	bool				lpoverride;
> >  	struct etmv4_config		config;
> > +	struct etmv4_save_state		*save_state;
> > +	bool				state_needs_restore;
> >  };
> >  
> >  /* Address comparator access types */
> > -- 
> > 2.21.0
> > 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states
  2019-07-30 20:12 ` [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Mathieu Poirier
@ 2019-07-30 21:46   ` Andrew Murray
  0 siblings, 0 replies; 27+ messages in thread
From: Andrew Murray @ 2019-07-30 21:46 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Al.Grant, Suzuki K Poulose, Alexander Shishkin, coresight,
	Sudeep Holla, Leo Yan, linux-arm-kernel, Mike Leach

On Tue, Jul 30, 2019 at 02:12:20PM -0600, Mathieu Poirier wrote:
> Hi Andrew,
> 
> On Tue, Jul 30, 2019 at 01:51:51PM +0100, Andrew Murray wrote:
> > Some hardware will ignore bit TRCPDCR.PU which is used to signal
> > to hardware that power should not be removed from the trace unit.
> > Let's mitigate against this by conditionally saving and restoring
> > the trace unit state when the CPU enters low power states.
> > 
> > This patchset introduces a firmware property named
> > 'arm,coresight-needs-save-restore' - when this is present the
> > hardware state will be conditionally saved and restored.
> > 
> > A module parameter 'pm_save_enable' is also introduced which can
> > be configured to override the firmware property.
> > 
> > The hardware state is only ever saved and restored when a self-hosted
> > coresight is in use.
> > 
> > Changes since v3:
> > 
> >  - Only save/restore when self-hosted is being used and detect this
> >    without relying on the coresight registers (which may not be
> >    available)
> > 
> >  - Only allocate memory for etmv4_save_state at probe time when
> >    configuration indicates it may be used
> > 
> >  - Set pm_save_enable param to 0444 such that it is static after
> >    boot
> > 
> >  - Save/restore TRCPDCR
> > 
> >  - Add missing comments to struct etm4_drvdata documentation
> > 
> >  - Rebased onto coresight/next (8f1f9857)
> > 
> > Changes since v2:
> > 
> >  - Move the PM notifier block from drvdata to file static
> > 
> >  - Add section names to document references
> > 
> >  - Add additional information to commit messages
> > 
> >  - Remove trcdvcvr and trcdvcmr from saved state and add a comment to
> >    describe why
> > 
> >  - Ensure TRCPDCR_PU is set after restore and add a comment to explain
> >    why we bother toggling TRCPDCR_PU on save/restore
> > 
> >  - Reword the pm_save_enable options and add comments
> > 
> >  - Miscellaneous style changes
> > 
> >  - Move device tree binding documentation to its own patch
> > 
> > Changes since v1:
> > 
> >  - Rebased onto coresight/next
> > 
> >  - Correcly pass bit number rather than BIT macro to coresight_timeout
> > 
> >  - Abort saving state if a timeout occurs
> > 
> >  - Fix completely broken pm_notify handling and unregister handler on error
> > 
> >  - Use state_needs_restore to ensure state is restored only once
> > 
> >  - Add module parameter description to existing boot_enable parameter
> >    and use module_param instead of module_param_named
> > 
> >  - Add firmware bindings for coresight-needs-save-restore
> > 
> >  - Rename 'disable_pm_save' to 'pm_save_enable' which allows for
> >    disabled, enabled or firmware
> > 
> >  - Update comment on etm4_os_lock, it incorrectly indicated that
> >    the code unlocks the trace registers
> > 
> >  - Add comments to explain use of OS lock during save/restore
> > 
> >  - Fix incorrect error description whilst waiting for PM stable
> > 
> >  - Add WARN_ON_ONCE when cpu isn't as expected during save/restore
> > 
> >  - Various updates to commit messages
> > 
> > 
> > Andrew Murray (6):
> >   coresight: etm4x: remove superfluous setting of os_unlock
> >   coresight: etm4x: use explicit barriers on enable/disable
> >   coresight: etm4x: use module_param instead of module_param_named
> >   coresight: etm4x: improve clarity of etm4_os_unlock comment
> 
> I have picked up the first 4 patches, so no need to send them with your next
> revision.  Note that for patch 2/6 I have removed the "stable" tag as the patch
> doesn't apply to any of the stable tree.  Since I have another one like that in
> my tree I will rework both patches and send them directly to Greg for stable
> consideration.

Ah many thanks for this.

Andrew Murray

> 
> Thanks,
> Mathieu
> 
> 
> >   coresight: etm4x: save/restore state across CPU low power states
> >   dt-bindings: arm: coresight: Add support for
> >     coresight-needs-save-restore
> > 
> >  .../devicetree/bindings/arm/coresight.txt     |   3 +
> >  drivers/hwtracing/coresight/coresight-etm4x.c | 346 +++++++++++++++++-
> >  drivers/hwtracing/coresight/coresight-etm4x.h |  64 ++++
> >  3 files changed, 406 insertions(+), 7 deletions(-)
> > 
> > -- 
> > 2.21.0
> > 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* RE: [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states
  2019-07-30 21:45     ` Andrew Murray
@ 2019-07-31  8:16       ` Mike Leach
  2019-07-31  9:45         ` Andrew Murray
  0 siblings, 1 reply; 27+ messages in thread
From: Mike Leach @ 2019-07-31  8:16 UTC (permalink / raw)
  To: Andrew Murray, Mathieu Poirier
  Cc: Alexander Shishkin, coresight, Mike Leach, linux-arm-kernel,
	Sudeep Holla

Hi,

Since the decision has apparently been made to ignore the needs of external debug agents, then the "state" struct & variable used in this and the previously mentioned issues around allocating it are un-necessary complication. Simply use the existing config in the driver that contains all of the values that you need - and save on additional memory usage by the drivers.

Regards

Mike


> -----Original Message-----
> From: CoreSight <coresight-bounces@lists.linaro.org> On Behalf Of Andrew
> Murray
> Sent: 30 July 2019 22:46
> To: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>;
> coresight@lists.linaro.org; Sudeep Holla <Sudeep.Holla@arm.com>; linux-
> arm-kernel@lists.infradead.org; Mike Leach <mike.leach@linaro.org>
> Subject: Re: [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU
> low power states
>
> On Tue, Jul 30, 2019 at 03:16:33PM -0600, Mathieu Poirier wrote:
> > On Tue, Jul 30, 2019 at 01:51:56PM +0100, Andrew Murray wrote:
> > > Some hardware will ignore bit TRCPDCR.PU which is used to signal to
> > > hardware that power should not be removed from the trace unit.
> > > Let's mitigate against this by conditionally saving and restoring
> > > the trace unit state when the CPU enters low power states.
> > >
> > > This patchset introduces a firmware property named
> > > 'arm,coresight-needs-save-restore' - when this is present the
> > > hardware state will be conditionally saved and restored.
> > >
> > > A module parameter 'pm_save_enable' is also introduced which can be
> > > configured to override the firmware property. This can be set to
> > > never allow save/restore, to conditionally allow it, or to do as the
> > > firmware indicates (default).
> > >
> > > We avoid saving the hardware state when coresight isn't in use to
> > > reduce PM latency - we can't determine this by reading the claim
> > > tags (TRCCLAIMCLR) as these are 'trace' registers which need power
> > > and clocking, something we can't easily provide in the PM context.
> > > Therefore we rely on the existing drvdata->mode internal state that
> > > is set when self-hosted coresight is used (and powered).
> > >
> > > As we do not have a simple way of determining if an external agent
> > > is using coresight, we don't save/restore for this use case.
> > >
> > > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > > ---
> > >  drivers/hwtracing/coresight/coresight-etm4x.c | 322
> > > ++++++++++++++++++  drivers/hwtracing/coresight/coresight-etm4x.h |
> > > 64 ++++
> > >  2 files changed, 386 insertions(+)
> > >
> > > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c
> > > b/drivers/hwtracing/coresight/coresight-etm4x.c
> > > index a128b5063f46..30f118792289 100644
> > > --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> > > +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> > > @@ -18,6 +18,7 @@
> > >  #include <linux/stat.h>
> > >  #include <linux/clk.h>
> > >  #include <linux/cpu.h>
> > > +#include <linux/cpu_pm.h>
> > >  #include <linux/coresight.h>
> > >  #include <linux/coresight-pmu.h>
> > >  #include <linux/pm_wakeup.h>
> > > @@ -26,6 +27,7 @@
> > >  #include <linux/uaccess.h>
> > >  #include <linux/perf_event.h>
> > >  #include <linux/pm_runtime.h>
> > > +#include <linux/property.h>
> > >  #include <asm/sections.h>
> > >  #include <asm/local.h>
> > >  #include <asm/virt.h>
> > > @@ -37,6 +39,15 @@ static int boot_enable;
> > > module_param(boot_enable, int, 0444);
> MODULE_PARM_DESC(boot_enable,
> > > "Enable tracing on boot");
> > >
> > > +#define PARAM_PM_SAVE_NEVER0 /* never save/restore state
> */
> > > +#define PARAM_PM_SAVE_ALWAYS1 /* always save/restore
> state */
> > > +#define PARAM_PM_SAVE_FIRMWARE2 /* only save/restore if
> firmware flag set */
> > > +
> > > +static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
> > > +module_param(pm_save_enable, int, 0444);
> > > +MODULE_PARM_DESC(pm_save_enable,
> > > +"Save/restore state on power down: 0 = never, 1 = always, 2 =
> > > +firmware");
> > > +
> > >  /* The number of ETMv4 currently registered */  static int
> > > etm4_count;  static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; @@
> > > -54,6 +65,14 @@ static void etm4_os_unlock(struct etmv4_drvdata
> *drvdata)
> > >  isb();
> > >  }
> > >
> > > +static void etm4_os_lock(struct etmv4_drvdata *drvdata) {
> > > +/* Writing 0x1 to TRCOSLAR locks the trace registers */
> > > +writel_relaxed(0x1, drvdata->base + TRCOSLAR);
> > > +drvdata->os_unlock = false;
> > > +isb();
> > > +}
> > > +
> > >  static bool etm4_arch_supported(u8 arch)  {
> > >  /* Mask out the minor version number */ @@ -1085,6 +1104,294
> @@
> > > static void etm4_init_trace_id(struct etmv4_drvdata *drvdata)
> > >  drvdata->trcid = coresight_get_trace_id(drvdata->cpu);
> > >  }
> > >
> > > +#ifdef CONFIG_CPU_PM
> > > +static int etm4_cpu_save(struct etmv4_drvdata *drvdata) {
> > > +int i, ret = 0;
> > > +struct etmv4_save_state *state;
> > > +struct device *etm_dev = &drvdata->csdev->dev;
> > > +
> > > +/*
> > > + * As recommended by 3.4.1 ("The procedure when powering down
> the PE")
> > > + * of ARM IHI 0064D
> > > + */
> > > +dsb(sy);
> > > +isb();
> > > +
> > > +CS_UNLOCK(drvdata->base);
> > > +
> > > +/* Lock the OS lock to disable trace and external debugger access */
> > > +etm4_os_lock(drvdata);
> > > +
> > > +/* wait for TRCSTATR.PMSTABLE to go up */
> > > +if (coresight_timeout(drvdata->base, TRCSTATR,
> > > +TRCSTATR_PMSTABLE_BIT, 1)) {
> > > +dev_err(etm_dev,
> > > +"timeout while waiting for PM Stable Status\n");
> > > +etm4_os_unlock(drvdata);
> > > +ret = -EBUSY;
> > > +goto out;
> > > +}
> > > +
> > > +state = drvdata->save_state;
> > > +
> > > +state->trcprgctlr = readl(drvdata->base + TRCPRGCTLR);
> > > +state->trcprocselr = readl(drvdata->base + TRCPROCSELR);
> > > +state->trcconfigr = readl(drvdata->base + TRCCONFIGR);
> > > +state->trcauxctlr = readl(drvdata->base + TRCAUXCTLR);
> > > +state->trceventctl0r = readl(drvdata->base + TRCEVENTCTL0R);
> > > +state->trceventctl1r = readl(drvdata->base + TRCEVENTCTL1R);
> > > +state->trcstallctlr = readl(drvdata->base + TRCSTALLCTLR);
> > > +state->trctsctlr = readl(drvdata->base + TRCTSCTLR);
> > > +state->trcsyncpr = readl(drvdata->base + TRCSYNCPR);
> > > +state->trcccctlr = readl(drvdata->base + TRCCCCTLR);
> > > +state->trcbbctlr = readl(drvdata->base + TRCBBCTLR);
> > > +state->trctraceidr = readl(drvdata->base + TRCTRACEIDR);
> > > +state->trcqctlr = readl(drvdata->base + TRCQCTLR);
> > > +
> > > +state->trcvictlr = readl(drvdata->base + TRCVICTLR);
> > > +state->trcviiectlr = readl(drvdata->base + TRCVIIECTLR);
> > > +state->trcvissctlr = readl(drvdata->base + TRCVISSCTLR);
> > > +state->trcvipcssctlr = readl(drvdata->base + TRCVIPCSSCTLR);
> > > +state->trcvdctlr = readl(drvdata->base + TRCVDCTLR);
> > > +state->trcvdsacctlr = readl(drvdata->base + TRCVDSACCTLR);
> > > +state->trcvdarcctlr = readl(drvdata->base + TRCVDARCCTLR);
> > > +
> > > +for (i = 0; i < drvdata->nrseqstate; i++)
> > > +state->trcseqevr[i] = readl(drvdata->base + TRCSEQEVRn(i));
> > > +
> > > +state->trcseqrstevr = readl(drvdata->base + TRCSEQRSTEVR);
> > > +state->trcseqstr = readl(drvdata->base + TRCSEQSTR);
> > > +state->trcextinselr = readl(drvdata->base + TRCEXTINSELR);
> > > +
> > > +for (i = 0; i < drvdata->nr_cntr; i++) {
> > > +state->trccntrldvr[i] = readl(drvdata->base +
> TRCCNTRLDVRn(i));
> > > +state->trccntctlr[i] = readl(drvdata->base + TRCCNTCTLRn(i));
> > > +state->trccntvr[i] = readl(drvdata->base + TRCCNTVRn(i));
> > > +}
> > > +
> > > +for (i = 0; i < drvdata->nr_resource * 2; i++)
> > > +state->trcrsctlr[i] = readl(drvdata->base + TRCRSCTLRn(i));
> > > +
> > > +for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> > > +state->trcssccr[i] = readl(drvdata->base + TRCSSCCRn(i));
> > > +state->trcsscsr[i] = readl(drvdata->base + TRCSSCSRn(i));
> > > +state->trcsspcicr[i] = readl(drvdata->base + TRCSSPCICRn(i));
> > > +}
> > > +
> > > +for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
> > > +state->trcacvr[i] = readl(drvdata->base + TRCACVRn(i));
> > > +state->trcacatr[i] = readl(drvdata->base + TRCACATRn(i));
> > > +}
> > > +
> > > +/*
> > > + * Data trace stream is architecturally prohibited for A profile cores
> > > + * so we don't save (or later restore) trcdvcvr and trcdvcmr - As per
> > > + * section 1.3.4 ("Possible functional configurations of an ETMv4 trace
> > > + * unit") of ARM IHI 0064D.
> > > + */
> > > +
> > > +for (i = 0; i < drvdata->numcidc; i++)
> > > +state->trccidcvr[i] = readl(drvdata->base + TRCCIDCVRn(i));
> > > +
> > > +for (i = 0; i < drvdata->numvmidc; i++)
> > > +state->trcvmidcvr[i] = readl(drvdata->base +
> TRCVMIDCVRn(i));
> > > +
> > > +state->trccidcctlr0 = readl(drvdata->base + TRCCIDCCTLR0);
> > > +state->trccidcctlr1 = readl(drvdata->base + TRCCIDCCTLR1);
> > > +
> > > +state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR0);
> > > +state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR1);
> > > +
> > > +state->trcclaimset = readl(drvdata->base + TRCCLAIMCLR);
> > > +
> > > +state->trcpdcr = readl(drvdata->base + TRCPDCR);
> > > +
> > > +/* wait for TRCSTATR.IDLE to go up */
> > > +if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT,
> 1)) {
> > > +dev_err(etm_dev,
> > > +"timeout while waiting for Idle Trace Status\n");
> > > +etm4_os_unlock(drvdata);
> > > +ret = -EBUSY;
> > > +goto out;
> > > +}
> > > +
> > > +drvdata->state_needs_restore = true;
> > > +
> > > +/*
> > > + * Power can be removed from the trace unit now. We do this to
> > > + * potentially save power on systems that respect the TRCPDCR_PU
> > > + * despite requesting software to save/restore state.
> > > + */
> > > +writel_relaxed((state->trcpdcr & ~TRCPDCR_PU),
> > > +drvdata->base + TRCPDCR);
> > > +
> > > +out:
> > > +CS_LOCK(drvdata->base);
> > > +return ret;
> > > +}
> > > +
> > > +static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) {
> > > +int i;
> > > +struct etmv4_save_state *state = drvdata->save_state;
> > > +
> > > +CS_UNLOCK(drvdata->base);
> > > +
> > > +writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
> > > +
> > > +writel_relaxed(state->trcprgctlr, drvdata->base + TRCPRGCTLR);
> > > +writel_relaxed(state->trcprocselr, drvdata->base + TRCPROCSELR);
> > > +writel_relaxed(state->trcconfigr, drvdata->base + TRCCONFIGR);
> > > +writel_relaxed(state->trcauxctlr, drvdata->base + TRCAUXCTLR);
> > > +writel_relaxed(state->trceventctl0r, drvdata->base +
> TRCEVENTCTL0R);
> > > +writel_relaxed(state->trceventctl1r, drvdata->base +
> TRCEVENTCTL1R);
> > > +writel_relaxed(state->trcstallctlr, drvdata->base + TRCSTALLCTLR);
> > > +writel_relaxed(state->trctsctlr, drvdata->base + TRCTSCTLR);
> > > +writel_relaxed(state->trcsyncpr, drvdata->base + TRCSYNCPR);
> > > +writel_relaxed(state->trcccctlr, drvdata->base + TRCCCCTLR);
> > > +writel_relaxed(state->trcbbctlr, drvdata->base + TRCBBCTLR);
> > > +writel_relaxed(state->trctraceidr, drvdata->base + TRCTRACEIDR);
> > > +writel_relaxed(state->trcqctlr, drvdata->base + TRCQCTLR);
> > > +
> > > +writel_relaxed(state->trcvictlr, drvdata->base + TRCVICTLR);
> > > +writel_relaxed(state->trcviiectlr, drvdata->base + TRCVIIECTLR);
> > > +writel_relaxed(state->trcvissctlr, drvdata->base + TRCVISSCTLR);
> > > +writel_relaxed(state->trcvipcssctlr, drvdata->base + TRCVIPCSSCTLR);
> > > +writel_relaxed(state->trcvdctlr, drvdata->base + TRCVDCTLR);
> > > +writel_relaxed(state->trcvdsacctlr, drvdata->base + TRCVDSACCTLR);
> > > +writel_relaxed(state->trcvdarcctlr, drvdata->base + TRCVDARCCTLR);
> > > +
> > > +for (i = 0; i < drvdata->nrseqstate; i++)
> > > +writel_relaxed(state->trcseqevr[i],
> > > +drvdata->base + TRCSEQEVRn(i));
> > > +
> > > +writel_relaxed(state->trcseqrstevr, drvdata->base + TRCSEQRSTEVR);
> > > +writel_relaxed(state->trcseqstr, drvdata->base + TRCSEQSTR);
> > > +writel_relaxed(state->trcextinselr, drvdata->base + TRCEXTINSELR);
> > > +
> > > +for (i = 0; i < drvdata->nr_cntr; i++) {
> > > +writel_relaxed(state->trccntrldvr[i],
> > > +drvdata->base + TRCCNTRLDVRn(i));
> > > +writel_relaxed(state->trccntctlr[i],
> > > +drvdata->base + TRCCNTCTLRn(i));
> > > +writel_relaxed(state->trccntvr[i],
> > > +drvdata->base + TRCCNTVRn(i));
> > > +}
> > > +
> > > +for (i = 0; i < drvdata->nr_resource * 2; i++)
> > > +writel_relaxed(state->trcrsctlr[i],
> > > +drvdata->base + TRCRSCTLRn(i));
> > > +
> > > +for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> > > +writel_relaxed(state->trcssccr[i],
> > > +drvdata->base + TRCSSCCRn(i));
> > > +writel_relaxed(state->trcsscsr[i],
> > > +drvdata->base + TRCSSCSRn(i));
> > > +writel_relaxed(state->trcsspcicr[i],
> > > +drvdata->base + TRCSSPCICRn(i));
> > > +}
> > > +
> > > +for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
> > > +writel_relaxed(state->trcacvr[i],
> > > +drvdata->base + TRCACVRn(i));
> > > +writel_relaxed(state->trcacatr[i],
> > > +drvdata->base + TRCACATRn(i));
> > > +}
> > > +
> > > +for (i = 0; i < drvdata->numcidc; i++)
> > > +writel_relaxed(state->trccidcvr[i],
> > > +drvdata->base + TRCCIDCVRn(i));
> > > +
> > > +for (i = 0; i < drvdata->numvmidc; i++)
> > > +writel_relaxed(state->trcvmidcvr[i],
> > > +drvdata->base + TRCVMIDCVRn(i));
> > > +
> > > +writel_relaxed(state->trccidcctlr0, drvdata->base + TRCCIDCCTLR0);
> > > +writel_relaxed(state->trccidcctlr1, drvdata->base + TRCCIDCCTLR1);
> > > +
> > > +writel_relaxed(state->trcvmidcctlr0, drvdata->base +
> TRCVMIDCCTLR0);
> > > +writel_relaxed(state->trcvmidcctlr0, drvdata->base +
> > > +TRCVMIDCCTLR1);
> > > +
> > > +writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
> > > +
> > > +writel_relaxed(state->trcpdcr, drvdata->base + TRCPDCR);
> > > +
> > > +drvdata->state_needs_restore = false;
> > > +
> > > +/*
> > > + * As recommended by section 4.3.7 ("Synchronization when using
> the
> > > + * memory-mapped interface") of ARM IHI 0064D
> > > + */
> > > +dsb(sy);
> > > +isb();
> > > +
> > > +/* Unlock the OS lock to re-enable trace and external debug access
> */
> > > +etm4_os_unlock(drvdata);
> > > +CS_LOCK(drvdata->base);
> > > +}
> > > +
> > > +static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long
> cmd,
> > > +      void *v)
> > > +{
> > > +struct etmv4_drvdata *drvdata;
> > > +unsigned int cpu = smp_processor_id();
> > > +
> > > +if (!etmdrvdata[cpu])
> > > +return 0;
> > > +
> > > +drvdata = etmdrvdata[cpu];
> > > +
> > > +if (!drvdata->save_state)
> > > +return NOTIFY_OK;
> >
> > The problem here is that if no memory was allocated for ->save_state
> > at boot time and someone does:
> >         $ echo 1 >
> > /sys/module/coresight_etm4x/parameters/pm_save_enable
> >
> > then they will be mislead in thinking that save/restore operations are
> > taking place.  To avoid the problem I suggest to use module_param_cb()
> > where memory can be allocated and freed as the functionality is requested
> by users.
>
> Actually notice the permissions of pm_save_enable:
>
> > > +module_param(pm_save_enable, int, 0444);
>
> I changed this to be readonly after boot. I initially started down the track of
> module_param_cb, but allocating memory ahead of when it is needed was
> slightly complex as the module_param_cb callback doesn't have drvdata and
> so you'd have to figure out which of the etmdrvdata's to allocate for
> (perhaps all those that are not NULL). You'd also have to allocate on probe as
> well.
>
> Besides the benefit of changing the param via sysfs for testing, I'm not sure
> that this is all that useful to anyone - especially as we currently don't support
> save/restore for external debug. Unless there are potential coresight users
> that don't have the ability to change the kernel command line or device tree?
>
> Thanks,
>
> Andrew Murray
>
> >
> > Thanks,
> > Mathieu
> >
> > > +
> > > +if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
> > > +return NOTIFY_BAD;
> > > +
> > > +switch (cmd) {
> > > +case CPU_PM_ENTER:
> > > +/* save the state if self-hosted coresight is in use */
> > > +if (local_read(&drvdata->mode))
> > > +if (etm4_cpu_save(drvdata))
> > > +return NOTIFY_BAD;
> > > +break;
> > > +case CPU_PM_EXIT:
> > > +case CPU_PM_ENTER_FAILED:
> > > +/* trcclaimset is set when there is state to restore */
> > > +if (drvdata->state_needs_restore)
> > > +etm4_cpu_restore(drvdata);
> > > +break;
> > > +default:
> > > +return NOTIFY_DONE;
> > > +}
> > > +
> > > +return NOTIFY_OK;
> > > +}
> > > +
> > > +static struct notifier_block etm4_cpu_pm_nb = {
> > > +.notifier_call = etm4_cpu_pm_notify, };
> > > +
> > > +static int etm4_cpu_pm_register(void) {
> > > +return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
> > > +}
> > > +
> > > +static void etm4_cpu_pm_unregister(void) {
> > > +cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
> > > +}
> > > +#else
> > > +static int etm4_cpu_pm_register(void) { return 0; } static void
> > > +etm4_cpu_pm_unregister(void) { } #endif
> > > +
> > > +static inline bool etm4_needs_save_restore(struct device *dev) {
> > > +return fwnode_property_present(dev->fwnode,
> > > +       "arm,coresight-needs-save-restore");
> > > +}
> > > +
> > >  static int etm4_probe(struct amba_device *adev, const struct
> > > amba_id *id)  {
> > >  int ret;
> > > @@ -1101,6 +1408,15 @@ static int etm4_probe(struct amba_device
> > > *adev, const struct amba_id *id)
> > >
> > >  dev_set_drvdata(dev, drvdata);
> > >
> > > +if (pm_save_enable == PARAM_PM_SAVE_ALWAYS ||
> > > +    (pm_save_enable == PARAM_PM_SAVE_FIRMWARE &&
> > > +     etm4_needs_save_restore(dev))) {
> > > +drvdata->save_state = devm_kmalloc(dev,
> > > +sizeof(struct etmv4_save_state),
> GFP_KERNEL);
> > > +if (!drvdata->save_state)
> > > +return -ENOMEM;
> > > +}
> > > +
> > >  /* Validity for the resource is already checked by the AMBA core */
> > >  base = devm_ioremap_resource(dev, res);
> > >  if (IS_ERR(base))
> > > @@ -1135,6 +1451,10 @@ static int etm4_probe(struct amba_device
> *adev, const struct amba_id *id)
> > >  if (ret < 0)
> > >  goto err_arch_supported;
> > >  hp_online = ret;
> > > +
> > > +ret = etm4_cpu_pm_register();
> > > +if (ret)
> > > +goto err_arch_supported;
> > >  }
> > >
> > >  cpus_read_unlock();
> > > @@ -1185,6 +1505,8 @@ static int etm4_probe(struct amba_device
> > > *adev, const struct amba_id *id)
> > >
> > >  err_arch_supported:
> > >  if (--etm4_count == 0) {
> > > +etm4_cpu_pm_unregister();
> > > +
> > >
> cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTI
> NG);
> > >  if (hp_online)
> > >  cpuhp_remove_state_nocalls(hp_online);
> > > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h
> > > b/drivers/hwtracing/coresight/coresight-etm4x.h
> > > index 4523f10ddd0f..546d790cb01b 100644
> > > --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> > > +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> > > @@ -175,6 +175,7 @@
> > >   ETM_MODE_EXCL_USER)
> > >
> > >  #define TRCSTATR_IDLE_BIT0
> > > +#define TRCSTATR_PMSTABLE_BIT1
> > >  #define ETM_DEFAULT_ADDR_COMP0
> > >
> > >  /* PowerDown Control Register bits */ @@ -281,6 +282,65 @@ struct
> > > etmv4_config {
> > >  u32ext_inp;
> > >  };
> > >
> > > +/**
> > > + * struct etm4_save_state - state to be preserved when ETM is
> > > +without power  */ struct etmv4_save_state {
> > > +u32trcprgctlr;
> > > +u32trcprocselr;
> > > +u32trcconfigr;
> > > +u32trcauxctlr;
> > > +u32trceventctl0r;
> > > +u32trceventctl1r;
> > > +u32trcstallctlr;
> > > +u32trctsctlr;
> > > +u32trcsyncpr;
> > > +u32trcccctlr;
> > > +u32trcbbctlr;
> > > +u32trctraceidr;
> > > +u32trcqctlr;
> > > +
> > > +u32trcvictlr;
> > > +u32trcviiectlr;
> > > +u32trcvissctlr;
> > > +u32trcvipcssctlr;
> > > +u32trcvdctlr;
> > > +u32trcvdsacctlr;
> > > +u32trcvdarcctlr;
> > > +
> > > +u32trcseqevr[ETM_MAX_SEQ_STATES];
> > > +u32trcseqrstevr;
> > > +u32trcseqstr;
> > > +u32trcextinselr;
> > > +u32trccntrldvr[ETMv4_MAX_CNTR];
> > > +u32trccntctlr[ETMv4_MAX_CNTR];
> > > +u32trccntvr[ETMv4_MAX_CNTR];
> > > +
> > > +u32trcrsctlr[ETM_MAX_RES_SEL * 2];
> > > +
> > > +u32trcssccr[ETM_MAX_SS_CMP];
> > > +u32trcsscsr[ETM_MAX_SS_CMP];
> > > +u32trcsspcicr[ETM_MAX_SS_CMP];
> > > +
> > > +u64trcacvr[ETM_MAX_SINGLE_ADDR_CMP];
> > > +u64trcacatr[ETM_MAX_SINGLE_ADDR_CMP];
> > > +u64trccidcvr[ETMv4_MAX_CTXID_CMP];
> > > +u32trcvmidcvr[ETM_MAX_VMID_CMP];
> > > +u32trccidcctlr0;
> > > +u32trccidcctlr1;
> > > +u32trcvmidcctlr0;
> > > +u32trcvmidcctlr1;
> > > +
> > > +u32trcclaimset;
> > > +
> > > +u32cntr_val[ETMv4_MAX_CNTR];
> > > +u32seq_state;
> > > +u32vinst_ctrl;
> > > +u32ss_status[ETM_MAX_SS_CMP];
> > > +
> > > +u32trcpdcr;
> > > +};
> > > +
> > >  /**
> > >   * struct etm4_drvdata - specifics associated to an ETM component
> > >   * @base:       Memory mapped base address for this component.
> > > @@ -336,6 +396,8 @@ struct etmv4_config {
> > >   * @atbtrig:If the implementation can support ATB triggers
> > >   * @lpoverride:If the implementation can support low-power state
> over.
> > >   * @config:structure holding configuration parameters.
> > > + * @save_state:State to be preserved across power loss
> > > + * @state_needs_restore: True when there is context to restore
> > > + after PM exit
> > >   */
> > >  struct etmv4_drvdata {
> > >  void __iomem*base;
> > > @@ -381,6 +443,8 @@ struct etmv4_drvdata {
> > >  boolatbtrig;
> > >  boollpoverride;
> > >  struct etmv4_configconfig;
> > > +struct etmv4_save_state*save_state;
> > > +boolstate_needs_restore;
> > >  };
> > >
> > >  /* Address comparator access types */
> > > --
> > > 2.21.0
> > >
> _______________________________________________
> CoreSight mailing list
> CoreSight@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/coresight
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states
  2019-07-31  8:16       ` Mike Leach
@ 2019-07-31  9:45         ` Andrew Murray
  0 siblings, 0 replies; 27+ messages in thread
From: Andrew Murray @ 2019-07-31  9:45 UTC (permalink / raw)
  To: Mike Leach
  Cc: Mathieu Poirier, Alexander Shishkin, coresight, Sudeep Holla,
	linux-arm-kernel, Mike Leach

On Wed, Jul 31, 2019 at 09:16:08AM +0100, Mike Leach wrote:
> Hi,
> 
> Since the decision has apparently been made to ignore the needs of external debug agents, then the "state" struct & variable used in this and the previously mentioned issues around allocating it are un-necessary complication. Simply use the existing config in the driver that contains all of the values that you need - and save on additional memory usage by the drivers.

Even though we can restore the ETM config with the config from the driver, we
still need to save/restore the state of non-config data such as counters (TRCCNTVRn)
that would get otherwise get lost.

Thanks,

Andrew Murray

> 
> Regards
> 
> Mike
> 
> 
> > -----Original Message-----
> > From: CoreSight <coresight-bounces@lists.linaro.org> On Behalf Of Andrew
> > Murray
> > Sent: 30 July 2019 22:46
> > To: Mathieu Poirier <mathieu.poirier@linaro.org>
> > Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>;
> > coresight@lists.linaro.org; Sudeep Holla <Sudeep.Holla@arm.com>; linux-
> > arm-kernel@lists.infradead.org; Mike Leach <mike.leach@linaro.org>
> > Subject: Re: [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU
> > low power states
> > 
> > On Tue, Jul 30, 2019 at 03:16:33PM -0600, Mathieu Poirier wrote:
> > > On Tue, Jul 30, 2019 at 01:51:56PM +0100, Andrew Murray wrote:
> > > > Some hardware will ignore bit TRCPDCR.PU which is used to signal to
> > > > hardware that power should not be removed from the trace unit.
> > > > Let's mitigate against this by conditionally saving and restoring
> > > > the trace unit state when the CPU enters low power states.
> > > >
> > > > This patchset introduces a firmware property named
> > > > 'arm,coresight-needs-save-restore' - when this is present the
> > > > hardware state will be conditionally saved and restored.
> > > >
> > > > A module parameter 'pm_save_enable' is also introduced which can be
> > > > configured to override the firmware property. This can be set to
> > > > never allow save/restore, to conditionally allow it, or to do as the
> > > > firmware indicates (default).
> > > >
> > > > We avoid saving the hardware state when coresight isn't in use to
> > > > reduce PM latency - we can't determine this by reading the claim
> > > > tags (TRCCLAIMCLR) as these are 'trace' registers which need power
> > > > and clocking, something we can't easily provide in the PM context.
> > > > Therefore we rely on the existing drvdata->mode internal state that
> > > > is set when self-hosted coresight is used (and powered).
> > > >
> > > > As we do not have a simple way of determining if an external agent
> > > > is using coresight, we don't save/restore for this use case.
> > > >
> > > > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > > > ---
> > > >  drivers/hwtracing/coresight/coresight-etm4x.c | 322
> > > > ++++++++++++++++++  drivers/hwtracing/coresight/coresight-etm4x.h |
> > > > 64 ++++
> > > >  2 files changed, 386 insertions(+)
> > > >
> > > > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c
> > > > b/drivers/hwtracing/coresight/coresight-etm4x.c
> > > > index a128b5063f46..30f118792289 100644
> > > > --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> > > > +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> > > > @@ -18,6 +18,7 @@
> > > >  #include <linux/stat.h>
> > > >  #include <linux/clk.h>
> > > >  #include <linux/cpu.h>
> > > > +#include <linux/cpu_pm.h>
> > > >  #include <linux/coresight.h>
> > > >  #include <linux/coresight-pmu.h>
> > > >  #include <linux/pm_wakeup.h>
> > > > @@ -26,6 +27,7 @@
> > > >  #include <linux/uaccess.h>
> > > >  #include <linux/perf_event.h>
> > > >  #include <linux/pm_runtime.h>
> > > > +#include <linux/property.h>
> > > >  #include <asm/sections.h>
> > > >  #include <asm/local.h>
> > > >  #include <asm/virt.h>
> > > > @@ -37,6 +39,15 @@ static int boot_enable;
> > > > module_param(boot_enable, int, 0444);
> > MODULE_PARM_DESC(boot_enable,
> > > > "Enable tracing on boot");
> > > >
> > > > +#define PARAM_PM_SAVE_NEVER	0 /* never save/restore state
> > */
> > > > +#define PARAM_PM_SAVE_ALWAYS	1 /* always save/restore
> > state */
> > > > +#define PARAM_PM_SAVE_FIRMWARE	2 /* only save/restore if
> > firmware flag set */
> > > > +
> > > > +static int pm_save_enable = PARAM_PM_SAVE_FIRMWARE;
> > > > +module_param(pm_save_enable, int, 0444);
> > > > +MODULE_PARM_DESC(pm_save_enable,
> > > > +	"Save/restore state on power down: 0 = never, 1 = always, 2 =
> > > > +firmware");
> > > > +
> > > >  /* The number of ETMv4 currently registered */  static int
> > > > etm4_count;  static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; @@
> > > > -54,6 +65,14 @@ static void etm4_os_unlock(struct etmv4_drvdata
> > *drvdata)
> > > >  	isb();
> > > >  }
> > > >
> > > > +static void etm4_os_lock(struct etmv4_drvdata *drvdata) {
> > > > +	/* Writing 0x1 to TRCOSLAR locks the trace registers */
> > > > +	writel_relaxed(0x1, drvdata->base + TRCOSLAR);
> > > > +	drvdata->os_unlock = false;
> > > > +	isb();
> > > > +}
> > > > +
> > > >  static bool etm4_arch_supported(u8 arch)  {
> > > >  	/* Mask out the minor version number */ @@ -1085,6 +1104,294
> > @@
> > > > static void etm4_init_trace_id(struct etmv4_drvdata *drvdata)
> > > >  	drvdata->trcid = coresight_get_trace_id(drvdata->cpu);
> > > >  }
> > > >
> > > > +#ifdef CONFIG_CPU_PM
> > > > +static int etm4_cpu_save(struct etmv4_drvdata *drvdata) {
> > > > +	int i, ret = 0;
> > > > +	struct etmv4_save_state *state;
> > > > +	struct device *etm_dev = &drvdata->csdev->dev;
> > > > +
> > > > +	/*
> > > > +	 * As recommended by 3.4.1 ("The procedure when powering down
> > the PE")
> > > > +	 * of ARM IHI 0064D
> > > > +	 */
> > > > +	dsb(sy);
> > > > +	isb();
> > > > +
> > > > +	CS_UNLOCK(drvdata->base);
> > > > +
> > > > +	/* Lock the OS lock to disable trace and external debugger access */
> > > > +	etm4_os_lock(drvdata);
> > > > +
> > > > +	/* wait for TRCSTATR.PMSTABLE to go up */
> > > > +	if (coresight_timeout(drvdata->base, TRCSTATR,
> > > > +					TRCSTATR_PMSTABLE_BIT, 1)) {
> > > > +		dev_err(etm_dev,
> > > > +			"timeout while waiting for PM Stable Status\n");
> > > > +		etm4_os_unlock(drvdata);
> > > > +		ret = -EBUSY;
> > > > +		goto out;
> > > > +	}
> > > > +
> > > > +	state = drvdata->save_state;
> > > > +
> > > > +	state->trcprgctlr = readl(drvdata->base + TRCPRGCTLR);
> > > > +	state->trcprocselr = readl(drvdata->base + TRCPROCSELR);
> > > > +	state->trcconfigr = readl(drvdata->base + TRCCONFIGR);
> > > > +	state->trcauxctlr = readl(drvdata->base + TRCAUXCTLR);
> > > > +	state->trceventctl0r = readl(drvdata->base + TRCEVENTCTL0R);
> > > > +	state->trceventctl1r = readl(drvdata->base + TRCEVENTCTL1R);
> > > > +	state->trcstallctlr = readl(drvdata->base + TRCSTALLCTLR);
> > > > +	state->trctsctlr = readl(drvdata->base + TRCTSCTLR);
> > > > +	state->trcsyncpr = readl(drvdata->base + TRCSYNCPR);
> > > > +	state->trcccctlr = readl(drvdata->base + TRCCCCTLR);
> > > > +	state->trcbbctlr = readl(drvdata->base + TRCBBCTLR);
> > > > +	state->trctraceidr = readl(drvdata->base + TRCTRACEIDR);
> > > > +	state->trcqctlr = readl(drvdata->base + TRCQCTLR);
> > > > +
> > > > +	state->trcvictlr = readl(drvdata->base + TRCVICTLR);
> > > > +	state->trcviiectlr = readl(drvdata->base + TRCVIIECTLR);
> > > > +	state->trcvissctlr = readl(drvdata->base + TRCVISSCTLR);
> > > > +	state->trcvipcssctlr = readl(drvdata->base + TRCVIPCSSCTLR);
> > > > +	state->trcvdctlr = readl(drvdata->base + TRCVDCTLR);
> > > > +	state->trcvdsacctlr = readl(drvdata->base + TRCVDSACCTLR);
> > > > +	state->trcvdarcctlr = readl(drvdata->base + TRCVDARCCTLR);
> > > > +
> > > > +	for (i = 0; i < drvdata->nrseqstate; i++)
> > > > +		state->trcseqevr[i] = readl(drvdata->base + TRCSEQEVRn(i));
> > > > +
> > > > +	state->trcseqrstevr = readl(drvdata->base + TRCSEQRSTEVR);
> > > > +	state->trcseqstr = readl(drvdata->base + TRCSEQSTR);
> > > > +	state->trcextinselr = readl(drvdata->base + TRCEXTINSELR);
> > > > +
> > > > +	for (i = 0; i < drvdata->nr_cntr; i++) {
> > > > +		state->trccntrldvr[i] = readl(drvdata->base +
> > TRCCNTRLDVRn(i));
> > > > +		state->trccntctlr[i] = readl(drvdata->base + TRCCNTCTLRn(i));
> > > > +		state->trccntvr[i] = readl(drvdata->base + TRCCNTVRn(i));
> > > > +	}
> > > > +
> > > > +	for (i = 0; i < drvdata->nr_resource * 2; i++)
> > > > +		state->trcrsctlr[i] = readl(drvdata->base + TRCRSCTLRn(i));
> > > > +
> > > > +	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> > > > +		state->trcssccr[i] = readl(drvdata->base + TRCSSCCRn(i));
> > > > +		state->trcsscsr[i] = readl(drvdata->base + TRCSSCSRn(i));
> > > > +		state->trcsspcicr[i] = readl(drvdata->base + TRCSSPCICRn(i));
> > > > +	}
> > > > +
> > > > +	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
> > > > +		state->trcacvr[i] = readl(drvdata->base + TRCACVRn(i));
> > > > +		state->trcacatr[i] = readl(drvdata->base + TRCACATRn(i));
> > > > +	}
> > > > +
> > > > +	/*
> > > > +	 * Data trace stream is architecturally prohibited for A profile cores
> > > > +	 * so we don't save (or later restore) trcdvcvr and trcdvcmr - As per
> > > > +	 * section 1.3.4 ("Possible functional configurations of an ETMv4 trace
> > > > +	 * unit") of ARM IHI 0064D.
> > > > +	 */
> > > > +
> > > > +	for (i = 0; i < drvdata->numcidc; i++)
> > > > +		state->trccidcvr[i] = readl(drvdata->base + TRCCIDCVRn(i));
> > > > +
> > > > +	for (i = 0; i < drvdata->numvmidc; i++)
> > > > +		state->trcvmidcvr[i] = readl(drvdata->base +
> > TRCVMIDCVRn(i));
> > > > +
> > > > +	state->trccidcctlr0 = readl(drvdata->base + TRCCIDCCTLR0);
> > > > +	state->trccidcctlr1 = readl(drvdata->base + TRCCIDCCTLR1);
> > > > +
> > > > +	state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR0);
> > > > +	state->trcvmidcctlr0 = readl(drvdata->base + TRCVMIDCCTLR1);
> > > > +
> > > > +	state->trcclaimset = readl(drvdata->base + TRCCLAIMCLR);
> > > > +
> > > > +	state->trcpdcr = readl(drvdata->base + TRCPDCR);
> > > > +
> > > > +	/* wait for TRCSTATR.IDLE to go up */
> > > > +	if (coresight_timeout(drvdata->base, TRCSTATR, TRCSTATR_IDLE_BIT,
> > 1)) {
> > > > +		dev_err(etm_dev,
> > > > +			"timeout while waiting for Idle Trace Status\n");
> > > > +		etm4_os_unlock(drvdata);
> > > > +		ret = -EBUSY;
> > > > +		goto out;
> > > > +	}
> > > > +
> > > > +	drvdata->state_needs_restore = true;
> > > > +
> > > > +	/*
> > > > +	 * Power can be removed from the trace unit now. We do this to
> > > > +	 * potentially save power on systems that respect the TRCPDCR_PU
> > > > +	 * despite requesting software to save/restore state.
> > > > +	 */
> > > > +	writel_relaxed((state->trcpdcr & ~TRCPDCR_PU),
> > > > +			drvdata->base + TRCPDCR);
> > > > +
> > > > +out:
> > > > +	CS_LOCK(drvdata->base);
> > > > +	return ret;
> > > > +}
> > > > +
> > > > +static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) {
> > > > +	int i;
> > > > +	struct etmv4_save_state *state = drvdata->save_state;
> > > > +
> > > > +	CS_UNLOCK(drvdata->base);
> > > > +
> > > > +	writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
> > > > +
> > > > +	writel_relaxed(state->trcprgctlr, drvdata->base + TRCPRGCTLR);
> > > > +	writel_relaxed(state->trcprocselr, drvdata->base + TRCPROCSELR);
> > > > +	writel_relaxed(state->trcconfigr, drvdata->base + TRCCONFIGR);
> > > > +	writel_relaxed(state->trcauxctlr, drvdata->base + TRCAUXCTLR);
> > > > +	writel_relaxed(state->trceventctl0r, drvdata->base +
> > TRCEVENTCTL0R);
> > > > +	writel_relaxed(state->trceventctl1r, drvdata->base +
> > TRCEVENTCTL1R);
> > > > +	writel_relaxed(state->trcstallctlr, drvdata->base + TRCSTALLCTLR);
> > > > +	writel_relaxed(state->trctsctlr, drvdata->base + TRCTSCTLR);
> > > > +	writel_relaxed(state->trcsyncpr, drvdata->base + TRCSYNCPR);
> > > > +	writel_relaxed(state->trcccctlr, drvdata->base + TRCCCCTLR);
> > > > +	writel_relaxed(state->trcbbctlr, drvdata->base + TRCBBCTLR);
> > > > +	writel_relaxed(state->trctraceidr, drvdata->base + TRCTRACEIDR);
> > > > +	writel_relaxed(state->trcqctlr, drvdata->base + TRCQCTLR);
> > > > +
> > > > +	writel_relaxed(state->trcvictlr, drvdata->base + TRCVICTLR);
> > > > +	writel_relaxed(state->trcviiectlr, drvdata->base + TRCVIIECTLR);
> > > > +	writel_relaxed(state->trcvissctlr, drvdata->base + TRCVISSCTLR);
> > > > +	writel_relaxed(state->trcvipcssctlr, drvdata->base + TRCVIPCSSCTLR);
> > > > +	writel_relaxed(state->trcvdctlr, drvdata->base + TRCVDCTLR);
> > > > +	writel_relaxed(state->trcvdsacctlr, drvdata->base + TRCVDSACCTLR);
> > > > +	writel_relaxed(state->trcvdarcctlr, drvdata->base + TRCVDARCCTLR);
> > > > +
> > > > +	for (i = 0; i < drvdata->nrseqstate; i++)
> > > > +		writel_relaxed(state->trcseqevr[i],
> > > > +					drvdata->base + TRCSEQEVRn(i));
> > > > +
> > > > +	writel_relaxed(state->trcseqrstevr, drvdata->base + TRCSEQRSTEVR);
> > > > +	writel_relaxed(state->trcseqstr, drvdata->base + TRCSEQSTR);
> > > > +	writel_relaxed(state->trcextinselr, drvdata->base + TRCEXTINSELR);
> > > > +
> > > > +	for (i = 0; i < drvdata->nr_cntr; i++) {
> > > > +		writel_relaxed(state->trccntrldvr[i],
> > > > +					drvdata->base + TRCCNTRLDVRn(i));
> > > > +		writel_relaxed(state->trccntctlr[i],
> > > > +					drvdata->base + TRCCNTCTLRn(i));
> > > > +		writel_relaxed(state->trccntvr[i],
> > > > +					drvdata->base + TRCCNTVRn(i));
> > > > +	}
> > > > +
> > > > +	for (i = 0; i < drvdata->nr_resource * 2; i++)
> > > > +		writel_relaxed(state->trcrsctlr[i],
> > > > +					drvdata->base + TRCRSCTLRn(i));
> > > > +
> > > > +	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> > > > +		writel_relaxed(state->trcssccr[i],
> > > > +					drvdata->base + TRCSSCCRn(i));
> > > > +		writel_relaxed(state->trcsscsr[i],
> > > > +					drvdata->base + TRCSSCSRn(i));
> > > > +		writel_relaxed(state->trcsspcicr[i],
> > > > +					drvdata->base + TRCSSPCICRn(i));
> > > > +	}
> > > > +
> > > > +	for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
> > > > +		writel_relaxed(state->trcacvr[i],
> > > > +					drvdata->base + TRCACVRn(i));
> > > > +		writel_relaxed(state->trcacatr[i],
> > > > +					drvdata->base + TRCACATRn(i));
> > > > +	}
> > > > +
> > > > +	for (i = 0; i < drvdata->numcidc; i++)
> > > > +		writel_relaxed(state->trccidcvr[i],
> > > > +					drvdata->base + TRCCIDCVRn(i));
> > > > +
> > > > +	for (i = 0; i < drvdata->numvmidc; i++)
> > > > +		writel_relaxed(state->trcvmidcvr[i],
> > > > +					drvdata->base + TRCVMIDCVRn(i));
> > > > +
> > > > +	writel_relaxed(state->trccidcctlr0, drvdata->base + TRCCIDCCTLR0);
> > > > +	writel_relaxed(state->trccidcctlr1, drvdata->base + TRCCIDCCTLR1);
> > > > +
> > > > +	writel_relaxed(state->trcvmidcctlr0, drvdata->base +
> > TRCVMIDCCTLR0);
> > > > +	writel_relaxed(state->trcvmidcctlr0, drvdata->base +
> > > > +TRCVMIDCCTLR1);
> > > > +
> > > > +	writel_relaxed(state->trcclaimset, drvdata->base + TRCCLAIMSET);
> > > > +
> > > > +	writel_relaxed(state->trcpdcr, drvdata->base + TRCPDCR);
> > > > +
> > > > +	drvdata->state_needs_restore = false;
> > > > +
> > > > +	/*
> > > > +	 * As recommended by section 4.3.7 ("Synchronization when using
> > the
> > > > +	 * memory-mapped interface") of ARM IHI 0064D
> > > > +	 */
> > > > +	dsb(sy);
> > > > +	isb();
> > > > +
> > > > +	/* Unlock the OS lock to re-enable trace and external debug access
> > */
> > > > +	etm4_os_unlock(drvdata);
> > > > +	CS_LOCK(drvdata->base);
> > > > +}
> > > > +
> > > > +static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long
> > cmd,
> > > > +			      void *v)
> > > > +{
> > > > +	struct etmv4_drvdata *drvdata;
> > > > +	unsigned int cpu = smp_processor_id();
> > > > +
> > > > +	if (!etmdrvdata[cpu])
> > > > +		return 0;
> > > > +
> > > > +	drvdata = etmdrvdata[cpu];
> > > > +
> > > > +	if (!drvdata->save_state)
> > > > +		return NOTIFY_OK;
> > >
> > > The problem here is that if no memory was allocated for ->save_state
> > > at boot time and someone does:
> > >         $ echo 1 >
> > > /sys/module/coresight_etm4x/parameters/pm_save_enable
> > >
> > > then they will be mislead in thinking that save/restore operations are
> > > taking place.  To avoid the problem I suggest to use module_param_cb()
> > > where memory can be allocated and freed as the functionality is requested
> > by users.
> > 
> > Actually notice the permissions of pm_save_enable:
> > 
> > > > +module_param(pm_save_enable, int, 0444);
> > 
> > I changed this to be readonly after boot. I initially started down the track of
> > module_param_cb, but allocating memory ahead of when it is needed was
> > slightly complex as the module_param_cb callback doesn't have drvdata and
> > so you'd have to figure out which of the etmdrvdata's to allocate for
> > (perhaps all those that are not NULL). You'd also have to allocate on probe as
> > well.
> > 
> > Besides the benefit of changing the param via sysfs for testing, I'm not sure
> > that this is all that useful to anyone - especially as we currently don't support
> > save/restore for external debug. Unless there are potential coresight users
> > that don't have the ability to change the kernel command line or device tree?
> > 
> > Thanks,
> > 
> > Andrew Murray
> > 
> > >
> > > Thanks,
> > > Mathieu
> > >
> > > > +
> > > > +	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
> > > > +		return NOTIFY_BAD;
> > > > +
> > > > +	switch (cmd) {
> > > > +	case CPU_PM_ENTER:
> > > > +		/* save the state if self-hosted coresight is in use */
> > > > +		if (local_read(&drvdata->mode))
> > > > +			if (etm4_cpu_save(drvdata))
> > > > +				return NOTIFY_BAD;
> > > > +		break;
> > > > +	case CPU_PM_EXIT:
> > > > +	case CPU_PM_ENTER_FAILED:
> > > > +		/* trcclaimset is set when there is state to restore */
> > > > +		if (drvdata->state_needs_restore)
> > > > +			etm4_cpu_restore(drvdata);
> > > > +		break;
> > > > +	default:
> > > > +		return NOTIFY_DONE;
> > > > +	}
> > > > +
> > > > +	return NOTIFY_OK;
> > > > +}
> > > > +
> > > > +static struct notifier_block etm4_cpu_pm_nb = {
> > > > +	.notifier_call = etm4_cpu_pm_notify, };
> > > > +
> > > > +static int etm4_cpu_pm_register(void) {
> > > > +	return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
> > > > +}
> > > > +
> > > > +static void etm4_cpu_pm_unregister(void) {
> > > > +	cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
> > > > +}
> > > > +#else
> > > > +static int etm4_cpu_pm_register(void) { return 0; } static void
> > > > +etm4_cpu_pm_unregister(void) { } #endif
> > > > +
> > > > +static inline bool etm4_needs_save_restore(struct device *dev) {
> > > > +	return fwnode_property_present(dev->fwnode,
> > > > +				       "arm,coresight-needs-save-restore");
> > > > +}
> > > > +
> > > >  static int etm4_probe(struct amba_device *adev, const struct
> > > > amba_id *id)  {
> > > >  	int ret;
> > > > @@ -1101,6 +1408,15 @@ static int etm4_probe(struct amba_device
> > > > *adev, const struct amba_id *id)
> > > >
> > > >  	dev_set_drvdata(dev, drvdata);
> > > >
> > > > +	if (pm_save_enable == PARAM_PM_SAVE_ALWAYS ||
> > > > +	    (pm_save_enable == PARAM_PM_SAVE_FIRMWARE &&
> > > > +	     etm4_needs_save_restore(dev))) {
> > > > +		drvdata->save_state = devm_kmalloc(dev,
> > > > +				sizeof(struct etmv4_save_state),
> > GFP_KERNEL);
> > > > +		if (!drvdata->save_state)
> > > > +			return -ENOMEM;
> > > > +	}
> > > > +
> > > >  	/* Validity for the resource is already checked by the AMBA core */
> > > >  	base = devm_ioremap_resource(dev, res);
> > > >  	if (IS_ERR(base))
> > > > @@ -1135,6 +1451,10 @@ static int etm4_probe(struct amba_device
> > *adev, const struct amba_id *id)
> > > >  		if (ret < 0)
> > > >  			goto err_arch_supported;
> > > >  		hp_online = ret;
> > > > +
> > > > +		ret = etm4_cpu_pm_register();
> > > > +		if (ret)
> > > > +			goto err_arch_supported;
> > > >  	}
> > > >
> > > >  	cpus_read_unlock();
> > > > @@ -1185,6 +1505,8 @@ static int etm4_probe(struct amba_device
> > > > *adev, const struct amba_id *id)
> > > >
> > > >  err_arch_supported:
> > > >  	if (--etm4_count == 0) {
> > > > +		etm4_cpu_pm_unregister();
> > > > +
> > > >
> > 	cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTI
> > NG);
> > > >  		if (hp_online)
> > > >  			cpuhp_remove_state_nocalls(hp_online);
> > > > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h
> > > > b/drivers/hwtracing/coresight/coresight-etm4x.h
> > > > index 4523f10ddd0f..546d790cb01b 100644
> > > > --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> > > > +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> > > > @@ -175,6 +175,7 @@
> > > >  					 ETM_MODE_EXCL_USER)
> > > >
> > > >  #define TRCSTATR_IDLE_BIT		0
> > > > +#define TRCSTATR_PMSTABLE_BIT		1
> > > >  #define ETM_DEFAULT_ADDR_COMP		0
> > > >
> > > >  /* PowerDown Control Register bits */ @@ -281,6 +282,65 @@ struct
> > > > etmv4_config {
> > > >  	u32				ext_inp;
> > > >  };
> > > >
> > > > +/**
> > > > + * struct etm4_save_state - state to be preserved when ETM is
> > > > +without power  */ struct etmv4_save_state {
> > > > +	u32	trcprgctlr;
> > > > +	u32	trcprocselr;
> > > > +	u32	trcconfigr;
> > > > +	u32	trcauxctlr;
> > > > +	u32	trceventctl0r;
> > > > +	u32	trceventctl1r;
> > > > +	u32	trcstallctlr;
> > > > +	u32	trctsctlr;
> > > > +	u32	trcsyncpr;
> > > > +	u32	trcccctlr;
> > > > +	u32	trcbbctlr;
> > > > +	u32	trctraceidr;
> > > > +	u32	trcqctlr;
> > > > +
> > > > +	u32	trcvictlr;
> > > > +	u32	trcviiectlr;
> > > > +	u32	trcvissctlr;
> > > > +	u32	trcvipcssctlr;
> > > > +	u32	trcvdctlr;
> > > > +	u32	trcvdsacctlr;
> > > > +	u32	trcvdarcctlr;
> > > > +
> > > > +	u32	trcseqevr[ETM_MAX_SEQ_STATES];
> > > > +	u32	trcseqrstevr;
> > > > +	u32	trcseqstr;
> > > > +	u32	trcextinselr;
> > > > +	u32	trccntrldvr[ETMv4_MAX_CNTR];
> > > > +	u32	trccntctlr[ETMv4_MAX_CNTR];
> > > > +	u32	trccntvr[ETMv4_MAX_CNTR];
> > > > +
> > > > +	u32	trcrsctlr[ETM_MAX_RES_SEL * 2];
> > > > +
> > > > +	u32	trcssccr[ETM_MAX_SS_CMP];
> > > > +	u32	trcsscsr[ETM_MAX_SS_CMP];
> > > > +	u32	trcsspcicr[ETM_MAX_SS_CMP];
> > > > +
> > > > +	u64	trcacvr[ETM_MAX_SINGLE_ADDR_CMP];
> > > > +	u64	trcacatr[ETM_MAX_SINGLE_ADDR_CMP];
> > > > +	u64	trccidcvr[ETMv4_MAX_CTXID_CMP];
> > > > +	u32	trcvmidcvr[ETM_MAX_VMID_CMP];
> > > > +	u32	trccidcctlr0;
> > > > +	u32	trccidcctlr1;
> > > > +	u32	trcvmidcctlr0;
> > > > +	u32	trcvmidcctlr1;
> > > > +
> > > > +	u32	trcclaimset;
> > > > +
> > > > +	u32	cntr_val[ETMv4_MAX_CNTR];
> > > > +	u32	seq_state;
> > > > +	u32	vinst_ctrl;
> > > > +	u32	ss_status[ETM_MAX_SS_CMP];
> > > > +
> > > > +	u32	trcpdcr;
> > > > +};
> > > > +
> > > >  /**
> > > >   * struct etm4_drvdata - specifics associated to an ETM component
> > > >   * @base:       Memory mapped base address for this component.
> > > > @@ -336,6 +396,8 @@ struct etmv4_config {
> > > >   * @atbtrig:	If the implementation can support ATB triggers
> > > >   * @lpoverride:	If the implementation can support low-power state
> > over.
> > > >   * @config:	structure holding configuration parameters.
> > > > + * @save_state:	State to be preserved across power loss
> > > > + * @state_needs_restore: True when there is context to restore
> > > > + after PM exit
> > > >   */
> > > >  struct etmv4_drvdata {
> > > >  	void __iomem			*base;
> > > > @@ -381,6 +443,8 @@ struct etmv4_drvdata {
> > > >  	bool				atbtrig;
> > > >  	bool				lpoverride;
> > > >  	struct etmv4_config		config;
> > > > +	struct etmv4_save_state		*save_state;
> > > > +	bool				state_needs_restore;
> > > >  };
> > > >
> > > >  /* Address comparator access types */
> > > > --
> > > > 2.21.0
> > > >
> > _______________________________________________
> > CoreSight mailing list
> > CoreSight@lists.linaro.org
> > https://lists.linaro.org/mailman/listinfo/coresight

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable
  2019-07-30 12:51 ` [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable Andrew Murray
@ 2019-08-01 13:31   ` Sasha Levin
  2019-08-01 14:48     ` Mathieu Poirier
  2019-08-02 18:08   ` Sasha Levin
  1 sibling, 1 reply; 27+ messages in thread
From: Sasha Levin @ 2019-08-01 13:31 UTC (permalink / raw)
  To: Sasha Levin, Andrew Murray, Mathieu Poirier; +Cc: , stable, linux-arm-kernel

Hi,

[This is an automated email]

This commit has been processed because it contains a -stable tag.
The stable tag indicates that it's relevant for the following trees: all

The bot has tested the following trees: v5.2.4, v5.1.21, v4.19.62, v4.14.134, v4.9.186, v4.4.186.

v5.2.4: Build OK!
v5.1.21: Build OK!
v4.19.62: Failed to apply! Possible dependencies:
    41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
    68a147752d04 ("coresight: etmx: Claim devices before use")
    e006d89abedd ("coresight: etm4x: Add support for handling errors")
    e2a1551a881f ("coresight: etm3: Add support for handling errors")

v4.14.134: Failed to apply! Possible dependencies:
    41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
    68a147752d04 ("coresight: etmx: Claim devices before use")
    e006d89abedd ("coresight: etm4x: Add support for handling errors")
    e2a1551a881f ("coresight: etm3: Add support for handling errors")

v4.9.186: Failed to apply! Possible dependencies:
    297ab90f15f6 ("coresight: tmc: Cleanup operation mode handling")
    2cd541402829 ("coresight: tmc: minor fix for output log")
    41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
    68a147752d04 ("coresight: etmx: Claim devices before use")
    c38e505e2701 ("coresight: tmc: Get rid of mode parameter for helper routines")
    e006d89abedd ("coresight: etm4x: Add support for handling errors")
    e2a1551a881f ("coresight: etm3: Add support for handling errors")

v4.4.186: Failed to apply! Possible dependencies:
    1925a470ce69 ("coresight: etm3x: splitting struct etm_drvdata")
    2127154d115d ("coresight: etm3x: implementing user/kernel mode tracing")
    22fd532eaa0c ("coresight: etm3x: adding operation mode for etm_enable()")
    27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
    41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
    52210c8745e4 ("coresight: implementing 'cpu_id()' API")
    68a147752d04 ("coresight: etmx: Claim devices before use")
    882d5e112491 ("coresight: etm3x: implementing perf_enable/disable() API")
    b3e94405941e ("coresight: associating path with session rather than tracer")
    c04148e708c0 ("coresight: etm3x: moving sysFS entries to dedicated file")
    c1f8e57c9e66 ("coresight: etm3x: moving etm_readl/writel to header file")
    e2a1551a881f ("coresight: etm3: Add support for handling errors")
    e827d4550aa3 ("coresight: etb10: adding operation mode for sink->enable()")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

--
Thanks,
Sasha

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable
  2019-08-01 13:31   ` Sasha Levin
@ 2019-08-01 14:48     ` Mathieu Poirier
  0 siblings, 0 replies; 27+ messages in thread
From: Mathieu Poirier @ 2019-08-01 14:48 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Andrew Murray, # 4 . 7, linux-arm-kernel

On Thu, 1 Aug 2019 at 07:31, Sasha Levin <sashal@kernel.org> wrote:
>
> Hi,
>
> [This is an automated email]
>
> This commit has been processed because it contains a -stable tag.
> The stable tag indicates that it's relevant for the following trees: all
>
> The bot has tested the following trees: v5.2.4, v5.1.21, v4.19.62, v4.14.134, v4.9.186, v4.4.186.
>
> v5.2.4: Build OK!
> v5.1.21: Build OK!
> v4.19.62: Failed to apply! Possible dependencies:
>     41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
>     68a147752d04 ("coresight: etmx: Claim devices before use")
>     e006d89abedd ("coresight: etm4x: Add support for handling errors")
>     e2a1551a881f ("coresight: etm3: Add support for handling errors")
>
> v4.14.134: Failed to apply! Possible dependencies:
>     41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
>     68a147752d04 ("coresight: etmx: Claim devices before use")
>     e006d89abedd ("coresight: etm4x: Add support for handling errors")
>     e2a1551a881f ("coresight: etm3: Add support for handling errors")
>
> v4.9.186: Failed to apply! Possible dependencies:
>     297ab90f15f6 ("coresight: tmc: Cleanup operation mode handling")
>     2cd541402829 ("coresight: tmc: minor fix for output log")
>     41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
>     68a147752d04 ("coresight: etmx: Claim devices before use")
>     c38e505e2701 ("coresight: tmc: Get rid of mode parameter for helper routines")
>     e006d89abedd ("coresight: etm4x: Add support for handling errors")
>     e2a1551a881f ("coresight: etm3: Add support for handling errors")
>
> v4.4.186: Failed to apply! Possible dependencies:
>     1925a470ce69 ("coresight: etm3x: splitting struct etm_drvdata")
>     2127154d115d ("coresight: etm3x: implementing user/kernel mode tracing")
>     22fd532eaa0c ("coresight: etm3x: adding operation mode for etm_enable()")
>     27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
>     41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
>     52210c8745e4 ("coresight: implementing 'cpu_id()' API")
>     68a147752d04 ("coresight: etmx: Claim devices before use")
>     882d5e112491 ("coresight: etm3x: implementing perf_enable/disable() API")
>     b3e94405941e ("coresight: associating path with session rather than tracer")
>     c04148e708c0 ("coresight: etm3x: moving sysFS entries to dedicated file")
>     c1f8e57c9e66 ("coresight: etm3x: moving etm_readl/writel to header file")
>     e2a1551a881f ("coresight: etm3: Add support for handling errors")
>     e827d4550aa3 ("coresight: etb10: adding operation mode for sink->enable()")
>
>
> NOTE: The patch will not be queued to stable trees until it is upstream.
>
> How should we proceed with this patch?

I have another one like that - will send a separate set that applies correctly.

Thanks for the consideration,
Mathieu

>
> --
> Thanks,
> Sasha

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 3/6] coresight: etm4x: use module_param instead of module_param_named
  2019-07-30 12:51 ` [PATCH v4 3/6] coresight: etm4x: use module_param instead of module_param_named Andrew Murray
@ 2019-08-02 10:23   ` Suzuki K Poulose
  0 siblings, 0 replies; 27+ messages in thread
From: Suzuki K Poulose @ 2019-08-02 10:23 UTC (permalink / raw)
  To: andrew.murray, mathieu.poirier, alexander.shishkin
  Cc: Al.Grant, coresight, leo.yan, Sudeep.Holla, linux-arm-kernel, mike.leach



On 30/07/2019 13:51, Andrew Murray wrote:
> Given that the user-exposed module parameter for 'boot_enable' matches
> the variable that it sets, let's use module_param instead of
> module_param_named.
> 
> Let's also use octal permissions (checkpatch recommends this) and
> provide a module parameter description.
> 
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
>   drivers/hwtracing/coresight/coresight-etm4x.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> index ec9468880c71..615bdbf7c9b7 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> @@ -34,7 +34,8 @@
>   #include "coresight-etm-perf.h"
>   
>   static int boot_enable;
> -module_param_named(boot_enable, boot_enable, int, S_IRUGO);
> +module_param(boot_enable, int, 0444);
> +MODULE_PARM_DESC(boot_enable, "Enable tracing on boot");
>   
>   /* The number of ETMv4 currently registered */
>   static int etm4_count;
> 

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-07-30 12:51 ` [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore Andrew Murray
@ 2019-08-02 10:40   ` Suzuki K Poulose
  2019-08-02 14:37     ` Andrew Murray
  0 siblings, 1 reply; 27+ messages in thread
From: Suzuki K Poulose @ 2019-08-02 10:40 UTC (permalink / raw)
  To: andrew.murray, mathieu.poirier, alexander.shishkin
  Cc: Al.Grant, coresight, leo.yan, Sudeep.Holla, linux-arm-kernel, mike.leach

Hi Andrew,

On 30/07/2019 13:51, Andrew Murray wrote:
> Some coresight components, because of choices made during hardware
> integration, require their state to be saved and restored across CPU low
> power states.
> 
> The software has no reliable method of detecting when save/restore is
> required thus let's add a binding to inform the kernel.
> 
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
>   Documentation/devicetree/bindings/arm/coresight.txt | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> index fcc3bacfd8bc..7cbdb7893af8 100644
> --- a/Documentation/devicetree/bindings/arm/coresight.txt
> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> @@ -92,6 +92,9 @@ its hardware characteristcs.
>   	* arm,cp14: must be present if the system accesses ETM/PTM management
>   	  registers via co-processor 14.
>   
> +	* arm,coresight-needs-save-restore: boolean. Indicates that software
> +	  should save/restore state across power down.
> +

Do you think we could be a bit more descriptive here about when people could add
it to the DT ? Here we don't mention when someone should use this property and
it may be added to platforms where it may be absolutely unnecessary. How about :

"Indicates that the hardware implementation may not honor the Powerup request
from the software and thus might loose the register context on CPU power down 
(e.g, during CPUIdle). Software must save/restore the context during a CPU power 
transition cycle."

Cheers
Suzuki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states
  2019-07-30 12:51 ` [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states Andrew Murray
  2019-07-30 21:16   ` Mathieu Poirier
@ 2019-08-02 10:54   ` Suzuki K Poulose
  2019-08-14  9:12     ` Andrew Murray
  1 sibling, 1 reply; 27+ messages in thread
From: Suzuki K Poulose @ 2019-08-02 10:54 UTC (permalink / raw)
  To: andrew.murray, mathieu.poirier, alexander.shishkin
  Cc: Al.Grant, coresight, leo.yan, Sudeep.Holla, linux-arm-kernel, mike.leach



On 30/07/2019 13:51, Andrew Murray wrote:
> Some hardware will ignore bit TRCPDCR.PU which is used to signal
> to hardware that power should not be removed from the trace unit.
> Let's mitigate against this by conditionally saving and restoring
> the trace unit state when the CPU enters low power states.
> 
> This patchset introduces a firmware property named
> 'arm,coresight-needs-save-restore' - when this is present the
> hardware state will be conditionally saved and restored.
> 
> A module parameter 'pm_save_enable' is also introduced which can
> be configured to override the firmware property. This can be set
> to never allow save/restore, to conditionally allow it, or to
> do as the firmware indicates (default).
> 
> We avoid saving the hardware state when coresight isn't in use
> to reduce PM latency - we can't determine this by reading the
> claim tags (TRCCLAIMCLR) as these are 'trace' registers which need
> power and clocking, something we can't easily provide in the PM
> context. Therefore we rely on the existing drvdata->mode internal
> state that is set when self-hosted coresight is used (and powered).
> 
> As we do not have a simple way of determining if an external agent
> is using coresight, we don't save/restore for this use case.
> 
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
>   drivers/hwtracing/coresight/coresight-etm4x.c | 322 ++++++++++++++++++
>   drivers/hwtracing/coresight/coresight-etm4x.h |  64 ++++
>   2 files changed, 386 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> index a128b5063f46..30f118792289 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c


> +static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
> +			      void *v)
> +{
> +	struct etmv4_drvdata *drvdata;
> +	unsigned int cpu = smp_processor_id();
> +
> +	if (!etmdrvdata[cpu])
> +		return 0;
> +
> +	drvdata = etmdrvdata[cpu];
> +
> +	if (!drvdata->save_state)
> +		return NOTIFY_OK;
> +
> +	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
> +		return NOTIFY_BAD;

minor nit: you may skip the second call to smp_processor_id() as this is called
on from non-preemptible context.

> +
> +	switch (cmd) {
> +	case CPU_PM_ENTER:
> +		/* save the state if self-hosted coresight is in use */
> +		if (local_read(&drvdata->mode))
> +			if (etm4_cpu_save(drvdata))
> +				return NOTIFY_BAD;
> +		break;
> +	case CPU_PM_EXIT:
> +	case CPU_PM_ENTER_FAILED:
> +		/* trcclaimset is set when there is state to restore */
> +		if (drvdata->state_needs_restore)
> +			etm4_cpu_restore(drvdata);
> +		break;
> +	default:
> +		return NOTIFY_DONE;
> +	}
> +
> +	return NOTIFY_OK;
> +}
> +


> +static void etm4_cpu_pm_unregister(void)
> +{
> +	cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
> +}
> +#else
> +static int etm4_cpu_pm_register(void) { return 0; }
> +static void etm4_cpu_pm_unregister(void) { }
> +#endif
> +
> +static inline bool etm4_needs_save_restore(struct device *dev)
> +{
> +	return fwnode_property_present(dev->fwnode,

nit: It may be safe to use dev_fwnode(dev), instead of dev->fwnode. But I
see a lot of existing users of dev->fwnode. Not sure it does have an impact.

Looks fine to me ,

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-08-02 10:40   ` Suzuki K Poulose
@ 2019-08-02 14:37     ` Andrew Murray
  2019-08-04 13:13       ` Mathieu Poirier
  0 siblings, 1 reply; 27+ messages in thread
From: Andrew Murray @ 2019-08-02 14:37 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: Al.Grant, mathieu.poirier, alexander.shishkin, coresight,
	leo.yan, Sudeep.Holla, linux-arm-kernel, mike.leach

On Fri, Aug 02, 2019 at 11:40:54AM +0100, Suzuki K Poulose wrote:
> Hi Andrew,
> 
> On 30/07/2019 13:51, Andrew Murray wrote:
> > Some coresight components, because of choices made during hardware
> > integration, require their state to be saved and restored across CPU low
> > power states.
> > 
> > The software has no reliable method of detecting when save/restore is
> > required thus let's add a binding to inform the kernel.
> > 
> > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > ---
> >   Documentation/devicetree/bindings/arm/coresight.txt | 3 +++
> >   1 file changed, 3 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> > index fcc3bacfd8bc..7cbdb7893af8 100644
> > --- a/Documentation/devicetree/bindings/arm/coresight.txt
> > +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> > @@ -92,6 +92,9 @@ its hardware characteristcs.
> >   	* arm,cp14: must be present if the system accesses ETM/PTM management
> >   	  registers via co-processor 14.
> > +	* arm,coresight-needs-save-restore: boolean. Indicates that software
> > +	  should save/restore state across power down.
> > +
> 
> Do you think we could be a bit more descriptive here about when people could add
> it to the DT ? Here we don't mention when someone should use this property and
> it may be added to platforms where it may be absolutely unnecessary. How about :
> 
> "Indicates that the hardware implementation may not honor the Powerup request
> from the software and thus might loose the register context on CPU power
> down (e.g, during CPUIdle). Software must save/restore the context during a
> CPU power transition cycle."

How about the following:

"Indicates that the hardware will loose register context on CPU power down (e.g.
CPUIdle), despite the TRCPDCR.PU bit being set."

I'm keen to avoid making suggestions about what the kernel will do when it sees
this flag and thus prefer to focus on describing what the hardware does. So I
dropped your last sentence. However the name of the flag still implies policy
which I don't like.

I also changed the 'may not honor' wording, I'm not sure if this is really the
case or if the spec is open to interpretation.

It would great for this wording to also apply to other CS components though I
haven't investigated if these have a PU bit or something different.

Thanks,

Andrew Murray

> 
> Cheers
> Suzuki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable
  2019-07-30 12:51 ` [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable Andrew Murray
  2019-08-01 13:31   ` Sasha Levin
@ 2019-08-02 18:08   ` Sasha Levin
  1 sibling, 0 replies; 27+ messages in thread
From: Sasha Levin @ 2019-08-02 18:08 UTC (permalink / raw)
  To: Sasha Levin, Andrew Murray, Mathieu Poirier; +Cc: , stable, linux-arm-kernel

Hi,

[This is an automated email]

This commit has been processed because it contains a -stable tag.
The stable tag indicates that it's relevant for the following trees: all

The bot has tested the following trees: v5.2.4, v5.1.21, v4.19.62, v4.14.134, v4.9.186, v4.4.186.

v5.2.4: Build OK!
v5.1.21: Build OK!
v4.19.62: Failed to apply! Possible dependencies:
    41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
    68a147752d04 ("coresight: etmx: Claim devices before use")
    e006d89abedd ("coresight: etm4x: Add support for handling errors")
    e2a1551a881f ("coresight: etm3: Add support for handling errors")

v4.14.134: Failed to apply! Possible dependencies:
    41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
    68a147752d04 ("coresight: etmx: Claim devices before use")
    e006d89abedd ("coresight: etm4x: Add support for handling errors")
    e2a1551a881f ("coresight: etm3: Add support for handling errors")

v4.9.186: Failed to apply! Possible dependencies:
    297ab90f15f6 ("coresight: tmc: Cleanup operation mode handling")
    2cd541402829 ("coresight: tmc: minor fix for output log")
    41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
    68a147752d04 ("coresight: etmx: Claim devices before use")
    c38e505e2701 ("coresight: tmc: Get rid of mode parameter for helper routines")
    e006d89abedd ("coresight: etm4x: Add support for handling errors")
    e2a1551a881f ("coresight: etm3: Add support for handling errors")

v4.4.186: Failed to apply! Possible dependencies:
    1925a470ce69 ("coresight: etm3x: splitting struct etm_drvdata")
    2127154d115d ("coresight: etm3x: implementing user/kernel mode tracing")
    22fd532eaa0c ("coresight: etm3x: adding operation mode for etm_enable()")
    27b10da8fff2 ("coresight: etb10: moving to local atomic operations")
    41a75cdde735 ("coresight: Convert driver messages to dev_dbg")
    52210c8745e4 ("coresight: implementing 'cpu_id()' API")
    68a147752d04 ("coresight: etmx: Claim devices before use")
    882d5e112491 ("coresight: etm3x: implementing perf_enable/disable() API")
    b3e94405941e ("coresight: associating path with session rather than tracer")
    c04148e708c0 ("coresight: etm3x: moving sysFS entries to dedicated file")
    c1f8e57c9e66 ("coresight: etm3x: moving etm_readl/writel to header file")
    e2a1551a881f ("coresight: etm3: Add support for handling errors")
    e827d4550aa3 ("coresight: etb10: adding operation mode for sink->enable()")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

--
Thanks,
Sasha

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-08-02 14:37     ` Andrew Murray
@ 2019-08-04 13:13       ` Mathieu Poirier
  2019-08-14 10:01         ` Andrew Murray
  0 siblings, 1 reply; 27+ messages in thread
From: Mathieu Poirier @ 2019-08-04 13:13 UTC (permalink / raw)
  To: Andrew Murray
  Cc: Al Grant, Suzuki K Poulose, Alexander Shishkin, Coresight ML,
	Sudeep Holla, Leo Yan, linux-arm-kernel, Mike Leach

On Fri, 2 Aug 2019 at 08:37, Andrew Murray <andrew.murray@arm.com> wrote:
>
> On Fri, Aug 02, 2019 at 11:40:54AM +0100, Suzuki K Poulose wrote:
> > Hi Andrew,
> >
> > On 30/07/2019 13:51, Andrew Murray wrote:
> > > Some coresight components, because of choices made during hardware
> > > integration, require their state to be saved and restored across CPU low
> > > power states.
> > >
> > > The software has no reliable method of detecting when save/restore is
> > > required thus let's add a binding to inform the kernel.
> > >
> > > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > > ---
> > >   Documentation/devicetree/bindings/arm/coresight.txt | 3 +++
> > >   1 file changed, 3 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> > > index fcc3bacfd8bc..7cbdb7893af8 100644
> > > --- a/Documentation/devicetree/bindings/arm/coresight.txt
> > > +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> > > @@ -92,6 +92,9 @@ its hardware characteristcs.
> > >     * arm,cp14: must be present if the system accesses ETM/PTM management
> > >       registers via co-processor 14.
> > > +   * arm,coresight-needs-save-restore: boolean. Indicates that software
> > > +     should save/restore state across power down.
> > > +
> >
> > Do you think we could be a bit more descriptive here about when people could add
> > it to the DT ? Here we don't mention when someone should use this property and
> > it may be added to platforms where it may be absolutely unnecessary. How about :
> >
> > "Indicates that the hardware implementation may not honor the Powerup request
> > from the software and thus might loose the register context on CPU power
> > down (e.g, during CPUIdle). Software must save/restore the context during a
> > CPU power transition cycle."
>
> How about the following:
>
> "Indicates that the hardware will loose register context on CPU power down (e.g.
> CPUIdle), despite the TRCPDCR.PU bit being set."
>
> I'm keen to avoid making suggestions about what the kernel will do when it sees
> this flag and thus prefer to focus on describing what the hardware does. So I
> dropped your last sentence. However the name of the flag still implies policy
> which I don't like.
>
> I also changed the 'may not honor' wording, I'm not sure if this is really the
> case or if the spec is open to interpretation.
>
> It would great for this wording to also apply to other CS components though I
> haven't investigated if these have a PU bit or something different.

Exactly - the definition needs to be broad enough to apply to other CS
components.  Mike what do you think would be appropriate for CTIs?

>
> Thanks,
>
> Andrew Murray
>
> >
> > Cheers
> > Suzuki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states
  2019-08-02 10:54   ` Suzuki K Poulose
@ 2019-08-14  9:12     ` Andrew Murray
  0 siblings, 0 replies; 27+ messages in thread
From: Andrew Murray @ 2019-08-14  9:12 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: Al.Grant, mathieu.poirier, alexander.shishkin, coresight,
	leo.yan, Sudeep.Holla, linux-arm-kernel, mike.leach

On Fri, Aug 02, 2019 at 11:54:12AM +0100, Suzuki K Poulose wrote:
> 
> 
> On 30/07/2019 13:51, Andrew Murray wrote:
> > Some hardware will ignore bit TRCPDCR.PU which is used to signal
> > to hardware that power should not be removed from the trace unit.
> > Let's mitigate against this by conditionally saving and restoring
> > the trace unit state when the CPU enters low power states.
> > 
> > This patchset introduces a firmware property named
> > 'arm,coresight-needs-save-restore' - when this is present the
> > hardware state will be conditionally saved and restored.
> > 
> > A module parameter 'pm_save_enable' is also introduced which can
> > be configured to override the firmware property. This can be set
> > to never allow save/restore, to conditionally allow it, or to
> > do as the firmware indicates (default).
> > 
> > We avoid saving the hardware state when coresight isn't in use
> > to reduce PM latency - we can't determine this by reading the
> > claim tags (TRCCLAIMCLR) as these are 'trace' registers which need
> > power and clocking, something we can't easily provide in the PM
> > context. Therefore we rely on the existing drvdata->mode internal
> > state that is set when self-hosted coresight is used (and powered).
> > 
> > As we do not have a simple way of determining if an external agent
> > is using coresight, we don't save/restore for this use case.
> > 
> > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > ---
> >   drivers/hwtracing/coresight/coresight-etm4x.c | 322 ++++++++++++++++++
> >   drivers/hwtracing/coresight/coresight-etm4x.h |  64 ++++
> >   2 files changed, 386 insertions(+)
> > 
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> > index a128b5063f46..30f118792289 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> 
> 
> > +static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
> > +			      void *v)
> > +{
> > +	struct etmv4_drvdata *drvdata;
> > +	unsigned int cpu = smp_processor_id();
> > +
> > +	if (!etmdrvdata[cpu])
> > +		return 0;
> > +
> > +	drvdata = etmdrvdata[cpu];
> > +
> > +	if (!drvdata->save_state)
> > +		return NOTIFY_OK;
> > +
> > +	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
> > +		return NOTIFY_BAD;
> 
> minor nit: you may skip the second call to smp_processor_id() as this is called
> on from non-preemptible context.
> 
> > +
> > +	switch (cmd) {
> > +	case CPU_PM_ENTER:
> > +		/* save the state if self-hosted coresight is in use */
> > +		if (local_read(&drvdata->mode))
> > +			if (etm4_cpu_save(drvdata))
> > +				return NOTIFY_BAD;
> > +		break;
> > +	case CPU_PM_EXIT:
> > +	case CPU_PM_ENTER_FAILED:
> > +		/* trcclaimset is set when there is state to restore */
> > +		if (drvdata->state_needs_restore)
> > +			etm4_cpu_restore(drvdata);
> > +		break;
> > +	default:
> > +		return NOTIFY_DONE;
> > +	}
> > +
> > +	return NOTIFY_OK;
> > +}
> > +
> 
> 
> > +static void etm4_cpu_pm_unregister(void)
> > +{
> > +	cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
> > +}
> > +#else
> > +static int etm4_cpu_pm_register(void) { return 0; }
> > +static void etm4_cpu_pm_unregister(void) { }
> > +#endif
> > +
> > +static inline bool etm4_needs_save_restore(struct device *dev)
> > +{
> > +	return fwnode_property_present(dev->fwnode,
> 
> nit: It may be safe to use dev_fwnode(dev), instead of dev->fwnode. But I
> see a lot of existing users of dev->fwnode. Not sure it does have an impact.
> 
> Looks fine to me ,
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>

Thanks - I'll make these changes.

Andrew Murray
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-08-04 13:13       ` Mathieu Poirier
@ 2019-08-14 10:01         ` Andrew Murray
  2019-08-14 11:06           ` Mike Leach
  0 siblings, 1 reply; 27+ messages in thread
From: Andrew Murray @ 2019-08-14 10:01 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Al Grant, Suzuki K Poulose, Alexander Shishkin, Coresight ML,
	Sudeep Holla, Leo Yan, linux-arm-kernel, Mike Leach

On Sun, Aug 04, 2019 at 07:13:45AM -0600, Mathieu Poirier wrote:
> On Fri, 2 Aug 2019 at 08:37, Andrew Murray <andrew.murray@arm.com> wrote:
> >
> > On Fri, Aug 02, 2019 at 11:40:54AM +0100, Suzuki K Poulose wrote:
> > > Hi Andrew,
> > >
> > > On 30/07/2019 13:51, Andrew Murray wrote:
> > > > Some coresight components, because of choices made during hardware
> > > > integration, require their state to be saved and restored across CPU low
> > > > power states.
> > > >
> > > > The software has no reliable method of detecting when save/restore is
> > > > required thus let's add a binding to inform the kernel.
> > > >
> > > > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > > > ---
> > > >   Documentation/devicetree/bindings/arm/coresight.txt | 3 +++
> > > >   1 file changed, 3 insertions(+)
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> > > > index fcc3bacfd8bc..7cbdb7893af8 100644
> > > > --- a/Documentation/devicetree/bindings/arm/coresight.txt
> > > > +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> > > > @@ -92,6 +92,9 @@ its hardware characteristcs.
> > > >     * arm,cp14: must be present if the system accesses ETM/PTM management
> > > >       registers via co-processor 14.
> > > > +   * arm,coresight-needs-save-restore: boolean. Indicates that software
> > > > +     should save/restore state across power down.
> > > > +
> > >
> > > Do you think we could be a bit more descriptive here about when people could add
> > > it to the DT ? Here we don't mention when someone should use this property and
> > > it may be added to platforms where it may be absolutely unnecessary. How about :
> > >
> > > "Indicates that the hardware implementation may not honor the Powerup request
> > > from the software and thus might loose the register context on CPU power
> > > down (e.g, during CPUIdle). Software must save/restore the context during a
> > > CPU power transition cycle."
> >
> > How about the following:
> >
> > "Indicates that the hardware will loose register context on CPU power down (e.g.
> > CPUIdle), despite the TRCPDCR.PU bit being set."
> >
> > I'm keen to avoid making suggestions about what the kernel will do when it sees
> > this flag and thus prefer to focus on describing what the hardware does. So I
> > dropped your last sentence. However the name of the flag still implies policy
> > which I don't like.
> >
> > I also changed the 'may not honor' wording, I'm not sure if this is really the
> > case or if the spec is open to interpretation.
> >
> > It would great for this wording to also apply to other CS components though I
> > haven't investigated if these have a PU bit or something different.
> 
> Exactly - the definition needs to be broad enough to apply to other CS
> components.  Mike what do you think would be appropriate for CTIs?

How about we keep this short and simple:

* arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
  will lose register context on CPU power down (e.g. CPUIdle).

I could have added something like "... despite TRCPDCR.PU being set", or to
apply more generically: "... despite available register controls being set to
prevent such context loss". However whilst these are more informative - they
elude to some of reasons as to why context is lost and as we cannot be
exhaustive I'd rather not give a limited example.

However if a longer explaination is required:

* arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
  will lose register context on CPU power down (e.g. CPUIdle). An example of
  where this may be needed are systems which contain a coresight component and
  CPU in the same power domain. When the CPU powers down the coresight
  component also powers down and loses its context.

Any objections/preference? :)

Thanks,

Andrew Murray

> 
> >
> > Thanks,
> >
> > Andrew Murray
> >
> > >
> > > Cheers
> > > Suzuki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-08-14 10:01         ` Andrew Murray
@ 2019-08-14 11:06           ` Mike Leach
  2019-08-14 12:35             ` Suzuki K Poulose
  0 siblings, 1 reply; 27+ messages in thread
From: Mike Leach @ 2019-08-14 11:06 UTC (permalink / raw)
  To: Andrew Murray
  Cc: Al Grant, Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin,
	Coresight ML, Leo Yan, Sudeep Holla, linux-arm-kernel

Hi,

On Wed, 14 Aug 2019 at 11:01, Andrew Murray <andrew.murray@arm.com> wrote:
>
> On Sun, Aug 04, 2019 at 07:13:45AM -0600, Mathieu Poirier wrote:
> > On Fri, 2 Aug 2019 at 08:37, Andrew Murray <andrew.murray@arm.com> wrote:
> > >
> > > On Fri, Aug 02, 2019 at 11:40:54AM +0100, Suzuki K Poulose wrote:
> > > > Hi Andrew,
> > > >
> > > > On 30/07/2019 13:51, Andrew Murray wrote:
> > > > > Some coresight components, because of choices made during hardware
> > > > > integration, require their state to be saved and restored across CPU low
> > > > > power states.
> > > > >
> > > > > The software has no reliable method of detecting when save/restore is
> > > > > required thus let's add a binding to inform the kernel.
> > > > >
> > > > > Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> > > > > ---
> > > > >   Documentation/devicetree/bindings/arm/coresight.txt | 3 +++
> > > > >   1 file changed, 3 insertions(+)
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> > > > > index fcc3bacfd8bc..7cbdb7893af8 100644
> > > > > --- a/Documentation/devicetree/bindings/arm/coresight.txt
> > > > > +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> > > > > @@ -92,6 +92,9 @@ its hardware characteristcs.
> > > > >     * arm,cp14: must be present if the system accesses ETM/PTM management
> > > > >       registers via co-processor 14.
> > > > > +   * arm,coresight-needs-save-restore: boolean. Indicates that software
> > > > > +     should save/restore state across power down.
> > > > > +
> > > >
> > > > Do you think we could be a bit more descriptive here about when people could add
> > > > it to the DT ? Here we don't mention when someone should use this property and
> > > > it may be added to platforms where it may be absolutely unnecessary. How about :
> > > >
> > > > "Indicates that the hardware implementation may not honor the Powerup request
> > > > from the software and thus might loose the register context on CPU power
> > > > down (e.g, during CPUIdle). Software must save/restore the context during a
> > > > CPU power transition cycle."
> > >
> > > How about the following:
> > >
> > > "Indicates that the hardware will loose register context on CPU power down (e.g.
> > > CPUIdle), despite the TRCPDCR.PU bit being set."
> > >
> > > I'm keen to avoid making suggestions about what the kernel will do when it sees
> > > this flag and thus prefer to focus on describing what the hardware does. So I
> > > dropped your last sentence. However the name of the flag still implies policy
> > > which I don't like.
> > >
> > > I also changed the 'may not honor' wording, I'm not sure if this is really the
> > > case or if the spec is open to interpretation.
> > >
> > > It would great for this wording to also apply to other CS components though I
> > > haven't investigated if these have a PU bit or something different.
> >
> > Exactly - the definition needs to be broad enough to apply to other CS
> > components.  Mike what do you think would be appropriate for CTIs?
>
CTIs have no power control at all - i.e. no PU bit to request we stay
up - and reside in the debug power domain. So they are coupled to the
CS/CPU/ETM/ power domains and reliant on outside forces to request
power.
The expectation is that for a PE bound CTI, if debug is powered then
it will be fully powered - so an ETM with PU respected, or the
external debug logic with DBGNOPWRDWN respected should be sufficient
for CTI to stay alive.

> How about we keep this short and simple:
>
> * arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
>   will lose register context on CPU power down (e.g. CPUIdle).
>

So the above name is generic enough to encompass the CTI as well.

> I could have added something like "... despite TRCPDCR.PU being set", or to
> apply more generically: "... despite available register controls being set to
> prevent such context loss". However whilst these are more informative - they
> elude to some of reasons as to why context is lost and as we cannot be
> exhaustive I'd rather not give a limited example.
>
> However if a longer explaination is required:
>
> * arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
>   will lose register context on CPU power down (e.g. CPUIdle). An example of
>   where this may be needed are systems which contain a coresight component and
>   CPU in the same power domain. When the CPU powers down the coresight
>   component also powers down and loses its context.
>
> Any objections/preference? :)
>

Don't really care about length of explanation - but shouldn't mention
ETM specific features.

Mike

> Thanks,
>
> Andrew Murray
>
> >
> > >
> > > Thanks,
> > >
> > > Andrew Murray
> > >
> > > >
> > > > Cheers
> > > > Suzuki



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-08-14 11:06           ` Mike Leach
@ 2019-08-14 12:35             ` Suzuki K Poulose
  2019-08-14 12:49               ` Andrew Murray
  2019-08-14 14:20               ` Mike Leach
  0 siblings, 2 replies; 27+ messages in thread
From: Suzuki K Poulose @ 2019-08-14 12:35 UTC (permalink / raw)
  To: mike.leach, andrew.murray
  Cc: Al.Grant, mathieu.poirier, alexander.shishkin, coresight,
	Sudeep.Holla, leo.yan, linux-arm-kernel

Hi Mike,

On 14/08/2019 12:06, Mike Leach wrote:
> Hi,
> 
> On Wed, 14 Aug 2019 at 11:01, Andrew Murray <andrew.murray@arm.com> wrote:
>>
>> On Sun, Aug 04, 2019 at 07:13:45AM -0600, Mathieu Poirier wrote:
>>> On Fri, 2 Aug 2019 at 08:37, Andrew Murray <andrew.murray@arm.com> wrote:
>>>>
>>>> On Fri, Aug 02, 2019 at 11:40:54AM +0100, Suzuki K Poulose wrote:
>>>>> Hi Andrew,
>>>>>
>>>>> On 30/07/2019 13:51, Andrew Murray wrote:
>>>>>> Some coresight components, because of choices made during hardware
>>>>>> integration, require their state to be saved and restored across CPU low
>>>>>> power states.

...

>>>>>> --- a/Documentation/devicetree/bindings/arm/coresight.txt
>>>>>> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
>>>>>> @@ -92,6 +92,9 @@ its hardware characteristcs.
>>>>>>      * arm,cp14: must be present if the system accesses ETM/PTM management
>>>>>>        registers via co-processor 14.
>>>>>> +   * arm,coresight-needs-save-restore: boolean. Indicates that software
>>>>>> +     should save/restore state across power down.
>>>>>> +
>>>>>
>>>>> Do you think we could be a bit more descriptive here about when people could add
>>>>> it to the DT ? Here we don't mention when someone should use this property and
>>>>> it may be added to platforms where it may be absolutely unnecessary. How about :
>>>>>
>>>>> "Indicates that the hardware implementation may not honor the Powerup request
>>>>> from the software and thus might loose the register context on CPU power
>>>>> down (e.g, during CPUIdle). Software must save/restore the context during a
>>>>> CPU power transition cycle."
>>>>
>>>> How about the following:
>>>>
>>>> "Indicates that the hardware will loose register context on CPU power down (e.g.
>>>> CPUIdle), despite the TRCPDCR.PU bit being set."
>>>>
>>>> I'm keen to avoid making suggestions about what the kernel will do when it sees
>>>> this flag and thus prefer to focus on describing what the hardware does. So I
>>>> dropped your last sentence. However the name of the flag still implies policy
>>>> which I don't like.
>>>>
>>>> I also changed the 'may not honor' wording, I'm not sure if this is really the
>>>> case or if the spec is open to interpretation.
>>>>
>>>> It would great for this wording to also apply to other CS components though I
>>>> haven't investigated if these have a PU bit or something different.
>>>
>>> Exactly - the definition needs to be broad enough to apply to other CS
>>> components.  Mike what do you think would be appropriate for CTIs?
>>
> CTIs have no power control at all - i.e. no PU bit to request we stay
> up - and reside in the debug power domain. So they are coupled to the
> CS/CPU/ETM/ power domains and reliant on outside forces to request
> power.
> The expectation is that for a PE bound CTI, if debug is powered then
> it will be fully powered - so an ETM with PU respected, or the
> external debug logic with DBGNOPWRDWN respected should be sufficient
> for CTI to stay alive.

I am trying to understand why we need this property for CTI.
Don't we always need to save-restore the CTI controls on a CPU_DOWN for the
associated CTI ? Since it may not be really tied to an ETM (e.g, if the CTI is
purely used to handle CPU triggers, PMU etc,). If that is the case, do we need
this property for CTI at all ?

> 
>> How about we keep this short and simple:
>>
>> * arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware

nit: s/loses/looses ?

>>    will lose register context on CPU power down (e.g. CPUIdle).
>>
> 
> So the above name is generic enough to encompass the CTI as well.
> 
>> I could have added something like "... despite TRCPDCR.PU being set", or to
>> apply more generically: "... despite available register controls being set to
>> prevent such context loss". However whilst these are more informative - they
>> elude to some of reasons as to why context is lost and as we cannot be
>> exhaustive I'd rather not give a limited example.
>>
>> However if a longer explaination is required:
>>
>> * arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
>>    will lose register context on CPU power down (e.g. CPUIdle). An example of
>>    where this may be needed are systems which contain a coresight component and
>>    CPU in the same power domain. When the CPU powers down the coresight
>>    component also powers down and loses its context.

This looks fine for me. But I am trying to understand the rationale behind
using this for CTI

Suzuki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-08-14 12:35             ` Suzuki K Poulose
@ 2019-08-14 12:49               ` Andrew Murray
  2019-08-14 14:20               ` Mike Leach
  1 sibling, 0 replies; 27+ messages in thread
From: Andrew Murray @ 2019-08-14 12:49 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: Al.Grant, mathieu.poirier, alexander.shishkin, coresight,
	leo.yan, Sudeep.Holla, linux-arm-kernel, mike.leach

On Wed, Aug 14, 2019 at 01:35:27PM +0100, Suzuki K Poulose wrote:
> Hi Mike,
> 
> On 14/08/2019 12:06, Mike Leach wrote:
> > Hi,
> > 
> > On Wed, 14 Aug 2019 at 11:01, Andrew Murray <andrew.murray@arm.com> wrote:
> > > 
> > > On Sun, Aug 04, 2019 at 07:13:45AM -0600, Mathieu Poirier wrote:
> > > > On Fri, 2 Aug 2019 at 08:37, Andrew Murray <andrew.murray@arm.com> wrote:
> > > > > 
> > > > > On Fri, Aug 02, 2019 at 11:40:54AM +0100, Suzuki K Poulose wrote:
> > > > > > Hi Andrew,
> > > > > > 
> > > > > > On 30/07/2019 13:51, Andrew Murray wrote:
> > > > > > > Some coresight components, because of choices made during hardware
> > > > > > > integration, require their state to be saved and restored across CPU low
> > > > > > > power states.
> 
> ...
> 
> > > > > > > --- a/Documentation/devicetree/bindings/arm/coresight.txt
> > > > > > > +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> > > > > > > @@ -92,6 +92,9 @@ its hardware characteristcs.
> > > > > > >      * arm,cp14: must be present if the system accesses ETM/PTM management
> > > > > > >        registers via co-processor 14.
> > > > > > > +   * arm,coresight-needs-save-restore: boolean. Indicates that software
> > > > > > > +     should save/restore state across power down.
> > > > > > > +
> > > > > > 
> > > > > > Do you think we could be a bit more descriptive here about when people could add
> > > > > > it to the DT ? Here we don't mention when someone should use this property and
> > > > > > it may be added to platforms where it may be absolutely unnecessary. How about :
> > > > > > 
> > > > > > "Indicates that the hardware implementation may not honor the Powerup request
> > > > > > from the software and thus might loose the register context on CPU power
> > > > > > down (e.g, during CPUIdle). Software must save/restore the context during a
> > > > > > CPU power transition cycle."
> > > > > 
> > > > > How about the following:
> > > > > 
> > > > > "Indicates that the hardware will loose register context on CPU power down (e.g.
> > > > > CPUIdle), despite the TRCPDCR.PU bit being set."
> > > > > 
> > > > > I'm keen to avoid making suggestions about what the kernel will do when it sees
> > > > > this flag and thus prefer to focus on describing what the hardware does. So I
> > > > > dropped your last sentence. However the name of the flag still implies policy
> > > > > which I don't like.
> > > > > 
> > > > > I also changed the 'may not honor' wording, I'm not sure if this is really the
> > > > > case or if the spec is open to interpretation.
> > > > > 
> > > > > It would great for this wording to also apply to other CS components though I
> > > > > haven't investigated if these have a PU bit or something different.
> > > > 
> > > > Exactly - the definition needs to be broad enough to apply to other CS
> > > > components.  Mike what do you think would be appropriate for CTIs?
> > > 
> > CTIs have no power control at all - i.e. no PU bit to request we stay
> > up - and reside in the debug power domain. So they are coupled to the
> > CS/CPU/ETM/ power domains and reliant on outside forces to request
> > power.
> > The expectation is that for a PE bound CTI, if debug is powered then
> > it will be fully powered - so an ETM with PU respected, or the
> > external debug logic with DBGNOPWRDWN respected should be sufficient
> > for CTI to stay alive.
> 
> I am trying to understand why we need this property for CTI.
> Don't we always need to save-restore the CTI controls on a CPU_DOWN for the
> associated CTI ? Since it may not be really tied to an ETM (e.g, if the CTI is
> purely used to handle CPU triggers, PMU etc,). If that is the case, do we need
> this property for CTI at all ?
> 
> > 
> > > How about we keep this short and simple:
> > > 
> > > * arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
> 
> nit: s/loses/looses ?

Given that lose refers to missing something and loose refers to something not fitting
well, I'd have thought the pural is loses. Though I've now looked at these words for
too long and nothing makes sense any more... 

> 
> > >    will lose register context on CPU power down (e.g. CPUIdle).
> > > 
> > 
> > So the above name is generic enough to encompass the CTI as well.
> > 
> > > I could have added something like "... despite TRCPDCR.PU being set", or to
> > > apply more generically: "... despite available register controls being set to
> > > prevent such context loss". However whilst these are more informative - they
> > > elude to some of reasons as to why context is lost and as we cannot be
> > > exhaustive I'd rather not give a limited example.
> > > 
> > > However if a longer explaination is required:
> > > 
> > > * arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
> > >    will lose register context on CPU power down (e.g. CPUIdle). An example of
> > >    where this may be needed are systems which contain a coresight component and
> > >    CPU in the same power domain. When the CPU powers down the coresight
> > >    component also powers down and loses its context.
> 
> This looks fine for me. But I am trying to understand the rationale behind
> using this for CTI

Thanks.

Thanks,

Andrew Murray

> 
> Suzuki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore
  2019-08-14 12:35             ` Suzuki K Poulose
  2019-08-14 12:49               ` Andrew Murray
@ 2019-08-14 14:20               ` Mike Leach
  1 sibling, 0 replies; 27+ messages in thread
From: Mike Leach @ 2019-08-14 14:20 UTC (permalink / raw)
  To: Suzuki K Poulose
  Cc: Al Grant, Mathieu Poirier, Alexander Shishkin, Coresight ML,
	Sudeep Holla, Leo Yan, Andrew Murray, linux-arm-kernel

Hi Suzuki,

On Wed, 14 Aug 2019 at 13:35, Suzuki K Poulose <suzuki.poulose@arm.com> wrote:
>
> Hi Mike,
>
> On 14/08/2019 12:06, Mike Leach wrote:
> > Hi,
> >
> > On Wed, 14 Aug 2019 at 11:01, Andrew Murray <andrew.murray@arm.com> wrote:
> >>
> >> On Sun, Aug 04, 2019 at 07:13:45AM -0600, Mathieu Poirier wrote:
> >>> On Fri, 2 Aug 2019 at 08:37, Andrew Murray <andrew.murray@arm.com> wrote:
> >>>>
> >>>> On Fri, Aug 02, 2019 at 11:40:54AM +0100, Suzuki K Poulose wrote:
> >>>>> Hi Andrew,
> >>>>>
> >>>>> On 30/07/2019 13:51, Andrew Murray wrote:
> >>>>>> Some coresight components, because of choices made during hardware
> >>>>>> integration, require their state to be saved and restored across CPU low
> >>>>>> power states.
>
> ...
>
> >>>>>> --- a/Documentation/devicetree/bindings/arm/coresight.txt
> >>>>>> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> >>>>>> @@ -92,6 +92,9 @@ its hardware characteristcs.
> >>>>>>      * arm,cp14: must be present if the system accesses ETM/PTM management
> >>>>>>        registers via co-processor 14.
> >>>>>> +   * arm,coresight-needs-save-restore: boolean. Indicates that software
> >>>>>> +     should save/restore state across power down.
> >>>>>> +
> >>>>>
> >>>>> Do you think we could be a bit more descriptive here about when people could add
> >>>>> it to the DT ? Here we don't mention when someone should use this property and
> >>>>> it may be added to platforms where it may be absolutely unnecessary. How about :
> >>>>>
> >>>>> "Indicates that the hardware implementation may not honor the Powerup request
> >>>>> from the software and thus might loose the register context on CPU power
> >>>>> down (e.g, during CPUIdle). Software must save/restore the context during a
> >>>>> CPU power transition cycle."
> >>>>
> >>>> How about the following:
> >>>>
> >>>> "Indicates that the hardware will loose register context on CPU power down (e.g.
> >>>> CPUIdle), despite the TRCPDCR.PU bit being set."
> >>>>
> >>>> I'm keen to avoid making suggestions about what the kernel will do when it sees
> >>>> this flag and thus prefer to focus on describing what the hardware does. So I
> >>>> dropped your last sentence. However the name of the flag still implies policy
> >>>> which I don't like.
> >>>>
> >>>> I also changed the 'may not honor' wording, I'm not sure if this is really the
> >>>> case or if the spec is open to interpretation.
> >>>>
> >>>> It would great for this wording to also apply to other CS components though I
> >>>> haven't investigated if these have a PU bit or something different.
> >>>
> >>> Exactly - the definition needs to be broad enough to apply to other CS
> >>> components.  Mike what do you think would be appropriate for CTIs?
> >>
> > CTIs have no power control at all - i.e. no PU bit to request we stay
> > up - and reside in the debug power domain. So they are coupled to the
> > CS/CPU/ETM/ power domains and reliant on outside forces to request
> > power.
> > The expectation is that for a PE bound CTI, if debug is powered then
> > it will be fully powered - so an ETM with PU respected, or the
> > external debug logic with DBGNOPWRDWN respected should be sufficient
> > for CTI to stay alive.
>
> I am trying to understand why we need this property for CTI.
> Don't we always need to save-restore the CTI controls on a CPU_DOWN for the
> associated CTI ? Since it may not be really tied to an ETM (e.g, if the CTI is
> purely used to handle CPU triggers, PMU etc,). If that is the case, do we need
> this property for CTI at all ?
>

CTI will be in use for one of two reasons:-
1) External Debug - in which case the DBGNOPOWERDOWN bit should be set
and the debug domain remains powered.
2) Trace (self hosted or external) - so we have an ETM and PU is set
and the debug power domain remains powered.

In these ideal cases we never need to save and restore as the debug
power domain remains powered.

Now in this phase of development we are disregarding external debug
and trace. So we are only in self hosted trace mode - which is
probably the most common use case for a linux system.

Therefore the CTI will only be in use if there is an ETM tracing self
hosted. If PU is not working and the parameter is set then we know we
need to hook  CPUIdle notifications and save and restore (thought in
the case of CTI it is really restore only for self hosted as there are
no dynamic registers.). If we are not saving and restoring then we do
not need to register for CPUIdle notifiers (which like hotplug need to
be centralised, not re-implemented in each and every driver), saving
some latency.

The architecture specifically precludes using the CTI PMU trigger to
the generic CTI PE interrupt - so the PMU overflow trigger will only
ever be used to activate some debug event (e.g. debug halt, trace halt
etc).

Regards

Mike

> >
> >> How about we keep this short and simple:
> >>
> >> * arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
>
> nit: s/loses/looses ?
>
> >>    will lose register context on CPU power down (e.g. CPUIdle).
> >>
> >
> > So the above name is generic enough to encompass the CTI as well.
> >
> >> I could have added something like "... despite TRCPDCR.PU being set", or to
> >> apply more generically: "... despite available register controls being set to
> >> prevent such context loss". However whilst these are more informative - they
> >> elude to some of reasons as to why context is lost and as we cannot be
> >> exhaustive I'd rather not give a limited example.
> >>
> >> However if a longer explaination is required:
> >>
> >> * arm,coresight-loses-context-with-cpu : boolean. Indicates that the hardware
> >>    will lose register context on CPU power down (e.g. CPUIdle). An example of
> >>    where this may be needed are systems which contain a coresight component and
> >>    CPU in the same power domain. When the CPU powers down the coresight
> >>    component also powers down and loses its context.
>
> This looks fine for me. But I am trying to understand the rationale behind
> using this for CTI
>
> Suzuki



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2019-08-14 14:20 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-30 12:51 [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Andrew Murray
2019-07-30 12:51 ` [PATCH v4 1/6] coresight: etm4x: remove superfluous setting of os_unlock Andrew Murray
2019-07-30 12:51 ` [PATCH v4 2/6] coresight: etm4x: use explicit barriers on enable/disable Andrew Murray
2019-08-01 13:31   ` Sasha Levin
2019-08-01 14:48     ` Mathieu Poirier
2019-08-02 18:08   ` Sasha Levin
2019-07-30 12:51 ` [PATCH v4 3/6] coresight: etm4x: use module_param instead of module_param_named Andrew Murray
2019-08-02 10:23   ` Suzuki K Poulose
2019-07-30 12:51 ` [PATCH v4 4/6] coresight: etm4x: improve clarity of etm4_os_unlock comment Andrew Murray
2019-07-30 12:51 ` [PATCH v4 5/6] coresight: etm4x: save/restore state across CPU low power states Andrew Murray
2019-07-30 21:16   ` Mathieu Poirier
2019-07-30 21:45     ` Andrew Murray
2019-07-31  8:16       ` Mike Leach
2019-07-31  9:45         ` Andrew Murray
2019-08-02 10:54   ` Suzuki K Poulose
2019-08-14  9:12     ` Andrew Murray
2019-07-30 12:51 ` [PATCH v4 6/6] dt-bindings: arm: coresight: Add support for coresight-needs-save-restore Andrew Murray
2019-08-02 10:40   ` Suzuki K Poulose
2019-08-02 14:37     ` Andrew Murray
2019-08-04 13:13       ` Mathieu Poirier
2019-08-14 10:01         ` Andrew Murray
2019-08-14 11:06           ` Mike Leach
2019-08-14 12:35             ` Suzuki K Poulose
2019-08-14 12:49               ` Andrew Murray
2019-08-14 14:20               ` Mike Leach
2019-07-30 20:12 ` [PATCH v4 0/6] coresight: etm4x: save/restore ETMv4 context across CPU low power states Mathieu Poirier
2019-07-30 21:46   ` Andrew Murray

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