xref: /linux/drivers/hwtracing/coresight/coresight-tpdm.c (revision cb4eb6771c0f8fd1c52a8f6fdec7762fb087380a)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/amba/bus.h>
7 #include <linux/bitfield.h>
8 #include <linux/bitmap.h>
9 #include <linux/coresight.h>
10 #include <linux/coresight-pmu.h>
11 #include <linux/device.h>
12 #include <linux/err.h>
13 #include <linux/fs.h>
14 #include <linux/io.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 
19 #include "coresight-priv.h"
20 #include "coresight-tpdm.h"
21 
tpdm_has_dsb_dataset(struct tpdm_drvdata * drvdata)22 static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
23 {
24 	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
25 }
26 
tpdm_has_cmb_dataset(struct tpdm_drvdata * drvdata)27 static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata)
28 {
29 	return (drvdata->datasets & TPDM_PIDR0_DS_CMB);
30 }
31 
tpdm_has_mcmb_dataset(struct tpdm_drvdata * drvdata)32 static bool tpdm_has_mcmb_dataset(struct tpdm_drvdata *drvdata)
33 {
34 	return (drvdata->datasets & TPDM_PIDR0_DS_MCMB);
35 }
36 
37 /* Read dataset array member with the index number */
tpdm_simple_dataset_show(struct device * dev,struct device_attribute * attr,char * buf)38 static ssize_t tpdm_simple_dataset_show(struct device *dev,
39 					struct device_attribute *attr,
40 					char *buf)
41 {
42 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
43 	struct tpdm_dataset_attribute *tpdm_attr =
44 		container_of(attr, struct tpdm_dataset_attribute, attr);
45 
46 	switch (tpdm_attr->mem) {
47 	case DSB_EDGE_CTRL:
48 		if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCR)
49 			return -EINVAL;
50 		return sysfs_emit(buf, "0x%x\n",
51 			drvdata->dsb->edge_ctrl[tpdm_attr->idx]);
52 	case DSB_EDGE_CTRL_MASK:
53 		if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCMR)
54 			return -EINVAL;
55 		return sysfs_emit(buf, "0x%x\n",
56 			drvdata->dsb->edge_ctrl_mask[tpdm_attr->idx]);
57 	case DSB_TRIG_PATT:
58 		if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT)
59 			return -EINVAL;
60 		return sysfs_emit(buf, "0x%x\n",
61 			drvdata->dsb->trig_patt[tpdm_attr->idx]);
62 	case DSB_TRIG_PATT_MASK:
63 		if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT)
64 			return -EINVAL;
65 		return sysfs_emit(buf, "0x%x\n",
66 			drvdata->dsb->trig_patt_mask[tpdm_attr->idx]);
67 	case DSB_PATT:
68 		if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT)
69 			return -EINVAL;
70 		return sysfs_emit(buf, "0x%x\n",
71 			drvdata->dsb->patt_val[tpdm_attr->idx]);
72 	case DSB_PATT_MASK:
73 		if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT)
74 			return -EINVAL;
75 		return sysfs_emit(buf, "0x%x\n",
76 			drvdata->dsb->patt_mask[tpdm_attr->idx]);
77 	case DSB_MSR:
78 		if (tpdm_attr->idx >= drvdata->dsb_msr_num)
79 			return -EINVAL;
80 		return sysfs_emit(buf, "0x%x\n",
81 				drvdata->dsb->msr[tpdm_attr->idx]);
82 	case CMB_TRIG_PATT:
83 		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
84 			return -EINVAL;
85 		return sysfs_emit(buf, "0x%x\n",
86 			drvdata->cmb->trig_patt[tpdm_attr->idx]);
87 	case CMB_TRIG_PATT_MASK:
88 		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
89 			return -EINVAL;
90 		return sysfs_emit(buf, "0x%x\n",
91 			drvdata->cmb->trig_patt_mask[tpdm_attr->idx]);
92 	case CMB_PATT:
93 		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
94 			return -EINVAL;
95 		return sysfs_emit(buf, "0x%x\n",
96 			drvdata->cmb->patt_val[tpdm_attr->idx]);
97 	case CMB_PATT_MASK:
98 		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
99 			return -EINVAL;
100 		return sysfs_emit(buf, "0x%x\n",
101 			drvdata->cmb->patt_mask[tpdm_attr->idx]);
102 	case CMB_MSR:
103 		if (tpdm_attr->idx >= drvdata->cmb_msr_num)
104 			return -EINVAL;
105 		return sysfs_emit(buf, "0x%x\n",
106 				drvdata->cmb->msr[tpdm_attr->idx]);
107 	}
108 	return -EINVAL;
109 }
110 
111 /* Write dataset array member with the index number */
tpdm_simple_dataset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)112 static ssize_t tpdm_simple_dataset_store(struct device *dev,
113 					 struct device_attribute *attr,
114 					 const char *buf,
115 					 size_t size)
116 {
117 	unsigned long val;
118 	ssize_t ret = -EINVAL;
119 
120 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
121 	struct tpdm_dataset_attribute *tpdm_attr =
122 		container_of(attr, struct tpdm_dataset_attribute, attr);
123 
124 	if (kstrtoul(buf, 0, &val))
125 		return ret;
126 
127 	guard(spinlock)(&drvdata->spinlock);
128 	switch (tpdm_attr->mem) {
129 	case DSB_TRIG_PATT:
130 		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
131 			drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
132 			ret = size;
133 		}
134 		break;
135 	case DSB_TRIG_PATT_MASK:
136 		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
137 			drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val;
138 			ret = size;
139 		}
140 		break;
141 	case DSB_PATT:
142 		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
143 			drvdata->dsb->patt_val[tpdm_attr->idx] = val;
144 			ret = size;
145 		}
146 		break;
147 	case DSB_PATT_MASK:
148 		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
149 			drvdata->dsb->patt_mask[tpdm_attr->idx] = val;
150 			ret = size;
151 		}
152 		break;
153 	case DSB_MSR:
154 		if (tpdm_attr->idx < drvdata->dsb_msr_num) {
155 			drvdata->dsb->msr[tpdm_attr->idx] = val;
156 			ret = size;
157 		}
158 		break;
159 	case CMB_TRIG_PATT:
160 		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
161 			drvdata->cmb->trig_patt[tpdm_attr->idx] = val;
162 			ret = size;
163 		}
164 		break;
165 	case CMB_TRIG_PATT_MASK:
166 		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
167 			drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val;
168 			ret = size;
169 		}
170 		break;
171 	case CMB_PATT:
172 		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
173 			drvdata->cmb->patt_val[tpdm_attr->idx] = val;
174 			ret = size;
175 		}
176 		break;
177 	case CMB_PATT_MASK:
178 		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
179 			drvdata->cmb->patt_mask[tpdm_attr->idx] = val;
180 			ret = size;
181 		}
182 		break;
183 	case CMB_MSR:
184 		if (tpdm_attr->idx < drvdata->cmb_msr_num) {
185 			drvdata->cmb->msr[tpdm_attr->idx] = val;
186 			ret = size;
187 		}
188 		break;
189 	default:
190 		break;
191 	}
192 
193 	return ret;
194 }
195 
tpdm_dsb_is_visible(struct kobject * kobj,struct attribute * attr,int n)196 static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
197 				   struct attribute *attr, int n)
198 {
199 	struct device *dev = kobj_to_dev(kobj);
200 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
201 
202 	if (drvdata && tpdm_has_dsb_dataset(drvdata))
203 		return attr->mode;
204 
205 	return 0;
206 }
207 
tpdm_cmb_is_visible(struct kobject * kobj,struct attribute * attr,int n)208 static umode_t tpdm_cmb_is_visible(struct kobject *kobj,
209 				   struct attribute *attr, int n)
210 {
211 	struct device *dev = kobj_to_dev(kobj);
212 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
213 
214 	if (drvdata && drvdata->cmb)
215 		return attr->mode;
216 
217 	return 0;
218 }
219 
tpdm_dsb_msr_is_visible(struct kobject * kobj,struct attribute * attr,int n)220 static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
221 				       struct attribute *attr, int n)
222 {
223 	struct device *dev = kobj_to_dev(kobj);
224 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
225 	struct device_attribute *dev_attr =
226 		container_of(attr, struct device_attribute, attr);
227 	struct tpdm_dataset_attribute *tpdm_attr =
228 		container_of(dev_attr, struct tpdm_dataset_attribute, attr);
229 
230 	if (tpdm_attr->idx < drvdata->dsb_msr_num)
231 		return attr->mode;
232 
233 	return 0;
234 }
235 
tpdm_cmb_msr_is_visible(struct kobject * kobj,struct attribute * attr,int n)236 static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
237 				       struct attribute *attr, int n)
238 {
239 	struct device *dev = kobj_to_dev(kobj);
240 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
241 
242 	struct device_attribute *dev_attr =
243 		container_of(attr, struct device_attribute, attr);
244 	struct tpdm_dataset_attribute *tpdm_attr =
245 		container_of(dev_attr, struct tpdm_dataset_attribute, attr);
246 
247 	if (tpdm_attr->idx < drvdata->cmb_msr_num)
248 		return attr->mode;
249 
250 	return 0;
251 }
252 
tpdm_mcmb_is_visible(struct kobject * kobj,struct attribute * attr,int n)253 static umode_t tpdm_mcmb_is_visible(struct kobject *kobj,
254 				    struct attribute *attr, int n)
255 {
256 	struct device *dev = kobj_to_dev(kobj);
257 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
258 
259 	if (drvdata && tpdm_has_mcmb_dataset(drvdata))
260 		return attr->mode;
261 
262 	return 0;
263 }
264 
tpdm_reset_datasets(struct tpdm_drvdata * drvdata)265 static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
266 {
267 	if (tpdm_has_dsb_dataset(drvdata)) {
268 		memset(drvdata->dsb, 0, sizeof(struct dsb_dataset));
269 
270 		drvdata->dsb->trig_ts = true;
271 		drvdata->dsb->trig_type = false;
272 	}
273 
274 	if (drvdata->cmb)
275 		memset(drvdata->cmb, 0, sizeof(struct cmb_dataset));
276 }
277 
set_dsb_mode(struct tpdm_drvdata * drvdata,u32 * val)278 static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val)
279 {
280 	u32 mode;
281 
282 	/* Set the test accurate mode */
283 	mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode);
284 	*val &= ~TPDM_DSB_CR_TEST_MODE;
285 	*val |= FIELD_PREP(TPDM_DSB_CR_TEST_MODE, mode);
286 
287 	/* Set the byte lane for high-performance mode */
288 	mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode);
289 	*val &= ~TPDM_DSB_CR_HPSEL;
290 	*val |= FIELD_PREP(TPDM_DSB_CR_HPSEL, mode);
291 
292 	/* Set the performance mode */
293 	if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF)
294 		*val |= TPDM_DSB_CR_MODE;
295 	else
296 		*val &= ~TPDM_DSB_CR_MODE;
297 }
298 
set_dsb_tier(struct tpdm_drvdata * drvdata)299 static void set_dsb_tier(struct tpdm_drvdata *drvdata)
300 {
301 	u32 val;
302 
303 	val = readl_relaxed(drvdata->base + TPDM_DSB_TIER);
304 
305 	/* Clear all relevant fields */
306 	val &= ~(TPDM_DSB_TIER_PATT_TSENAB | TPDM_DSB_TIER_PATT_TYPE |
307 		 TPDM_DSB_TIER_XTRIG_TSENAB);
308 
309 	/* Set pattern timestamp type and enablement */
310 	if (drvdata->dsb->patt_ts) {
311 		val |= TPDM_DSB_TIER_PATT_TSENAB;
312 		if (drvdata->dsb->patt_type)
313 			val |= TPDM_DSB_TIER_PATT_TYPE;
314 		else
315 			val &= ~TPDM_DSB_TIER_PATT_TYPE;
316 	} else {
317 		val &= ~TPDM_DSB_TIER_PATT_TSENAB;
318 	}
319 
320 	/* Set trigger timestamp */
321 	if (drvdata->dsb->trig_ts)
322 		val |= TPDM_DSB_TIER_XTRIG_TSENAB;
323 	else
324 		val &= ~TPDM_DSB_TIER_XTRIG_TSENAB;
325 
326 	writel_relaxed(val, drvdata->base + TPDM_DSB_TIER);
327 }
328 
set_dsb_msr(struct tpdm_drvdata * drvdata)329 static void set_dsb_msr(struct tpdm_drvdata *drvdata)
330 {
331 	int i;
332 
333 	for (i = 0; i < drvdata->dsb_msr_num; i++)
334 		writel_relaxed(drvdata->dsb->msr[i],
335 			   drvdata->base + TPDM_DSB_MSR(i));
336 }
337 
tpdm_enable_dsb(struct tpdm_drvdata * drvdata)338 static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
339 {
340 	u32 val, i;
341 
342 	if (!tpdm_has_dsb_dataset(drvdata))
343 		return;
344 
345 	for (i = 0; i < TPDM_DSB_MAX_EDCR; i++)
346 		writel_relaxed(drvdata->dsb->edge_ctrl[i],
347 			       drvdata->base + TPDM_DSB_EDCR(i));
348 	for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++)
349 		writel_relaxed(drvdata->dsb->edge_ctrl_mask[i],
350 			       drvdata->base + TPDM_DSB_EDCMR(i));
351 	for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
352 		writel_relaxed(drvdata->dsb->patt_val[i],
353 			       drvdata->base + TPDM_DSB_TPR(i));
354 		writel_relaxed(drvdata->dsb->patt_mask[i],
355 			       drvdata->base + TPDM_DSB_TPMR(i));
356 		writel_relaxed(drvdata->dsb->trig_patt[i],
357 			       drvdata->base + TPDM_DSB_XPR(i));
358 		writel_relaxed(drvdata->dsb->trig_patt_mask[i],
359 			       drvdata->base + TPDM_DSB_XPMR(i));
360 	}
361 
362 	set_dsb_tier(drvdata);
363 	set_dsb_msr(drvdata);
364 
365 	val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
366 	/* Set the mode of DSB dataset */
367 	set_dsb_mode(drvdata, &val);
368 	/* Set trigger type */
369 	if (drvdata->dsb->trig_type)
370 		val |= TPDM_DSB_CR_TRIG_TYPE;
371 	else
372 		val &= ~TPDM_DSB_CR_TRIG_TYPE;
373 	/* Set the enable bit of DSB control register to 1 */
374 	val |= TPDM_DSB_CR_ENA;
375 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
376 }
377 
set_cmb_tier(struct tpdm_drvdata * drvdata)378 static void set_cmb_tier(struct tpdm_drvdata *drvdata)
379 {
380 	u32 val;
381 
382 	val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
383 
384 	/* Clear all relevant fields */
385 	val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
386 		 TPDM_CMB_TIER_XTRIG_TSENAB);
387 
388 	/* Set pattern timestamp type and enablement */
389 	if (drvdata->cmb->patt_ts)
390 		val |= TPDM_CMB_TIER_PATT_TSENAB;
391 
392 	/* Set trigger timestamp */
393 	if (drvdata->cmb->trig_ts)
394 		val |= TPDM_CMB_TIER_XTRIG_TSENAB;
395 
396 	/* Set all timestamp enablement*/
397 	if (drvdata->cmb->ts_all)
398 		val |= TPDM_CMB_TIER_TS_ALL;
399 
400 	writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
401 }
402 
set_cmb_msr(struct tpdm_drvdata * drvdata)403 static void set_cmb_msr(struct tpdm_drvdata *drvdata)
404 {
405 	int i;
406 
407 	for (i = 0; i < drvdata->cmb_msr_num; i++)
408 		writel_relaxed(drvdata->cmb->msr[i],
409 			   drvdata->base + TPDM_CMB_MSR(i));
410 }
411 
tpdm_enable_cmb(struct tpdm_drvdata * drvdata)412 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
413 {
414 	u32 val, i;
415 
416 	if (!drvdata->cmb)
417 		return;
418 
419 	/* Configure pattern registers */
420 	for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
421 		writel_relaxed(drvdata->cmb->patt_val[i],
422 			drvdata->base + TPDM_CMB_TPR(i));
423 		writel_relaxed(drvdata->cmb->patt_mask[i],
424 			drvdata->base + TPDM_CMB_TPMR(i));
425 		writel_relaxed(drvdata->cmb->trig_patt[i],
426 			drvdata->base + TPDM_CMB_XPR(i));
427 		writel_relaxed(drvdata->cmb->trig_patt_mask[i],
428 			drvdata->base + TPDM_CMB_XPMR(i));
429 	}
430 
431 	set_cmb_tier(drvdata);
432 	set_cmb_msr(drvdata);
433 
434 	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
435 	/*
436 	 * Set to 0 for continuous CMB collection mode,
437 	 * 1 for trace-on-change CMB collection mode.
438 	 */
439 	if (drvdata->cmb->trace_mode)
440 		val |= TPDM_CMB_CR_MODE;
441 	else
442 		val &= ~TPDM_CMB_CR_MODE;
443 
444 	if (tpdm_has_mcmb_dataset(drvdata)) {
445 		val &= ~TPDM_CMB_CR_XTRIG_LNSEL;
446 		/* Set the lane participates in the output pattern */
447 		val |= FIELD_PREP(TPDM_CMB_CR_XTRIG_LNSEL,
448 			drvdata->cmb->mcmb.trig_lane);
449 
450 		/* Set the enablement of the lane */
451 		val &= ~TPDM_CMB_CR_E_LN;
452 		val |= FIELD_PREP(TPDM_CMB_CR_E_LN,
453 			drvdata->cmb->mcmb.lane_select);
454 	}
455 
456 	/* Set the enable bit of CMB control register to 1 */
457 	val |= TPDM_CMB_CR_ENA;
458 	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
459 }
460 
461 /*
462  * TPDM enable operations
463  * The TPDM or Monitor serves as data collection component for various
464  * dataset types. It covers Basic Counts(BC), Tenure Counts(TC),
465  * Continuous Multi-Bit(CMB), Multi-lane CMB(MCMB) and Discrete Single
466  * Bit(DSB). This function will initialize the configuration according
467  * to the dataset type supported by the TPDM.
468  */
__tpdm_enable(struct tpdm_drvdata * drvdata)469 static void __tpdm_enable(struct tpdm_drvdata *drvdata)
470 {
471 	if (coresight_is_static_tpdm(drvdata->csdev))
472 		return;
473 
474 	CS_UNLOCK(drvdata->base);
475 
476 	tpdm_enable_dsb(drvdata);
477 	tpdm_enable_cmb(drvdata);
478 
479 	CS_LOCK(drvdata->base);
480 }
481 
tpdm_enable(struct coresight_device * csdev,struct perf_event * event,enum cs_mode mode,struct coresight_path * path)482 static int tpdm_enable(struct coresight_device *csdev, struct perf_event *event,
483 		       enum cs_mode mode,
484 		       struct coresight_path *path)
485 {
486 	struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
487 
488 	spin_lock(&drvdata->spinlock);
489 	if (drvdata->enable) {
490 		spin_unlock(&drvdata->spinlock);
491 		return -EBUSY;
492 	}
493 
494 	if (!coresight_take_mode(csdev, mode)) {
495 		spin_unlock(&drvdata->spinlock);
496 		return -EBUSY;
497 	}
498 
499 	__tpdm_enable(drvdata);
500 	drvdata->traceid = path->trace_id;
501 	drvdata->enable = true;
502 	spin_unlock(&drvdata->spinlock);
503 
504 	dev_dbg(drvdata->dev, "TPDM tracing enabled\n");
505 	return 0;
506 }
507 
tpdm_disable_dsb(struct tpdm_drvdata * drvdata)508 static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
509 {
510 	u32 val;
511 
512 	if (!tpdm_has_dsb_dataset(drvdata))
513 		return;
514 
515 	/* Set the enable bit of DSB control register to 0 */
516 	val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
517 	val &= ~TPDM_DSB_CR_ENA;
518 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
519 }
520 
tpdm_disable_cmb(struct tpdm_drvdata * drvdata)521 static void tpdm_disable_cmb(struct tpdm_drvdata *drvdata)
522 {
523 	u32 val;
524 
525 	if (!drvdata->cmb)
526 		return;
527 
528 	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
529 	/* Set the enable bit of CMB control register to 0 */
530 	val &= ~TPDM_CMB_CR_ENA;
531 	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
532 }
533 
534 /* TPDM disable operations */
__tpdm_disable(struct tpdm_drvdata * drvdata)535 static void __tpdm_disable(struct tpdm_drvdata *drvdata)
536 {
537 	if (coresight_is_static_tpdm(drvdata->csdev))
538 		return;
539 
540 	CS_UNLOCK(drvdata->base);
541 
542 	tpdm_disable_dsb(drvdata);
543 	tpdm_disable_cmb(drvdata);
544 
545 	CS_LOCK(drvdata->base);
546 }
547 
tpdm_disable(struct coresight_device * csdev,struct perf_event * event)548 static void tpdm_disable(struct coresight_device *csdev,
549 			 struct perf_event *event)
550 {
551 	struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
552 
553 	spin_lock(&drvdata->spinlock);
554 	if (!drvdata->enable) {
555 		spin_unlock(&drvdata->spinlock);
556 		return;
557 	}
558 
559 	__tpdm_disable(drvdata);
560 	coresight_set_mode(csdev, CS_MODE_DISABLED);
561 	drvdata->enable = false;
562 	spin_unlock(&drvdata->spinlock);
563 
564 	dev_dbg(drvdata->dev, "TPDM tracing disabled\n");
565 }
566 
567 static const struct coresight_ops_source tpdm_source_ops = {
568 	.enable		= tpdm_enable,
569 	.disable	= tpdm_disable,
570 };
571 
572 static const struct coresight_ops tpdm_cs_ops = {
573 	.source_ops	= &tpdm_source_ops,
574 };
575 
tpdm_datasets_setup(struct tpdm_drvdata * drvdata)576 static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata)
577 {
578 	u32 pidr;
579 
580 	/*  Get the datasets present on the TPDM. */
581 	pidr = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0);
582 	drvdata->datasets |= pidr & GENMASK(TPDM_DATASETS - 1, 0);
583 
584 	if (tpdm_has_dsb_dataset(drvdata) && (!drvdata->dsb)) {
585 		drvdata->dsb = devm_kzalloc(drvdata->dev,
586 						sizeof(*drvdata->dsb), GFP_KERNEL);
587 		if (!drvdata->dsb)
588 			return -ENOMEM;
589 	}
590 	if ((tpdm_has_cmb_dataset(drvdata) || tpdm_has_mcmb_dataset(drvdata))
591 			&& (!drvdata->cmb)) {
592 		drvdata->cmb = devm_kzalloc(drvdata->dev,
593 						sizeof(*drvdata->cmb), GFP_KERNEL);
594 		if (!drvdata->cmb)
595 			return -ENOMEM;
596 	}
597 
598 	tpdm_reset_datasets(drvdata);
599 
600 	return 0;
601 }
602 
static_tpdm_datasets_setup(struct tpdm_drvdata * drvdata,struct device * dev)603 static int static_tpdm_datasets_setup(struct tpdm_drvdata *drvdata, struct device *dev)
604 {
605 	/* setup datasets for static TPDM */
606 	if (fwnode_property_present(dev->fwnode, "qcom,dsb-element-bits") &&
607 	    (!drvdata->dsb)) {
608 		drvdata->dsb = devm_kzalloc(drvdata->dev,
609 						sizeof(*drvdata->dsb), GFP_KERNEL);
610 
611 		if (!drvdata->dsb)
612 			return -ENOMEM;
613 	}
614 
615 	if (fwnode_property_present(dev->fwnode, "qcom,cmb-element-bits") &&
616 	    (!drvdata->cmb)) {
617 		drvdata->cmb = devm_kzalloc(drvdata->dev,
618 						sizeof(*drvdata->cmb), GFP_KERNEL);
619 
620 		if (!drvdata->cmb)
621 			return -ENOMEM;
622 	}
623 
624 	return 0;
625 }
626 
reset_dataset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)627 static ssize_t reset_dataset_store(struct device *dev,
628 				   struct device_attribute *attr,
629 				   const char *buf,
630 				   size_t size)
631 {
632 	int ret = 0;
633 	unsigned long val;
634 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
635 
636 	ret = kstrtoul(buf, 0, &val);
637 	if (ret || val != 1)
638 		return -EINVAL;
639 
640 	spin_lock(&drvdata->spinlock);
641 	tpdm_reset_datasets(drvdata);
642 	spin_unlock(&drvdata->spinlock);
643 
644 	return size;
645 }
646 static DEVICE_ATTR_WO(reset_dataset);
647 
648 /*
649  * value 1: 64 bits test data
650  * value 2: 32 bits test data
651  */
integration_test_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)652 static ssize_t integration_test_store(struct device *dev,
653 					  struct device_attribute *attr,
654 					  const char *buf,
655 					  size_t size)
656 {
657 	int i, ret = 0;
658 	unsigned long val;
659 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
660 
661 	ret = kstrtoul(buf, 10, &val);
662 	if (ret)
663 		return ret;
664 
665 	if (val != 1 && val != 2)
666 		return -EINVAL;
667 
668 	if (!drvdata->enable)
669 		return -EINVAL;
670 
671 	if (val == 1)
672 		val = ATBCNTRL_VAL_64;
673 	else
674 		val = ATBCNTRL_VAL_32;
675 	CS_UNLOCK(drvdata->base);
676 	writel_relaxed(0x1, drvdata->base + TPDM_ITCNTRL);
677 
678 	for (i = 0; i < INTEGRATION_TEST_CYCLE; i++)
679 		writel_relaxed(val, drvdata->base + TPDM_ITATBCNTRL);
680 
681 	writel_relaxed(0, drvdata->base + TPDM_ITCNTRL);
682 	CS_LOCK(drvdata->base);
683 	return size;
684 }
685 static DEVICE_ATTR_WO(integration_test);
686 
687 static struct attribute *tpdm_attrs[] = {
688 	&dev_attr_reset_dataset.attr,
689 	&dev_attr_integration_test.attr,
690 	NULL,
691 };
692 
693 static struct attribute_group tpdm_attr_grp = {
694 	.attrs = tpdm_attrs,
695 };
696 
traceid_show(struct device * dev,struct device_attribute * attr,char * buf)697 static ssize_t traceid_show(struct device *dev,
698 			    struct device_attribute *attr, char *buf)
699 {
700 	unsigned long val;
701 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
702 
703 	val = drvdata->traceid;
704 	if (!val)
705 		return -EINVAL;
706 
707 	return sysfs_emit(buf, "%#lx\n", val);
708 }
709 static DEVICE_ATTR_RO(traceid);
710 
711 static struct attribute *traceid_attrs[] = {
712 	&dev_attr_traceid.attr,
713 	NULL,
714 };
715 
716 static struct attribute_group traceid_attr_grp = {
717 	.attrs = traceid_attrs,
718 };
719 
dsb_mode_show(struct device * dev,struct device_attribute * attr,char * buf)720 static ssize_t dsb_mode_show(struct device *dev,
721 			     struct device_attribute *attr,
722 			     char *buf)
723 {
724 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
725 
726 	return sysfs_emit(buf, "%x\n", drvdata->dsb->mode);
727 }
728 
dsb_mode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)729 static ssize_t dsb_mode_store(struct device *dev,
730 			      struct device_attribute *attr,
731 			      const char *buf,
732 			      size_t size)
733 {
734 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
735 	unsigned long val;
736 
737 	if ((kstrtoul(buf, 0, &val)) || (val & ~TPDM_DSB_MODE_MASK))
738 		return -EINVAL;
739 
740 	spin_lock(&drvdata->spinlock);
741 	drvdata->dsb->mode = val & TPDM_DSB_MODE_MASK;
742 	spin_unlock(&drvdata->spinlock);
743 	return size;
744 }
745 static DEVICE_ATTR_RW(dsb_mode);
746 
ctrl_idx_show(struct device * dev,struct device_attribute * attr,char * buf)747 static ssize_t ctrl_idx_show(struct device *dev,
748 			     struct device_attribute *attr,
749 			     char *buf)
750 {
751 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
752 
753 	return sysfs_emit(buf, "%u\n",
754 			(unsigned int)drvdata->dsb->edge_ctrl_idx);
755 }
756 
757 /*
758  * The EDCR registers can include up to 16 32-bit registers, and each
759  * one can be configured to control up to 16 edge detections(2 bits
760  * control one edge detection). So a total 256 edge detections can be
761  * configured. This function provides a way to set the index number of
762  * the edge detection which needs to be configured.
763  */
ctrl_idx_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)764 static ssize_t ctrl_idx_store(struct device *dev,
765 			      struct device_attribute *attr,
766 			      const char *buf,
767 			      size_t size)
768 {
769 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
770 	unsigned long val;
771 
772 	if ((kstrtoul(buf, 0, &val)) || (val >= TPDM_DSB_MAX_LINES))
773 		return -EINVAL;
774 
775 	spin_lock(&drvdata->spinlock);
776 	drvdata->dsb->edge_ctrl_idx = val;
777 	spin_unlock(&drvdata->spinlock);
778 
779 	return size;
780 }
781 static DEVICE_ATTR_RW(ctrl_idx);
782 
783 /*
784  * This function is used to control the edge detection according
785  * to the index number that has been set.
786  * "edge_ctrl" should be one of the following values.
787  * 0 - Rising edge detection
788  * 1 - Falling edge detection
789  * 2 - Rising and falling edge detection (toggle detection)
790  */
ctrl_val_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)791 static ssize_t ctrl_val_store(struct device *dev,
792 			      struct device_attribute *attr,
793 			      const char *buf,
794 			      size_t size)
795 {
796 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
797 	unsigned long val, edge_ctrl;
798 	int reg;
799 
800 	if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2))
801 		return -EINVAL;
802 
803 	spin_lock(&drvdata->spinlock);
804 	/*
805 	 * There are 2 bit per DSB Edge Control line.
806 	 * Thus we have 16 lines in a 32bit word.
807 	 */
808 	reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx);
809 	val = drvdata->dsb->edge_ctrl[reg];
810 	val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx);
811 	val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx);
812 	drvdata->dsb->edge_ctrl[reg] = val;
813 	spin_unlock(&drvdata->spinlock);
814 
815 	return size;
816 }
817 static DEVICE_ATTR_WO(ctrl_val);
818 
ctrl_mask_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)819 static ssize_t ctrl_mask_store(struct device *dev,
820 			       struct device_attribute *attr,
821 			       const char *buf,
822 			       size_t size)
823 {
824 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
825 	unsigned long val;
826 	u32 set;
827 	int reg;
828 
829 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
830 		return -EINVAL;
831 
832 	spin_lock(&drvdata->spinlock);
833 	/*
834 	 * There is 1 bit per DSB Edge Control Mark line.
835 	 * Thus we have 32 lines in a 32bit word.
836 	 */
837 	reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx);
838 	set = drvdata->dsb->edge_ctrl_mask[reg];
839 	if (val)
840 		set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx));
841 	else
842 		set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx));
843 	drvdata->dsb->edge_ctrl_mask[reg] = set;
844 	spin_unlock(&drvdata->spinlock);
845 
846 	return size;
847 }
848 static DEVICE_ATTR_WO(ctrl_mask);
849 
enable_ts_show(struct device * dev,struct device_attribute * attr,char * buf)850 static ssize_t enable_ts_show(struct device *dev,
851 			      struct device_attribute *attr,
852 			      char *buf)
853 {
854 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
855 	struct tpdm_dataset_attribute *tpdm_attr =
856 		container_of(attr, struct tpdm_dataset_attribute, attr);
857 	ssize_t size = -EINVAL;
858 
859 	if (tpdm_attr->mem == DSB_PATT)
860 		size = sysfs_emit(buf, "%u\n",
861 				  (unsigned int)drvdata->dsb->patt_ts);
862 	else if (tpdm_attr->mem == CMB_PATT)
863 		size = sysfs_emit(buf, "%u\n",
864 				  (unsigned int)drvdata->cmb->patt_ts);
865 
866 	return size;
867 }
868 
869 /*
870  * value 1: Enable/Disable DSB pattern timestamp
871  */
enable_ts_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)872 static ssize_t enable_ts_store(struct device *dev,
873 			       struct device_attribute *attr,
874 			       const char *buf,
875 			       size_t size)
876 {
877 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
878 	struct tpdm_dataset_attribute *tpdm_attr =
879 		container_of(attr, struct tpdm_dataset_attribute, attr);
880 	unsigned long val;
881 
882 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
883 		return -EINVAL;
884 
885 	guard(spinlock)(&drvdata->spinlock);
886 	if (tpdm_attr->mem == DSB_PATT)
887 		drvdata->dsb->patt_ts = !!val;
888 	else if (tpdm_attr->mem == CMB_PATT)
889 		drvdata->cmb->patt_ts = !!val;
890 	else
891 		return -EINVAL;
892 
893 	return size;
894 }
895 
set_type_show(struct device * dev,struct device_attribute * attr,char * buf)896 static ssize_t set_type_show(struct device *dev,
897 			     struct device_attribute *attr,
898 			     char *buf)
899 {
900 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
901 
902 	return sysfs_emit(buf, "%u\n",
903 			 (unsigned int)drvdata->dsb->patt_type);
904 }
905 
906 /*
907  * value 1: Set DSB pattern type
908  */
set_type_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)909 static ssize_t set_type_store(struct device *dev,
910 			      struct device_attribute *attr,
911 			      const char *buf, size_t size)
912 {
913 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
914 	unsigned long val;
915 
916 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
917 		return -EINVAL;
918 
919 	spin_lock(&drvdata->spinlock);
920 	drvdata->dsb->patt_type = val;
921 	spin_unlock(&drvdata->spinlock);
922 	return size;
923 }
924 static DEVICE_ATTR_RW(set_type);
925 
dsb_trig_type_show(struct device * dev,struct device_attribute * attr,char * buf)926 static ssize_t dsb_trig_type_show(struct device *dev,
927 				  struct device_attribute *attr, char *buf)
928 {
929 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
930 
931 	return sysfs_emit(buf, "%u\n",
932 			 (unsigned int)drvdata->dsb->trig_type);
933 }
934 
935 /*
936  * Trigger type (boolean):
937  * false - Disable trigger type.
938  * true  - Enable trigger type.
939  */
dsb_trig_type_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)940 static ssize_t dsb_trig_type_store(struct device *dev,
941 				   struct device_attribute *attr,
942 				   const char *buf,
943 				   size_t size)
944 {
945 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
946 	unsigned long val;
947 
948 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
949 		return -EINVAL;
950 
951 	spin_lock(&drvdata->spinlock);
952 	if (val)
953 		drvdata->dsb->trig_type = true;
954 	else
955 		drvdata->dsb->trig_type = false;
956 	spin_unlock(&drvdata->spinlock);
957 	return size;
958 }
959 static DEVICE_ATTR_RW(dsb_trig_type);
960 
dsb_trig_ts_show(struct device * dev,struct device_attribute * attr,char * buf)961 static ssize_t dsb_trig_ts_show(struct device *dev,
962 				struct device_attribute *attr,
963 				char *buf)
964 {
965 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
966 
967 	return sysfs_emit(buf, "%u\n",
968 			 (unsigned int)drvdata->dsb->trig_ts);
969 }
970 
971 /*
972  * Trigger timestamp (boolean):
973  * false - Disable trigger timestamp.
974  * true  - Enable trigger timestamp.
975  */
dsb_trig_ts_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)976 static ssize_t dsb_trig_ts_store(struct device *dev,
977 				 struct device_attribute *attr,
978 				 const char *buf,
979 				 size_t size)
980 {
981 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
982 	unsigned long val;
983 
984 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
985 		return -EINVAL;
986 
987 	spin_lock(&drvdata->spinlock);
988 	if (val)
989 		drvdata->dsb->trig_ts = true;
990 	else
991 		drvdata->dsb->trig_ts = false;
992 	spin_unlock(&drvdata->spinlock);
993 	return size;
994 }
995 static DEVICE_ATTR_RW(dsb_trig_ts);
996 
cmb_mode_show(struct device * dev,struct device_attribute * attr,char * buf)997 static ssize_t cmb_mode_show(struct device *dev,
998 			     struct device_attribute *attr,
999 			     char *buf)
1000 {
1001 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1002 
1003 	return sysfs_emit(buf, "%x\n", drvdata->cmb->trace_mode);
1004 
1005 }
1006 
cmb_mode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)1007 static ssize_t cmb_mode_store(struct device *dev,
1008 			      struct device_attribute *attr,
1009 			      const char *buf,
1010 			      size_t size)
1011 {
1012 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1013 	unsigned long trace_mode;
1014 
1015 	if (kstrtoul(buf, 0, &trace_mode) || (trace_mode & ~1UL))
1016 		return -EINVAL;
1017 
1018 	spin_lock(&drvdata->spinlock);
1019 	drvdata->cmb->trace_mode = trace_mode;
1020 	spin_unlock(&drvdata->spinlock);
1021 	return size;
1022 }
1023 static DEVICE_ATTR_RW(cmb_mode);
1024 
cmb_ts_all_show(struct device * dev,struct device_attribute * attr,char * buf)1025 static ssize_t cmb_ts_all_show(struct device *dev,
1026 			       struct device_attribute *attr,
1027 			       char *buf)
1028 {
1029 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1030 
1031 	return sysfs_emit(buf, "%u\n",
1032 			  (unsigned int)drvdata->cmb->ts_all);
1033 }
1034 
cmb_ts_all_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)1035 static ssize_t cmb_ts_all_store(struct device *dev,
1036 				struct device_attribute *attr,
1037 				const char *buf,
1038 				size_t size)
1039 {
1040 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1041 	unsigned long val;
1042 
1043 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
1044 		return -EINVAL;
1045 
1046 	guard(spinlock)(&drvdata->spinlock);
1047 	if (val)
1048 		drvdata->cmb->ts_all = true;
1049 	else
1050 		drvdata->cmb->ts_all = false;
1051 
1052 	return size;
1053 }
1054 static DEVICE_ATTR_RW(cmb_ts_all);
1055 
cmb_trig_ts_show(struct device * dev,struct device_attribute * attr,char * buf)1056 static ssize_t cmb_trig_ts_show(struct device *dev,
1057 				struct device_attribute *attr,
1058 				char *buf)
1059 {
1060 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1061 
1062 	return sysfs_emit(buf, "%u\n",
1063 			  (unsigned int)drvdata->cmb->trig_ts);
1064 }
1065 
cmb_trig_ts_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)1066 static ssize_t cmb_trig_ts_store(struct device *dev,
1067 				 struct device_attribute *attr,
1068 				 const char *buf,
1069 				 size_t size)
1070 {
1071 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1072 	unsigned long val;
1073 
1074 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
1075 		return -EINVAL;
1076 
1077 	guard(spinlock)(&drvdata->spinlock);
1078 	if (val)
1079 		drvdata->cmb->trig_ts = true;
1080 	else
1081 		drvdata->cmb->trig_ts = false;
1082 
1083 	return size;
1084 }
1085 static DEVICE_ATTR_RW(cmb_trig_ts);
1086 
mcmb_trig_lane_show(struct device * dev,struct device_attribute * attr,char * buf)1087 static ssize_t mcmb_trig_lane_show(struct device *dev,
1088 				   struct device_attribute *attr,
1089 				   char *buf)
1090 {
1091 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1092 
1093 	return sysfs_emit(buf, "%u\n",
1094 			  (unsigned int)drvdata->cmb->mcmb.trig_lane);
1095 }
1096 
mcmb_trig_lane_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)1097 static ssize_t mcmb_trig_lane_store(struct device *dev,
1098 				    struct device_attribute *attr,
1099 				    const char *buf,
1100 				    size_t size)
1101 {
1102 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1103 	unsigned long val;
1104 
1105 	if ((kstrtoul(buf, 0, &val)) || (val >= TPDM_MCMB_MAX_LANES))
1106 		return -EINVAL;
1107 
1108 	guard(spinlock)(&drvdata->spinlock);
1109 	drvdata->cmb->mcmb.trig_lane = val;
1110 
1111 	return size;
1112 }
1113 static DEVICE_ATTR_RW(mcmb_trig_lane);
1114 
mcmb_lanes_select_show(struct device * dev,struct device_attribute * attr,char * buf)1115 static ssize_t mcmb_lanes_select_show(struct device *dev,
1116 				      struct device_attribute *attr,
1117 				      char *buf)
1118 {
1119 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1120 
1121 	return sysfs_emit(buf, "%u\n",
1122 			  (unsigned int)drvdata->cmb->mcmb.lane_select);
1123 }
1124 
mcmb_lanes_select_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)1125 static ssize_t mcmb_lanes_select_store(struct device *dev,
1126 				       struct device_attribute *attr,
1127 				       const char *buf,
1128 				       size_t size)
1129 {
1130 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1131 	unsigned long val;
1132 
1133 	if (kstrtoul(buf, 0, &val) || (val & ~TPDM_MCMB_E_LN_MASK))
1134 		return -EINVAL;
1135 
1136 	guard(spinlock)(&drvdata->spinlock);
1137 	drvdata->cmb->mcmb.lane_select = val & TPDM_MCMB_E_LN_MASK;
1138 
1139 	return size;
1140 }
1141 static DEVICE_ATTR_RW(mcmb_lanes_select);
1142 
1143 static struct attribute *tpdm_dsb_edge_attrs[] = {
1144 	&dev_attr_ctrl_idx.attr,
1145 	&dev_attr_ctrl_val.attr,
1146 	&dev_attr_ctrl_mask.attr,
1147 	DSB_EDGE_CTRL_ATTR(0),
1148 	DSB_EDGE_CTRL_ATTR(1),
1149 	DSB_EDGE_CTRL_ATTR(2),
1150 	DSB_EDGE_CTRL_ATTR(3),
1151 	DSB_EDGE_CTRL_ATTR(4),
1152 	DSB_EDGE_CTRL_ATTR(5),
1153 	DSB_EDGE_CTRL_ATTR(6),
1154 	DSB_EDGE_CTRL_ATTR(7),
1155 	DSB_EDGE_CTRL_ATTR(8),
1156 	DSB_EDGE_CTRL_ATTR(9),
1157 	DSB_EDGE_CTRL_ATTR(10),
1158 	DSB_EDGE_CTRL_ATTR(11),
1159 	DSB_EDGE_CTRL_ATTR(12),
1160 	DSB_EDGE_CTRL_ATTR(13),
1161 	DSB_EDGE_CTRL_ATTR(14),
1162 	DSB_EDGE_CTRL_ATTR(15),
1163 	DSB_EDGE_CTRL_MASK_ATTR(0),
1164 	DSB_EDGE_CTRL_MASK_ATTR(1),
1165 	DSB_EDGE_CTRL_MASK_ATTR(2),
1166 	DSB_EDGE_CTRL_MASK_ATTR(3),
1167 	DSB_EDGE_CTRL_MASK_ATTR(4),
1168 	DSB_EDGE_CTRL_MASK_ATTR(5),
1169 	DSB_EDGE_CTRL_MASK_ATTR(6),
1170 	DSB_EDGE_CTRL_MASK_ATTR(7),
1171 	NULL,
1172 };
1173 
1174 static struct attribute *tpdm_dsb_trig_patt_attrs[] = {
1175 	DSB_TRIG_PATT_ATTR(0),
1176 	DSB_TRIG_PATT_ATTR(1),
1177 	DSB_TRIG_PATT_ATTR(2),
1178 	DSB_TRIG_PATT_ATTR(3),
1179 	DSB_TRIG_PATT_ATTR(4),
1180 	DSB_TRIG_PATT_ATTR(5),
1181 	DSB_TRIG_PATT_ATTR(6),
1182 	DSB_TRIG_PATT_ATTR(7),
1183 	DSB_TRIG_PATT_MASK_ATTR(0),
1184 	DSB_TRIG_PATT_MASK_ATTR(1),
1185 	DSB_TRIG_PATT_MASK_ATTR(2),
1186 	DSB_TRIG_PATT_MASK_ATTR(3),
1187 	DSB_TRIG_PATT_MASK_ATTR(4),
1188 	DSB_TRIG_PATT_MASK_ATTR(5),
1189 	DSB_TRIG_PATT_MASK_ATTR(6),
1190 	DSB_TRIG_PATT_MASK_ATTR(7),
1191 	NULL,
1192 };
1193 
1194 static struct attribute *tpdm_dsb_patt_attrs[] = {
1195 	DSB_PATT_ATTR(0),
1196 	DSB_PATT_ATTR(1),
1197 	DSB_PATT_ATTR(2),
1198 	DSB_PATT_ATTR(3),
1199 	DSB_PATT_ATTR(4),
1200 	DSB_PATT_ATTR(5),
1201 	DSB_PATT_ATTR(6),
1202 	DSB_PATT_ATTR(7),
1203 	DSB_PATT_MASK_ATTR(0),
1204 	DSB_PATT_MASK_ATTR(1),
1205 	DSB_PATT_MASK_ATTR(2),
1206 	DSB_PATT_MASK_ATTR(3),
1207 	DSB_PATT_MASK_ATTR(4),
1208 	DSB_PATT_MASK_ATTR(5),
1209 	DSB_PATT_MASK_ATTR(6),
1210 	DSB_PATT_MASK_ATTR(7),
1211 	DSB_PATT_ENABLE_TS,
1212 	&dev_attr_set_type.attr,
1213 	NULL,
1214 };
1215 
1216 static struct attribute *tpdm_dsb_msr_attrs[] = {
1217 	DSB_MSR_ATTR(0),
1218 	DSB_MSR_ATTR(1),
1219 	DSB_MSR_ATTR(2),
1220 	DSB_MSR_ATTR(3),
1221 	DSB_MSR_ATTR(4),
1222 	DSB_MSR_ATTR(5),
1223 	DSB_MSR_ATTR(6),
1224 	DSB_MSR_ATTR(7),
1225 	DSB_MSR_ATTR(8),
1226 	DSB_MSR_ATTR(9),
1227 	DSB_MSR_ATTR(10),
1228 	DSB_MSR_ATTR(11),
1229 	DSB_MSR_ATTR(12),
1230 	DSB_MSR_ATTR(13),
1231 	DSB_MSR_ATTR(14),
1232 	DSB_MSR_ATTR(15),
1233 	DSB_MSR_ATTR(16),
1234 	DSB_MSR_ATTR(17),
1235 	DSB_MSR_ATTR(18),
1236 	DSB_MSR_ATTR(19),
1237 	DSB_MSR_ATTR(20),
1238 	DSB_MSR_ATTR(21),
1239 	DSB_MSR_ATTR(22),
1240 	DSB_MSR_ATTR(23),
1241 	DSB_MSR_ATTR(24),
1242 	DSB_MSR_ATTR(25),
1243 	DSB_MSR_ATTR(26),
1244 	DSB_MSR_ATTR(27),
1245 	DSB_MSR_ATTR(28),
1246 	DSB_MSR_ATTR(29),
1247 	DSB_MSR_ATTR(30),
1248 	DSB_MSR_ATTR(31),
1249 	NULL,
1250 };
1251 
1252 static struct attribute *tpdm_cmb_trig_patt_attrs[] = {
1253 	CMB_TRIG_PATT_ATTR(0),
1254 	CMB_TRIG_PATT_ATTR(1),
1255 	CMB_TRIG_PATT_MASK_ATTR(0),
1256 	CMB_TRIG_PATT_MASK_ATTR(1),
1257 	NULL,
1258 };
1259 
1260 static struct attribute *tpdm_cmb_patt_attrs[] = {
1261 	CMB_PATT_ATTR(0),
1262 	CMB_PATT_ATTR(1),
1263 	CMB_PATT_MASK_ATTR(0),
1264 	CMB_PATT_MASK_ATTR(1),
1265 	CMB_PATT_ENABLE_TS,
1266 	NULL,
1267 };
1268 
1269 static struct attribute *tpdm_cmb_msr_attrs[] = {
1270 	CMB_MSR_ATTR(0),
1271 	CMB_MSR_ATTR(1),
1272 	CMB_MSR_ATTR(2),
1273 	CMB_MSR_ATTR(3),
1274 	CMB_MSR_ATTR(4),
1275 	CMB_MSR_ATTR(5),
1276 	CMB_MSR_ATTR(6),
1277 	CMB_MSR_ATTR(7),
1278 	CMB_MSR_ATTR(8),
1279 	CMB_MSR_ATTR(9),
1280 	CMB_MSR_ATTR(10),
1281 	CMB_MSR_ATTR(11),
1282 	CMB_MSR_ATTR(12),
1283 	CMB_MSR_ATTR(13),
1284 	CMB_MSR_ATTR(14),
1285 	CMB_MSR_ATTR(15),
1286 	CMB_MSR_ATTR(16),
1287 	CMB_MSR_ATTR(17),
1288 	CMB_MSR_ATTR(18),
1289 	CMB_MSR_ATTR(19),
1290 	CMB_MSR_ATTR(20),
1291 	CMB_MSR_ATTR(21),
1292 	CMB_MSR_ATTR(22),
1293 	CMB_MSR_ATTR(23),
1294 	CMB_MSR_ATTR(24),
1295 	CMB_MSR_ATTR(25),
1296 	CMB_MSR_ATTR(26),
1297 	CMB_MSR_ATTR(27),
1298 	CMB_MSR_ATTR(28),
1299 	CMB_MSR_ATTR(29),
1300 	CMB_MSR_ATTR(30),
1301 	CMB_MSR_ATTR(31),
1302 	NULL,
1303 };
1304 
1305 static struct attribute *tpdm_mcmb_attrs[] = {
1306 	&dev_attr_mcmb_trig_lane.attr,
1307 	&dev_attr_mcmb_lanes_select.attr,
1308 	NULL,
1309 };
1310 
1311 static struct attribute *tpdm_dsb_attrs[] = {
1312 	&dev_attr_dsb_mode.attr,
1313 	&dev_attr_dsb_trig_ts.attr,
1314 	&dev_attr_dsb_trig_type.attr,
1315 	NULL,
1316 };
1317 
1318 static struct attribute *tpdm_cmb_attrs[] = {
1319 	&dev_attr_cmb_mode.attr,
1320 	&dev_attr_cmb_ts_all.attr,
1321 	&dev_attr_cmb_trig_ts.attr,
1322 	NULL,
1323 };
1324 
1325 static struct attribute_group tpdm_dsb_attr_grp = {
1326 	.attrs = tpdm_dsb_attrs,
1327 	.is_visible = tpdm_dsb_is_visible,
1328 };
1329 
1330 static struct attribute_group tpdm_dsb_edge_grp = {
1331 	.attrs = tpdm_dsb_edge_attrs,
1332 	.is_visible = tpdm_dsb_is_visible,
1333 	.name = "dsb_edge",
1334 };
1335 
1336 static struct attribute_group tpdm_dsb_trig_patt_grp = {
1337 	.attrs = tpdm_dsb_trig_patt_attrs,
1338 	.is_visible = tpdm_dsb_is_visible,
1339 	.name = "dsb_trig_patt",
1340 };
1341 
1342 static struct attribute_group tpdm_dsb_patt_grp = {
1343 	.attrs = tpdm_dsb_patt_attrs,
1344 	.is_visible = tpdm_dsb_is_visible,
1345 	.name = "dsb_patt",
1346 };
1347 
1348 static struct attribute_group tpdm_dsb_msr_grp = {
1349 	.attrs = tpdm_dsb_msr_attrs,
1350 	.is_visible = tpdm_dsb_msr_is_visible,
1351 	.name = "dsb_msr",
1352 };
1353 
1354 static struct attribute_group tpdm_cmb_attr_grp = {
1355 	.attrs = tpdm_cmb_attrs,
1356 	.is_visible = tpdm_cmb_is_visible,
1357 };
1358 
1359 static struct attribute_group tpdm_cmb_trig_patt_grp = {
1360 	.attrs = tpdm_cmb_trig_patt_attrs,
1361 	.is_visible = tpdm_cmb_is_visible,
1362 	.name = "cmb_trig_patt",
1363 };
1364 
1365 static struct attribute_group tpdm_cmb_patt_grp = {
1366 	.attrs = tpdm_cmb_patt_attrs,
1367 	.is_visible = tpdm_cmb_is_visible,
1368 	.name = "cmb_patt",
1369 };
1370 
1371 static struct attribute_group tpdm_cmb_msr_grp = {
1372 	.attrs = tpdm_cmb_msr_attrs,
1373 	.is_visible = tpdm_cmb_msr_is_visible,
1374 	.name = "cmb_msr",
1375 };
1376 
1377 static struct attribute_group tpdm_mcmb_attr_grp = {
1378 	.attrs = tpdm_mcmb_attrs,
1379 	.is_visible = tpdm_mcmb_is_visible,
1380 };
1381 
1382 static const struct attribute_group *tpdm_attr_grps[] = {
1383 	&tpdm_attr_grp,
1384 	&tpdm_dsb_attr_grp,
1385 	&tpdm_dsb_edge_grp,
1386 	&tpdm_dsb_trig_patt_grp,
1387 	&tpdm_dsb_patt_grp,
1388 	&tpdm_dsb_msr_grp,
1389 	&tpdm_cmb_attr_grp,
1390 	&tpdm_cmb_trig_patt_grp,
1391 	&tpdm_cmb_patt_grp,
1392 	&tpdm_cmb_msr_grp,
1393 	&tpdm_mcmb_attr_grp,
1394 	&traceid_attr_grp,
1395 	NULL,
1396 };
1397 
1398 static const struct attribute_group *static_tpdm_attr_grps[] = {
1399 	&traceid_attr_grp,
1400 	NULL,
1401 };
1402 
tpdm_probe(struct device * dev,struct resource * res)1403 static int tpdm_probe(struct device *dev, struct resource *res)
1404 {
1405 	void __iomem *base;
1406 	struct coresight_platform_data *pdata;
1407 	struct tpdm_drvdata *drvdata;
1408 	struct coresight_desc desc = { 0 };
1409 	int ret;
1410 
1411 	pdata = coresight_get_platform_data(dev);
1412 	if (IS_ERR(pdata))
1413 		return PTR_ERR(pdata);
1414 	dev->platform_data = pdata;
1415 
1416 	/* driver data*/
1417 	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
1418 	if (!drvdata)
1419 		return -ENOMEM;
1420 	drvdata->dev = dev;
1421 	dev_set_drvdata(dev, drvdata);
1422 
1423 	if (res) {
1424 		base = devm_ioremap_resource(dev, res);
1425 		if (IS_ERR(base))
1426 			return PTR_ERR(base);
1427 
1428 		drvdata->base = base;
1429 		ret = tpdm_datasets_setup(drvdata);
1430 		if (ret)
1431 			return ret;
1432 
1433 		desc.access = CSDEV_ACCESS_IOMEM(base);
1434 		if (tpdm_has_dsb_dataset(drvdata))
1435 			of_property_read_u32(drvdata->dev->of_node,
1436 					     "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
1437 
1438 		if (tpdm_has_cmb_dataset(drvdata))
1439 			of_property_read_u32(drvdata->dev->of_node,
1440 					     "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
1441 	} else {
1442 		ret = static_tpdm_datasets_setup(drvdata, dev);
1443 		if (ret)
1444 			return ret;
1445 	}
1446 
1447 	/* Set up coresight component description */
1448 	desc.name = coresight_alloc_device_name("tpdm", dev);
1449 	if (!desc.name)
1450 		return -ENOMEM;
1451 	desc.type = CORESIGHT_DEV_TYPE_SOURCE;
1452 	desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM;
1453 	desc.ops = &tpdm_cs_ops;
1454 	desc.pdata = dev->platform_data;
1455 	desc.dev = dev;
1456 	if (res)
1457 		desc.groups = tpdm_attr_grps;
1458 	else
1459 		desc.groups = static_tpdm_attr_grps;
1460 	drvdata->csdev = coresight_register(&desc);
1461 	if (IS_ERR(drvdata->csdev))
1462 		return PTR_ERR(drvdata->csdev);
1463 
1464 	spin_lock_init(&drvdata->spinlock);
1465 
1466 	return 0;
1467 }
1468 
tpdm_remove(struct device * dev)1469 static int tpdm_remove(struct device *dev)
1470 {
1471 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev);
1472 
1473 	coresight_unregister(drvdata->csdev);
1474 
1475 	return 0;
1476 }
1477 
dynamic_tpdm_probe(struct amba_device * adev,const struct amba_id * id)1478 static int dynamic_tpdm_probe(struct amba_device *adev,
1479 			      const struct amba_id *id)
1480 {
1481 	int ret;
1482 
1483 	ret = tpdm_probe(&adev->dev, &adev->res);
1484 	if (!ret)
1485 		pm_runtime_put(&adev->dev);
1486 
1487 	return ret;
1488 }
1489 
dynamic_tpdm_remove(struct amba_device * adev)1490 static void dynamic_tpdm_remove(struct amba_device *adev)
1491 {
1492 	tpdm_remove(&adev->dev);
1493 }
1494 
1495 /*
1496  * Different TPDM has different periph id.
1497  * The difference is 0-7 bits' value. So ignore 0-7 bits.
1498  */
1499 static const struct amba_id dynamic_tpdm_ids[] = {
1500 	{
1501 		.id	= 0x001f0e00,
1502 		.mask	= 0x00ffff00,
1503 	},
1504 	{ 0, 0, NULL },
1505 };
1506 
1507 MODULE_DEVICE_TABLE(amba, dynamic_tpdm_ids);
1508 
1509 static struct amba_driver dynamic_tpdm_driver = {
1510 	.drv = {
1511 		.name   = "coresight-tpdm",
1512 		.suppress_bind_attrs = true,
1513 	},
1514 	.probe          = dynamic_tpdm_probe,
1515 	.id_table	= dynamic_tpdm_ids,
1516 	.remove		= dynamic_tpdm_remove,
1517 };
1518 
tpdm_platform_probe(struct platform_device * pdev)1519 static int tpdm_platform_probe(struct platform_device *pdev)
1520 {
1521 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1522 	int ret;
1523 
1524 	pm_runtime_get_noresume(&pdev->dev);
1525 	pm_runtime_set_active(&pdev->dev);
1526 	pm_runtime_enable(&pdev->dev);
1527 
1528 	ret = tpdm_probe(&pdev->dev, res);
1529 	pm_runtime_put(&pdev->dev);
1530 	if (ret)
1531 		pm_runtime_disable(&pdev->dev);
1532 
1533 	return ret;
1534 }
1535 
tpdm_platform_remove(struct platform_device * pdev)1536 static void tpdm_platform_remove(struct platform_device *pdev)
1537 {
1538 	struct tpdm_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
1539 
1540 	if (WARN_ON(!drvdata))
1541 		return;
1542 
1543 	tpdm_remove(&pdev->dev);
1544 	pm_runtime_disable(&pdev->dev);
1545 }
1546 
1547 static const struct of_device_id static_tpdm_match[] = {
1548 	{.compatible = "qcom,coresight-static-tpdm"},
1549 	{}
1550 };
1551 
1552 MODULE_DEVICE_TABLE(of, static_tpdm_match);
1553 
1554 static struct platform_driver static_tpdm_driver = {
1555 	.probe		= tpdm_platform_probe,
1556 	.remove		= tpdm_platform_remove,
1557 	.driver		= {
1558 		.name	= "coresight-static-tpdm",
1559 		.of_match_table = static_tpdm_match,
1560 		.suppress_bind_attrs = true,
1561 	},
1562 };
1563 
tpdm_init(void)1564 static int __init tpdm_init(void)
1565 {
1566 	return coresight_init_driver("tpdm", &dynamic_tpdm_driver, &static_tpdm_driver,
1567 				     THIS_MODULE);
1568 }
1569 
tpdm_exit(void)1570 static void __exit tpdm_exit(void)
1571 {
1572 	coresight_remove_driver(&dynamic_tpdm_driver, &static_tpdm_driver);
1573 }
1574 
1575 module_init(tpdm_init);
1576 module_exit(tpdm_exit);
1577 
1578 MODULE_LICENSE("GPL");
1579 MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
1580