GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / hwtracing / coresight / coresight-tmc-etr.c
1 /*
2  * Copyright(C) 2016 Linaro Limited. All rights reserved.
3  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
4  *
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.
8  *
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
12  * more details.
13  *
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/>.
16  */
17
18 #include <linux/coresight.h>
19 #include <linux/dma-mapping.h>
20 #include "coresight-priv.h"
21 #include "coresight-tmc.h"
22
23 static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
24 {
25         u32 axictl, sts;
26
27         /* Zero out the memory to help with debug */
28         memset(drvdata->vaddr, 0, drvdata->size);
29
30         CS_UNLOCK(drvdata->base);
31
32         /* Wait for TMCSReady bit to be set */
33         tmc_wait_for_tmcready(drvdata);
34
35         writel_relaxed(drvdata->size / 4, drvdata->base + TMC_RSZ);
36         writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE);
37
38         axictl = readl_relaxed(drvdata->base + TMC_AXICTL);
39         axictl &= ~TMC_AXICTL_CLEAR_MASK;
40         axictl |= (TMC_AXICTL_PROT_CTL_B1 | TMC_AXICTL_WR_BURST_16);
41         axictl |= TMC_AXICTL_AXCACHE_OS;
42
43         if (tmc_etr_has_cap(drvdata, TMC_ETR_AXI_ARCACHE)) {
44                 axictl &= ~TMC_AXICTL_ARCACHE_MASK;
45                 axictl |= TMC_AXICTL_ARCACHE_OS;
46         }
47
48         writel_relaxed(axictl, drvdata->base + TMC_AXICTL);
49         tmc_write_dba(drvdata, drvdata->paddr);
50         /*
51          * If the TMC pointers must be programmed before the session,
52          * we have to set it properly (i.e, RRP/RWP to base address and
53          * STS to "not full").
54          */
55         if (tmc_etr_has_cap(drvdata, TMC_ETR_SAVE_RESTORE)) {
56                 tmc_write_rrp(drvdata, drvdata->paddr);
57                 tmc_write_rwp(drvdata, drvdata->paddr);
58                 sts = readl_relaxed(drvdata->base + TMC_STS) & ~TMC_STS_FULL;
59                 writel_relaxed(sts, drvdata->base + TMC_STS);
60         }
61
62         writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI |
63                        TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT |
64                        TMC_FFCR_TRIGON_TRIGIN,
65                        drvdata->base + TMC_FFCR);
66         writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG);
67         tmc_enable_hw(drvdata);
68
69         CS_LOCK(drvdata->base);
70 }
71
72 static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata)
73 {
74         const u32 *barrier;
75         u32 val;
76         u32 *temp;
77         u64 rwp;
78
79         rwp = tmc_read_rwp(drvdata);
80         val = readl_relaxed(drvdata->base + TMC_STS);
81
82         /*
83          * Adjust the buffer to point to the beginning of the trace data
84          * and update the available trace data.
85          */
86         if (val & TMC_STS_FULL) {
87                 drvdata->buf = drvdata->vaddr + rwp - drvdata->paddr;
88                 drvdata->len = drvdata->size;
89
90                 barrier = barrier_pkt;
91                 temp = (u32 *)drvdata->buf;
92
93                 while (*barrier) {
94                         *temp = *barrier;
95                         temp++;
96                         barrier++;
97                 }
98
99         } else {
100                 drvdata->buf = drvdata->vaddr;
101                 drvdata->len = rwp - drvdata->paddr;
102         }
103 }
104
105 static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
106 {
107         CS_UNLOCK(drvdata->base);
108
109         tmc_flush_and_stop(drvdata);
110         /*
111          * When operating in sysFS mode the content of the buffer needs to be
112          * read before the TMC is disabled.
113          */
114         if (drvdata->mode == CS_MODE_SYSFS)
115                 tmc_etr_dump_hw(drvdata);
116         tmc_disable_hw(drvdata);
117
118         CS_LOCK(drvdata->base);
119 }
120
121 static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
122 {
123         int ret = 0;
124         bool used = false;
125         unsigned long flags;
126         void __iomem *vaddr = NULL;
127         dma_addr_t paddr;
128         struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
129
130
131         /*
132          * If we don't have a buffer release the lock and allocate memory.
133          * Otherwise keep the lock and move along.
134          */
135         spin_lock_irqsave(&drvdata->spinlock, flags);
136         if (!drvdata->vaddr) {
137                 spin_unlock_irqrestore(&drvdata->spinlock, flags);
138
139                 /*
140                  * Contiguous  memory can't be allocated while a spinlock is
141                  * held.  As such allocate memory here and free it if a buffer
142                  * has already been allocated (from a previous session).
143                  */
144                 vaddr = dma_alloc_coherent(drvdata->dev, drvdata->size,
145                                            &paddr, GFP_KERNEL);
146                 if (!vaddr)
147                         return -ENOMEM;
148
149                 /* Let's try again */
150                 spin_lock_irqsave(&drvdata->spinlock, flags);
151         }
152
153         if (drvdata->reading) {
154                 ret = -EBUSY;
155                 goto out;
156         }
157
158         /*
159          * In sysFS mode we can have multiple writers per sink.  Since this
160          * sink is already enabled no memory is needed and the HW need not be
161          * touched.
162          */
163         if (drvdata->mode == CS_MODE_SYSFS)
164                 goto out;
165
166         /*
167          * If drvdata::buf == NULL, use the memory allocated above.
168          * Otherwise a buffer still exists from a previous session, so
169          * simply use that.
170          */
171         if (drvdata->buf == NULL) {
172                 used = true;
173                 drvdata->vaddr = vaddr;
174                 drvdata->paddr = paddr;
175                 drvdata->buf = drvdata->vaddr;
176         }
177
178         drvdata->mode = CS_MODE_SYSFS;
179         tmc_etr_enable_hw(drvdata);
180 out:
181         spin_unlock_irqrestore(&drvdata->spinlock, flags);
182
183         /* Free memory outside the spinlock if need be */
184         if (!used && vaddr)
185                 dma_free_coherent(drvdata->dev, drvdata->size, vaddr, paddr);
186
187         if (!ret)
188                 dev_info(drvdata->dev, "TMC-ETR enabled\n");
189
190         return ret;
191 }
192
193 static int tmc_enable_etr_sink_perf(struct coresight_device *csdev)
194 {
195         int ret = 0;
196         unsigned long flags;
197         struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
198
199         spin_lock_irqsave(&drvdata->spinlock, flags);
200         if (drvdata->reading) {
201                 ret = -EINVAL;
202                 goto out;
203         }
204
205         /*
206          * In Perf mode there can be only one writer per sink.  There
207          * is also no need to continue if the ETR is already operated
208          * from sysFS.
209          */
210         if (drvdata->mode != CS_MODE_DISABLED) {
211                 ret = -EINVAL;
212                 goto out;
213         }
214
215         drvdata->mode = CS_MODE_PERF;
216         tmc_etr_enable_hw(drvdata);
217 out:
218         spin_unlock_irqrestore(&drvdata->spinlock, flags);
219
220         return ret;
221 }
222
223 static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
224 {
225         switch (mode) {
226         case CS_MODE_SYSFS:
227                 return tmc_enable_etr_sink_sysfs(csdev);
228         case CS_MODE_PERF:
229                 return tmc_enable_etr_sink_perf(csdev);
230         }
231
232         /* We shouldn't be here */
233         return -EINVAL;
234 }
235
236 static void tmc_disable_etr_sink(struct coresight_device *csdev)
237 {
238         unsigned long flags;
239         struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
240
241         spin_lock_irqsave(&drvdata->spinlock, flags);
242         if (drvdata->reading) {
243                 spin_unlock_irqrestore(&drvdata->spinlock, flags);
244                 return;
245         }
246
247         /* Disable the TMC only if it needs to */
248         if (drvdata->mode != CS_MODE_DISABLED) {
249                 tmc_etr_disable_hw(drvdata);
250                 drvdata->mode = CS_MODE_DISABLED;
251         }
252
253         spin_unlock_irqrestore(&drvdata->spinlock, flags);
254
255         dev_info(drvdata->dev, "TMC-ETR disabled\n");
256 }
257
258 static const struct coresight_ops_sink tmc_etr_sink_ops = {
259         .enable         = tmc_enable_etr_sink,
260         .disable        = tmc_disable_etr_sink,
261 };
262
263 const struct coresight_ops tmc_etr_cs_ops = {
264         .sink_ops       = &tmc_etr_sink_ops,
265 };
266
267 int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
268 {
269         int ret = 0;
270         unsigned long flags;
271
272         /* config types are set a boot time and never change */
273         if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
274                 return -EINVAL;
275
276         spin_lock_irqsave(&drvdata->spinlock, flags);
277         if (drvdata->reading) {
278                 ret = -EBUSY;
279                 goto out;
280         }
281
282         /* Don't interfere if operated from Perf */
283         if (drvdata->mode == CS_MODE_PERF) {
284                 ret = -EINVAL;
285                 goto out;
286         }
287
288         /* If drvdata::buf is NULL the trace data has been read already */
289         if (drvdata->buf == NULL) {
290                 ret = -EINVAL;
291                 goto out;
292         }
293
294         /* Disable the TMC if need be */
295         if (drvdata->mode == CS_MODE_SYSFS)
296                 tmc_etr_disable_hw(drvdata);
297
298         drvdata->reading = true;
299 out:
300         spin_unlock_irqrestore(&drvdata->spinlock, flags);
301
302         return ret;
303 }
304
305 int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
306 {
307         unsigned long flags;
308         dma_addr_t paddr;
309         void __iomem *vaddr = NULL;
310
311         /* config types are set a boot time and never change */
312         if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
313                 return -EINVAL;
314
315         spin_lock_irqsave(&drvdata->spinlock, flags);
316
317         /* RE-enable the TMC if need be */
318         if (drvdata->mode == CS_MODE_SYSFS) {
319                 /*
320                  * The trace run will continue with the same allocated trace
321                  * buffer. The trace buffer is cleared in tmc_etr_enable_hw(),
322                  * so we don't have to explicitly clear it. Also, since the
323                  * tracer is still enabled drvdata::buf can't be NULL.
324                  */
325                 tmc_etr_enable_hw(drvdata);
326         } else {
327                 /*
328                  * The ETR is not tracing and the buffer was just read.
329                  * As such prepare to free the trace buffer.
330                  */
331                 vaddr = drvdata->vaddr;
332                 paddr = drvdata->paddr;
333                 drvdata->buf = drvdata->vaddr = NULL;
334         }
335
336         drvdata->reading = false;
337         spin_unlock_irqrestore(&drvdata->spinlock, flags);
338
339         /* Free allocated memory out side of the spinlock */
340         if (vaddr)
341                 dma_free_coherent(drvdata->dev, drvdata->size, vaddr, paddr);
342
343         return 0;
344 }