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