2 * Copyright(C) 2016 Linaro Limited. All rights reserved.
3 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <linux/coresight.h>
19 #include <linux/dma-mapping.h>
20 #include "coresight-priv.h"
21 #include "coresight-tmc.h"
23 void tmc_etr_enable_hw(struct tmc_drvdata
*drvdata
)
27 /* Zero out the memory to help with debug */
28 memset(drvdata
->vaddr
, 0, drvdata
->size
);
30 CS_UNLOCK(drvdata
->base
);
32 /* Wait for TMCSReady bit to be set */
33 tmc_wait_for_tmcready(drvdata
);
35 writel_relaxed(drvdata
->size
/ 4, drvdata
->base
+ TMC_RSZ
);
36 writel_relaxed(TMC_MODE_CIRCULAR_BUFFER
, drvdata
->base
+ TMC_MODE
);
38 axictl
= readl_relaxed(drvdata
->base
+ TMC_AXICTL
);
39 axictl
|= TMC_AXICTL_WR_BURST_16
;
40 writel_relaxed(axictl
, drvdata
->base
+ TMC_AXICTL
);
41 axictl
&= ~TMC_AXICTL_SCT_GAT_MODE
;
42 writel_relaxed(axictl
, drvdata
->base
+ TMC_AXICTL
);
44 ~(TMC_AXICTL_PROT_CTL_B0
| TMC_AXICTL_PROT_CTL_B1
)) |
45 TMC_AXICTL_PROT_CTL_B1
;
46 writel_relaxed(axictl
, drvdata
->base
+ TMC_AXICTL
);
48 writel_relaxed(drvdata
->paddr
, drvdata
->base
+ TMC_DBALO
);
49 writel_relaxed(0x0, drvdata
->base
+ TMC_DBAHI
);
50 writel_relaxed(TMC_FFCR_EN_FMT
| TMC_FFCR_EN_TI
|
51 TMC_FFCR_FON_FLIN
| TMC_FFCR_FON_TRIG_EVT
|
52 TMC_FFCR_TRIGON_TRIGIN
,
53 drvdata
->base
+ TMC_FFCR
);
54 writel_relaxed(drvdata
->trigger_cntr
, drvdata
->base
+ TMC_TRG
);
55 tmc_enable_hw(drvdata
);
57 CS_LOCK(drvdata
->base
);
60 static void tmc_etr_dump_hw(struct tmc_drvdata
*drvdata
)
64 rwp
= readl_relaxed(drvdata
->base
+ TMC_RWP
);
65 val
= readl_relaxed(drvdata
->base
+ TMC_STS
);
67 /* How much memory do we still have */
69 drvdata
->buf
= drvdata
->vaddr
+ rwp
- drvdata
->paddr
;
71 drvdata
->buf
= drvdata
->vaddr
;
74 static void tmc_etr_disable_hw(struct tmc_drvdata
*drvdata
)
76 CS_UNLOCK(drvdata
->base
);
78 tmc_flush_and_stop(drvdata
);
80 * When operating in sysFS mode the content of the buffer needs to be
81 * read before the TMC is disabled.
83 if (local_read(&drvdata
->mode
) == CS_MODE_SYSFS
)
84 tmc_etr_dump_hw(drvdata
);
85 tmc_disable_hw(drvdata
);
87 CS_LOCK(drvdata
->base
);
90 static int tmc_enable_etr_sink_sysfs(struct coresight_device
*csdev
, u32 mode
)
96 void __iomem
*vaddr
= NULL
;
98 struct tmc_drvdata
*drvdata
= dev_get_drvdata(csdev
->dev
.parent
);
100 /* This shouldn't be happening */
101 if (WARN_ON(mode
!= CS_MODE_SYSFS
))
105 * If we don't have a buffer release the lock and allocate memory.
106 * Otherwise keep the lock and move along.
108 spin_lock_irqsave(&drvdata
->spinlock
, flags
);
109 if (!drvdata
->vaddr
) {
110 spin_unlock_irqrestore(&drvdata
->spinlock
, flags
);
113 * Contiguous memory can't be allocated while a spinlock is
114 * held. As such allocate memory here and free it if a buffer
115 * has already been allocated (from a previous session).
117 vaddr
= dma_alloc_coherent(drvdata
->dev
, drvdata
->size
,
122 /* Let's try again */
123 spin_lock_irqsave(&drvdata
->spinlock
, flags
);
126 if (drvdata
->reading
) {
131 val
= local_xchg(&drvdata
->mode
, mode
);
133 * In sysFS mode we can have multiple writers per sink. Since this
134 * sink is already enabled no memory is needed and the HW need not be
137 if (val
== CS_MODE_SYSFS
)
141 * If drvdata::buf == NULL, use the memory allocated above.
142 * Otherwise a buffer still exists from a previous session, so
145 if (drvdata
->buf
== NULL
) {
147 drvdata
->vaddr
= vaddr
;
148 drvdata
->paddr
= paddr
;
149 drvdata
->buf
= drvdata
->vaddr
;
152 memset(drvdata
->vaddr
, 0, drvdata
->size
);
154 tmc_etr_enable_hw(drvdata
);
156 spin_unlock_irqrestore(&drvdata
->spinlock
, flags
);
158 /* Free memory outside the spinlock if need be */
160 dma_free_coherent(drvdata
->dev
, drvdata
->size
, vaddr
, paddr
);
163 dev_info(drvdata
->dev
, "TMC-ETR enabled\n");
168 static int tmc_enable_etr_sink_perf(struct coresight_device
*csdev
, u32 mode
)
173 struct tmc_drvdata
*drvdata
= dev_get_drvdata(csdev
->dev
.parent
);
175 /* This shouldn't be happening */
176 if (WARN_ON(mode
!= CS_MODE_PERF
))
179 spin_lock_irqsave(&drvdata
->spinlock
, flags
);
180 if (drvdata
->reading
) {
185 val
= local_xchg(&drvdata
->mode
, mode
);
187 * In Perf mode there can be only one writer per sink. There
188 * is also no need to continue if the ETR is already operated
191 if (val
!= CS_MODE_DISABLED
) {
196 tmc_etr_enable_hw(drvdata
);
198 spin_unlock_irqrestore(&drvdata
->spinlock
, flags
);
203 static int tmc_enable_etr_sink(struct coresight_device
*csdev
, u32 mode
)
207 return tmc_enable_etr_sink_sysfs(csdev
, mode
);
209 return tmc_enable_etr_sink_perf(csdev
, mode
);
212 /* We shouldn't be here */
216 static void tmc_disable_etr_sink(struct coresight_device
*csdev
)
220 struct tmc_drvdata
*drvdata
= dev_get_drvdata(csdev
->dev
.parent
);
222 spin_lock_irqsave(&drvdata
->spinlock
, flags
);
223 if (drvdata
->reading
) {
224 spin_unlock_irqrestore(&drvdata
->spinlock
, flags
);
228 val
= local_xchg(&drvdata
->mode
, CS_MODE_DISABLED
);
229 /* Disable the TMC only if it needs to */
230 if (val
!= CS_MODE_DISABLED
)
231 tmc_etr_disable_hw(drvdata
);
233 spin_unlock_irqrestore(&drvdata
->spinlock
, flags
);
235 dev_info(drvdata
->dev
, "TMC-ETR disabled\n");
238 static const struct coresight_ops_sink tmc_etr_sink_ops
= {
239 .enable
= tmc_enable_etr_sink
,
240 .disable
= tmc_disable_etr_sink
,
243 const struct coresight_ops tmc_etr_cs_ops
= {
244 .sink_ops
= &tmc_etr_sink_ops
,
247 int tmc_read_prepare_etr(struct tmc_drvdata
*drvdata
)
253 /* config types are set a boot time and never change */
254 if (WARN_ON_ONCE(drvdata
->config_type
!= TMC_CONFIG_TYPE_ETR
))
257 spin_lock_irqsave(&drvdata
->spinlock
, flags
);
258 if (drvdata
->reading
) {
263 val
= local_read(&drvdata
->mode
);
264 /* Don't interfere if operated from Perf */
265 if (val
== CS_MODE_PERF
) {
270 /* If drvdata::buf is NULL the trace data has been read already */
271 if (drvdata
->buf
== NULL
) {
276 /* Disable the TMC if need be */
277 if (val
== CS_MODE_SYSFS
)
278 tmc_etr_disable_hw(drvdata
);
280 drvdata
->reading
= true;
282 spin_unlock_irqrestore(&drvdata
->spinlock
, flags
);
287 int tmc_read_unprepare_etr(struct tmc_drvdata
*drvdata
)
291 void __iomem
*vaddr
= NULL
;
293 /* config types are set a boot time and never change */
294 if (WARN_ON_ONCE(drvdata
->config_type
!= TMC_CONFIG_TYPE_ETR
))
297 spin_lock_irqsave(&drvdata
->spinlock
, flags
);
299 /* RE-enable the TMC if need be */
300 if (local_read(&drvdata
->mode
) == CS_MODE_SYSFS
) {
302 * The trace run will continue with the same allocated trace
303 * buffer. The trace buffer is cleared in tmc_etr_enable_hw(),
304 * so we don't have to explicitly clear it. Also, since the
305 * tracer is still enabled drvdata::buf can't be NULL.
307 tmc_etr_enable_hw(drvdata
);
310 * The ETR is not tracing and the buffer was just read.
311 * As such prepare to free the trace buffer.
313 vaddr
= drvdata
->vaddr
;
314 paddr
= drvdata
->paddr
;
315 drvdata
->buf
= drvdata
->vaddr
= NULL
;
318 drvdata
->reading
= false;
319 spin_unlock_irqrestore(&drvdata
->spinlock
, flags
);
321 /* Free allocated memory out side of the spinlock */
323 dma_free_coherent(drvdata
->dev
, drvdata
->size
, vaddr
, paddr
);