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;
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_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);
43 	axictl = (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);
47 
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);
56 
57 	CS_LOCK(drvdata->base);
58 }
59 
60 static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata)
61 {
62 	u32 rwp, val;
63 
64 	rwp = readl_relaxed(drvdata->base + TMC_RWP);
65 	val = readl_relaxed(drvdata->base + TMC_STS);
66 
67 	/*
68 	 * Adjust the buffer to point to the beginning of the trace data
69 	 * and update the available trace data.
70 	 */
71 	if (val & TMC_STS_FULL) {
72 		drvdata->buf = drvdata->vaddr + rwp - drvdata->paddr;
73 		drvdata->len = drvdata->size;
74 	} else {
75 		drvdata->buf = drvdata->vaddr;
76 		drvdata->len = rwp - drvdata->paddr;
77 	}
78 }
79 
80 static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
81 {
82 	CS_UNLOCK(drvdata->base);
83 
84 	tmc_flush_and_stop(drvdata);
85 	/*
86 	 * When operating in sysFS mode the content of the buffer needs to be
87 	 * read before the TMC is disabled.
88 	 */
89 	if (local_read(&drvdata->mode) == CS_MODE_SYSFS)
90 		tmc_etr_dump_hw(drvdata);
91 	tmc_disable_hw(drvdata);
92 
93 	CS_LOCK(drvdata->base);
94 }
95 
96 static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev, u32 mode)
97 {
98 	int ret = 0;
99 	bool used = false;
100 	long val;
101 	unsigned long flags;
102 	void __iomem *vaddr = NULL;
103 	dma_addr_t paddr;
104 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
105 
106 	 /* This shouldn't be happening */
107 	if (WARN_ON(mode != CS_MODE_SYSFS))
108 		return -EINVAL;
109 
110 	/*
111 	 * If we don't have a buffer release the lock and allocate memory.
112 	 * Otherwise keep the lock and move along.
113 	 */
114 	spin_lock_irqsave(&drvdata->spinlock, flags);
115 	if (!drvdata->vaddr) {
116 		spin_unlock_irqrestore(&drvdata->spinlock, flags);
117 
118 		/*
119 		 * Contiguous  memory can't be allocated while a spinlock is
120 		 * held.  As such allocate memory here and free it if a buffer
121 		 * has already been allocated (from a previous session).
122 		 */
123 		vaddr = dma_alloc_coherent(drvdata->dev, drvdata->size,
124 					   &paddr, GFP_KERNEL);
125 		if (!vaddr)
126 			return -ENOMEM;
127 
128 		/* Let's try again */
129 		spin_lock_irqsave(&drvdata->spinlock, flags);
130 	}
131 
132 	if (drvdata->reading) {
133 		ret = -EBUSY;
134 		goto out;
135 	}
136 
137 	val = local_xchg(&drvdata->mode, mode);
138 	/*
139 	 * In sysFS mode we can have multiple writers per sink.  Since this
140 	 * sink is already enabled no memory is needed and the HW need not be
141 	 * touched.
142 	 */
143 	if (val == CS_MODE_SYSFS)
144 		goto out;
145 
146 	/*
147 	 * If drvdata::buf == NULL, use the memory allocated above.
148 	 * Otherwise a buffer still exists from a previous session, so
149 	 * simply use that.
150 	 */
151 	if (drvdata->buf == NULL) {
152 		used = true;
153 		drvdata->vaddr = vaddr;
154 		drvdata->paddr = paddr;
155 		drvdata->buf = drvdata->vaddr;
156 	}
157 
158 	memset(drvdata->vaddr, 0, drvdata->size);
159 
160 	tmc_etr_enable_hw(drvdata);
161 out:
162 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
163 
164 	/* Free memory outside the spinlock if need be */
165 	if (!used && vaddr)
166 		dma_free_coherent(drvdata->dev, drvdata->size, vaddr, paddr);
167 
168 	if (!ret)
169 		dev_info(drvdata->dev, "TMC-ETR enabled\n");
170 
171 	return ret;
172 }
173 
174 static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, u32 mode)
175 {
176 	int ret = 0;
177 	long val;
178 	unsigned long flags;
179 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
180 
181 	 /* This shouldn't be happening */
182 	if (WARN_ON(mode != CS_MODE_PERF))
183 		return -EINVAL;
184 
185 	spin_lock_irqsave(&drvdata->spinlock, flags);
186 	if (drvdata->reading) {
187 		ret = -EINVAL;
188 		goto out;
189 	}
190 
191 	val = local_xchg(&drvdata->mode, mode);
192 	/*
193 	 * In Perf mode there can be only one writer per sink.  There
194 	 * is also no need to continue if the ETR is already operated
195 	 * from sysFS.
196 	 */
197 	if (val != CS_MODE_DISABLED) {
198 		ret = -EINVAL;
199 		goto out;
200 	}
201 
202 	tmc_etr_enable_hw(drvdata);
203 out:
204 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
205 
206 	return ret;
207 }
208 
209 static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
210 {
211 	switch (mode) {
212 	case CS_MODE_SYSFS:
213 		return tmc_enable_etr_sink_sysfs(csdev, mode);
214 	case CS_MODE_PERF:
215 		return tmc_enable_etr_sink_perf(csdev, mode);
216 	}
217 
218 	/* We shouldn't be here */
219 	return -EINVAL;
220 }
221 
222 static void tmc_disable_etr_sink(struct coresight_device *csdev)
223 {
224 	long val;
225 	unsigned long flags;
226 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
227 
228 	spin_lock_irqsave(&drvdata->spinlock, flags);
229 	if (drvdata->reading) {
230 		spin_unlock_irqrestore(&drvdata->spinlock, flags);
231 		return;
232 	}
233 
234 	val = local_xchg(&drvdata->mode, CS_MODE_DISABLED);
235 	/* Disable the TMC only if it needs to */
236 	if (val != CS_MODE_DISABLED)
237 		tmc_etr_disable_hw(drvdata);
238 
239 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
240 
241 	dev_info(drvdata->dev, "TMC-ETR disabled\n");
242 }
243 
244 static const struct coresight_ops_sink tmc_etr_sink_ops = {
245 	.enable		= tmc_enable_etr_sink,
246 	.disable	= tmc_disable_etr_sink,
247 };
248 
249 const struct coresight_ops tmc_etr_cs_ops = {
250 	.sink_ops	= &tmc_etr_sink_ops,
251 };
252 
253 int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
254 {
255 	int ret = 0;
256 	long val;
257 	unsigned long flags;
258 
259 	/* config types are set a boot time and never change */
260 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
261 		return -EINVAL;
262 
263 	spin_lock_irqsave(&drvdata->spinlock, flags);
264 	if (drvdata->reading) {
265 		ret = -EBUSY;
266 		goto out;
267 	}
268 
269 	val = local_read(&drvdata->mode);
270 	/* Don't interfere if operated from Perf */
271 	if (val == CS_MODE_PERF) {
272 		ret = -EINVAL;
273 		goto out;
274 	}
275 
276 	/* If drvdata::buf is NULL the trace data has been read already */
277 	if (drvdata->buf == NULL) {
278 		ret = -EINVAL;
279 		goto out;
280 	}
281 
282 	/* Disable the TMC if need be */
283 	if (val == CS_MODE_SYSFS)
284 		tmc_etr_disable_hw(drvdata);
285 
286 	drvdata->reading = true;
287 out:
288 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
289 
290 	return ret;
291 }
292 
293 int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
294 {
295 	unsigned long flags;
296 	dma_addr_t paddr;
297 	void __iomem *vaddr = NULL;
298 
299 	/* config types are set a boot time and never change */
300 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
301 		return -EINVAL;
302 
303 	spin_lock_irqsave(&drvdata->spinlock, flags);
304 
305 	/* RE-enable the TMC if need be */
306 	if (local_read(&drvdata->mode) == CS_MODE_SYSFS) {
307 		/*
308 		 * The trace run will continue with the same allocated trace
309 		 * buffer. The trace buffer is cleared in tmc_etr_enable_hw(),
310 		 * so we don't have to explicitly clear it. Also, since the
311 		 * tracer is still enabled drvdata::buf can't be NULL.
312 		 */
313 		tmc_etr_enable_hw(drvdata);
314 	} else {
315 		/*
316 		 * The ETR is not tracing and the buffer was just read.
317 		 * As such prepare to free the trace buffer.
318 		 */
319 		vaddr = drvdata->vaddr;
320 		paddr = drvdata->paddr;
321 		drvdata->buf = drvdata->vaddr = NULL;
322 	}
323 
324 	drvdata->reading = false;
325 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
326 
327 	/* Free allocated memory out side of the spinlock */
328 	if (vaddr)
329 		dma_free_coherent(drvdata->dev, drvdata->size, vaddr, paddr);
330 
331 	return 0;
332 }
333