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