blob: e67658fadac06f643835de3abd10156517c4bb0b [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001From 7150eac72ee0c2c7da03f53a90a871c3d6d4e538 Mon Sep 17 00:00:00 2001
2From: Suzuki K Poulose <suzuki.poulose@arm.com>
3Date: Tue, 14 Sep 2021 11:26:32 +0100
4Subject: [PATCH 1/2] coresight: etm4x: Save restore TRFCR_EL1
5
6When the CPU enters a low power mode, the TRFCR_EL1 contents could be
7reset. Thus we need to save/restore the TRFCR_EL1 along with the ETM4x
8registers to allow the tracing.
9
10The TRFCR related helpers are in a new header file, as we need to use
11them for TRBE in the later patches.
12
13Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
14Cc: Anshuman Khandual <anshuman.khandual@arm.com>
15Cc: Mike Leach <mike.leach@linaro.org>
16Cc: Leo Yan <leo.yan@linaro.org>
17Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
18Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
19Link: https://lore.kernel.org/r/20210914102641.1852544-2-suzuki.poulose@arm.com
20[Fixed cosmetic details]
21Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
22
23Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=937d3f58cacf377cab7c32e475e1ffa91d611dce]
24Signed-off-by: Davidson K <davidson.kumaresan@arm.com>
25---
26 .../coresight/coresight-etm4x-core.c | 43 +++++++++++++------
27 drivers/hwtracing/coresight/coresight-etm4x.h | 2 +
28 .../coresight/coresight-self-hosted-trace.h | 24 +++++++++++
29 3 files changed, 57 insertions(+), 12 deletions(-)
30 create mode 100644 drivers/hwtracing/coresight/coresight-self-hosted-trace.h
31
32diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
33index 90827077d2f9..b78080d169f8 100644
34--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
35+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
36@@ -39,6 +39,7 @@
37
38 #include "coresight-etm4x.h"
39 #include "coresight-etm-perf.h"
40+#include "coresight-self-hosted-trace.h"
41
42 static int boot_enable;
43 module_param(boot_enable, int, 0444);
44@@ -990,7 +991,7 @@ static void cpu_enable_tracing(struct etmv4_drvdata *drvdata)
45 if (is_kernel_in_hyp_mode())
46 trfcr |= TRFCR_EL2_CX;
47
48- write_sysreg_s(trfcr, SYS_TRFCR_EL1);
49+ write_trfcr(trfcr);
50 }
51
52 static void etm4_init_arch_data(void *info)
53@@ -1528,7 +1529,7 @@ static void etm4_init_trace_id(struct etmv4_drvdata *drvdata)
54 drvdata->trcid = coresight_get_trace_id(drvdata->cpu);
55 }
56
57-static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
58+static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
59 {
60 int i, ret = 0;
61 struct etmv4_save_state *state;
62@@ -1667,7 +1668,23 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
63 return ret;
64 }
65
66-static void etm4_cpu_restore(struct etmv4_drvdata *drvdata)
67+static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
68+{
69+ int ret = 0;
70+
71+ /* Save the TRFCR irrespective of whether the ETM is ON */
72+ if (drvdata->trfc)
73+ drvdata->save_trfcr = read_trfcr();
74+ /*
75+ * Save and restore the ETM Trace registers only if
76+ * the ETM is active.
77+ */
78+ if (local_read(&drvdata->mode) && drvdata->save_state)
79+ ret = __etm4_cpu_save(drvdata);
80+ return ret;
81+}
82+
83+static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
84 {
85 int i;
86 struct etmv4_save_state *state = drvdata->save_state;
87@@ -1763,6 +1780,14 @@ static void etm4_cpu_restore(struct etmv4_drvdata *drvdata)
88 etm4_cs_lock(drvdata, csa);
89 }
90
91+static void etm4_cpu_restore(struct etmv4_drvdata *drvdata)
92+{
93+ if (drvdata->trfc)
94+ write_trfcr(drvdata->save_trfcr);
95+ if (drvdata->state_needs_restore)
96+ __etm4_cpu_restore(drvdata);
97+}
98+
99 static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
100 void *v)
101 {
102@@ -1774,23 +1799,17 @@ static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
103
104 drvdata = etmdrvdata[cpu];
105
106- if (!drvdata->save_state)
107- return NOTIFY_OK;
108-
109 if (WARN_ON_ONCE(drvdata->cpu != cpu))
110 return NOTIFY_BAD;
111
112 switch (cmd) {
113 case CPU_PM_ENTER:
114- /* save the state if self-hosted coresight is in use */
115- if (local_read(&drvdata->mode))
116- if (etm4_cpu_save(drvdata))
117- return NOTIFY_BAD;
118+ if (etm4_cpu_save(drvdata))
119+ return NOTIFY_BAD;
120 break;
121 case CPU_PM_EXIT:
122 case CPU_PM_ENTER_FAILED:
123- if (drvdata->state_needs_restore)
124- etm4_cpu_restore(drvdata);
125+ etm4_cpu_restore(drvdata);
126 break;
127 default:
128 return NOTIFY_DONE;
129diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
130index e5b79bdb9851..82cba16b73a6 100644
131--- a/drivers/hwtracing/coresight/coresight-etm4x.h
132+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
133@@ -921,6 +921,7 @@ struct etmv4_save_state {
134 * @lpoverride: If the implementation can support low-power state over.
135 * @trfc: If the implementation supports Arm v8.4 trace filter controls.
136 * @config: structure holding configuration parameters.
137+ * @save_trfcr: Saved TRFCR_EL1 register during a CPU PM event.
138 * @save_state: State to be preserved across power loss
139 * @state_needs_restore: True when there is context to restore after PM exit
140 * @skip_power_up: Indicates if an implementation can skip powering up
141@@ -973,6 +974,7 @@ struct etmv4_drvdata {
142 bool lpoverride;
143 bool trfc;
144 struct etmv4_config config;
145+ u64 save_trfcr;
146 struct etmv4_save_state *save_state;
147 bool state_needs_restore;
148 bool skip_power_up;
149diff --git a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h
150new file mode 100644
151index 000000000000..303d71911870
152--- /dev/null
153+++ b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h
154@@ -0,0 +1,24 @@
155+/* SPDX-License-Identifier: GPL-2.0-only */
156+/*
157+ * Arm v8 Self-Hosted trace support.
158+ *
159+ * Copyright (C) 2021 ARM Ltd.
160+ */
161+
162+#ifndef __CORESIGHT_SELF_HOSTED_TRACE_H
163+#define __CORESIGHT_SELF_HOSTED_TRACE_H
164+
165+#include <asm/sysreg.h>
166+
167+static inline u64 read_trfcr(void)
168+{
169+ return read_sysreg_s(SYS_TRFCR_EL1);
170+}
171+
172+static inline void write_trfcr(u64 val)
173+{
174+ write_sysreg_s(val, SYS_TRFCR_EL1);
175+ isb();
176+}
177+
178+#endif /* __CORESIGHT_SELF_HOSTED_TRACE_H */
179--
1802.34.1
181