1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2019 Linaro Limited, All rights reserved.
4 * Author: Mike Leach <mike.leach@linaro.org>
5 */
6
7 #include <linux/atomic.h>
8 #include <linux/coresight.h>
9 #include <linux/device.h>
10 #include <linux/io.h>
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/sysfs.h>
14
15 #include "coresight-cti.h"
16
17 /*
18 * Declare the number of static declared attribute groups
19 * Value includes groups + NULL value at end of table.
20 */
21 #define CORESIGHT_CTI_STATIC_GROUPS_MAX 5
22
23 /*
24 * List of trigger signal type names. Match the constants declared in
25 * include\dt-bindings\arm\coresight-cti-dt.h
26 */
27 static const char * const sig_type_names[] = {
28 "genio", /* GEN_IO */
29 "intreq", /* GEN_INTREQ */
30 "intack", /* GEN_INTACK */
31 "haltreq", /* GEN_HALTREQ */
32 "restartreq", /* GEN_RESTARTREQ */
33 "pe_edbgreq", /* PE_EDBGREQ */
34 "pe_dbgrestart",/* PE_DBGRESTART */
35 "pe_ctiirq", /* PE_CTIIRQ */
36 "pe_pmuirq", /* PE_PMUIRQ */
37 "pe_dbgtrigger",/* PE_DBGTRIGGER */
38 "etm_extout", /* ETM_EXTOUT */
39 "etm_extin", /* ETM_EXTIN */
40 "snk_full", /* SNK_FULL */
41 "snk_acqcomp", /* SNK_ACQCOMP */
42 "snk_flushcomp",/* SNK_FLUSHCOMP */
43 "snk_flushin", /* SNK_FLUSHIN */
44 "snk_trigin", /* SNK_TRIGIN */
45 "stm_asyncout", /* STM_ASYNCOUT */
46 "stm_tout_spte",/* STM_TOUT_SPTE */
47 "stm_tout_sw", /* STM_TOUT_SW */
48 "stm_tout_hete",/* STM_TOUT_HETE */
49 "stm_hwevent", /* STM_HWEVENT */
50 "ela_tstart", /* ELA_TSTART */
51 "ela_tstop", /* ELA_TSTOP */
52 "ela_dbgreq", /* ELA_DBGREQ */
53 };
54
55 /* Show function pointer used in the connections dynamic declared attributes*/
56 typedef ssize_t (*p_show_fn)(struct device *dev, struct device_attribute *attr,
57 char *buf);
58
59 /* Connection attribute types */
60 enum cti_conn_attr_type {
61 CTI_CON_ATTR_NAME,
62 CTI_CON_ATTR_TRIGIN_SIG,
63 CTI_CON_ATTR_TRIGOUT_SIG,
64 CTI_CON_ATTR_TRIGIN_TYPES,
65 CTI_CON_ATTR_TRIGOUT_TYPES,
66 CTI_CON_ATTR_MAX,
67 };
68
69 /* Names for the connection attributes */
70 static const char * const con_attr_names[CTI_CON_ATTR_MAX] = {
71 "name",
72 "in_signals",
73 "out_signals",
74 "in_types",
75 "out_types",
76 };
77
78 /* basic attributes */
enable_show(struct device * dev,struct device_attribute * attr,char * buf)79 static ssize_t enable_show(struct device *dev,
80 struct device_attribute *attr,
81 char *buf)
82 {
83 int enable_req;
84 bool enabled, powered;
85 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
86
87 enable_req = atomic_read(&drvdata->config.enable_req_count);
88 spin_lock(&drvdata->spinlock);
89 powered = drvdata->config.hw_powered;
90 enabled = drvdata->config.hw_enabled;
91 spin_unlock(&drvdata->spinlock);
92
93 if (powered)
94 return sprintf(buf, "%d\n", enabled);
95 else
96 return sprintf(buf, "%d\n", !!enable_req);
97 }
98
enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)99 static ssize_t enable_store(struct device *dev,
100 struct device_attribute *attr,
101 const char *buf, size_t size)
102 {
103 int ret = 0;
104 unsigned long val;
105 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
106
107 ret = kstrtoul(buf, 0, &val);
108 if (ret)
109 return ret;
110
111 if (val)
112 ret = cti_enable(drvdata->csdev);
113 else
114 ret = cti_disable(drvdata->csdev);
115 if (ret)
116 return ret;
117 return size;
118 }
119 static DEVICE_ATTR_RW(enable);
120
powered_show(struct device * dev,struct device_attribute * attr,char * buf)121 static ssize_t powered_show(struct device *dev,
122 struct device_attribute *attr,
123 char *buf)
124 {
125 bool powered;
126 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
127
128 spin_lock(&drvdata->spinlock);
129 powered = drvdata->config.hw_powered;
130 spin_unlock(&drvdata->spinlock);
131
132 return sprintf(buf, "%d\n", powered);
133 }
134 static DEVICE_ATTR_RO(powered);
135
ctmid_show(struct device * dev,struct device_attribute * attr,char * buf)136 static ssize_t ctmid_show(struct device *dev,
137 struct device_attribute *attr, char *buf)
138 {
139 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
140
141 return sprintf(buf, "%d\n", drvdata->ctidev.ctm_id);
142 }
143 static DEVICE_ATTR_RO(ctmid);
144
nr_trigger_cons_show(struct device * dev,struct device_attribute * attr,char * buf)145 static ssize_t nr_trigger_cons_show(struct device *dev,
146 struct device_attribute *attr,
147 char *buf)
148 {
149 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
150
151 return sprintf(buf, "%d\n", drvdata->ctidev.nr_trig_con);
152 }
153 static DEVICE_ATTR_RO(nr_trigger_cons);
154
155 /* attribute and group sysfs tables. */
156 static struct attribute *coresight_cti_attrs[] = {
157 &dev_attr_enable.attr,
158 &dev_attr_powered.attr,
159 &dev_attr_ctmid.attr,
160 &dev_attr_nr_trigger_cons.attr,
161 NULL,
162 };
163
164 /* register based attributes */
165
166 /* Read registers with power check only (no enable check). */
coresight_cti_reg_show(struct device * dev,struct device_attribute * attr,char * buf)167 static ssize_t coresight_cti_reg_show(struct device *dev,
168 struct device_attribute *attr, char *buf)
169 {
170 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
171 struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr);
172 u32 val = 0;
173
174 pm_runtime_get_sync(dev->parent);
175 spin_lock(&drvdata->spinlock);
176 if (drvdata->config.hw_powered)
177 val = readl_relaxed(drvdata->base + cti_attr->off);
178 spin_unlock(&drvdata->spinlock);
179 pm_runtime_put_sync(dev->parent);
180 return sysfs_emit(buf, "0x%x\n", val);
181 }
182
183 /* Write registers with power check only (no enable check). */
coresight_cti_reg_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)184 static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev,
185 struct device_attribute *attr,
186 const char *buf, size_t size)
187 {
188 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
189 struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr);
190 unsigned long val = 0;
191
192 if (kstrtoul(buf, 0, &val))
193 return -EINVAL;
194
195 pm_runtime_get_sync(dev->parent);
196 spin_lock(&drvdata->spinlock);
197 if (drvdata->config.hw_powered)
198 cti_write_single_reg(drvdata, cti_attr->off, val);
199 spin_unlock(&drvdata->spinlock);
200 pm_runtime_put_sync(dev->parent);
201 return size;
202 }
203
204 #define coresight_cti_reg(name, offset) \
205 (&((struct cs_off_attribute[]) { \
206 { \
207 __ATTR(name, 0444, coresight_cti_reg_show, NULL), \
208 offset \
209 } \
210 })[0].attr.attr)
211
212 #define coresight_cti_reg_rw(name, offset) \
213 (&((struct cs_off_attribute[]) { \
214 { \
215 __ATTR(name, 0644, coresight_cti_reg_show, \
216 coresight_cti_reg_store), \
217 offset \
218 } \
219 })[0].attr.attr)
220
221 #define coresight_cti_reg_wo(name, offset) \
222 (&((struct cs_off_attribute[]) { \
223 { \
224 __ATTR(name, 0200, NULL, coresight_cti_reg_store), \
225 offset \
226 } \
227 })[0].attr.attr)
228
229 /* coresight management registers */
230 static struct attribute *coresight_cti_mgmt_attrs[] = {
231 coresight_cti_reg(devaff0, CTIDEVAFF0),
232 coresight_cti_reg(devaff1, CTIDEVAFF1),
233 coresight_cti_reg(authstatus, CORESIGHT_AUTHSTATUS),
234 coresight_cti_reg(devarch, CORESIGHT_DEVARCH),
235 coresight_cti_reg(devid, CORESIGHT_DEVID),
236 coresight_cti_reg(devtype, CORESIGHT_DEVTYPE),
237 coresight_cti_reg(pidr0, CORESIGHT_PERIPHIDR0),
238 coresight_cti_reg(pidr1, CORESIGHT_PERIPHIDR1),
239 coresight_cti_reg(pidr2, CORESIGHT_PERIPHIDR2),
240 coresight_cti_reg(pidr3, CORESIGHT_PERIPHIDR3),
241 coresight_cti_reg(pidr4, CORESIGHT_PERIPHIDR4),
242 NULL,
243 };
244
245 /* CTI low level programming registers */
246
247 /*
248 * Show a simple 32 bit value if enabled and powered.
249 * If inaccessible & pcached_val not NULL then show cached value.
250 */
cti_reg32_show(struct device * dev,char * buf,u32 * pcached_val,int reg_offset)251 static ssize_t cti_reg32_show(struct device *dev, char *buf,
252 u32 *pcached_val, int reg_offset)
253 {
254 u32 val = 0;
255 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
256 struct cti_config *config = &drvdata->config;
257
258 spin_lock(&drvdata->spinlock);
259 if ((reg_offset >= 0) && cti_active(config)) {
260 CS_UNLOCK(drvdata->base);
261 val = readl_relaxed(drvdata->base + reg_offset);
262 if (pcached_val)
263 *pcached_val = val;
264 CS_LOCK(drvdata->base);
265 } else if (pcached_val) {
266 val = *pcached_val;
267 }
268 spin_unlock(&drvdata->spinlock);
269 return sprintf(buf, "%#x\n", val);
270 }
271
272 /*
273 * Store a simple 32 bit value.
274 * If pcached_val not NULL, then copy to here too,
275 * if reg_offset >= 0 then write through if enabled.
276 */
cti_reg32_store(struct device * dev,const char * buf,size_t size,u32 * pcached_val,int reg_offset)277 static ssize_t cti_reg32_store(struct device *dev, const char *buf,
278 size_t size, u32 *pcached_val, int reg_offset)
279 {
280 unsigned long val;
281 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
282 struct cti_config *config = &drvdata->config;
283
284 if (kstrtoul(buf, 0, &val))
285 return -EINVAL;
286
287 spin_lock(&drvdata->spinlock);
288 /* local store */
289 if (pcached_val)
290 *pcached_val = (u32)val;
291
292 /* write through if offset and enabled */
293 if ((reg_offset >= 0) && cti_active(config))
294 cti_write_single_reg(drvdata, reg_offset, val);
295 spin_unlock(&drvdata->spinlock);
296 return size;
297 }
298
299 /* Standard macro for simple rw cti config registers */
300 #define cti_config_reg32_rw(name, cfgname, offset) \
301 static ssize_t name##_show(struct device *dev, \
302 struct device_attribute *attr, \
303 char *buf) \
304 { \
305 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
306 return cti_reg32_show(dev, buf, \
307 &drvdata->config.cfgname, offset); \
308 } \
309 \
310 static ssize_t name##_store(struct device *dev, \
311 struct device_attribute *attr, \
312 const char *buf, size_t size) \
313 { \
314 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
315 return cti_reg32_store(dev, buf, size, \
316 &drvdata->config.cfgname, offset); \
317 } \
318 static DEVICE_ATTR_RW(name)
319
inout_sel_show(struct device * dev,struct device_attribute * attr,char * buf)320 static ssize_t inout_sel_show(struct device *dev,
321 struct device_attribute *attr,
322 char *buf)
323 {
324 u32 val;
325 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
326
327 val = (u32)drvdata->config.ctiinout_sel;
328 return sprintf(buf, "%d\n", val);
329 }
330
inout_sel_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)331 static ssize_t inout_sel_store(struct device *dev,
332 struct device_attribute *attr,
333 const char *buf, size_t size)
334 {
335 unsigned long val;
336 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
337
338 if (kstrtoul(buf, 0, &val))
339 return -EINVAL;
340 if (val > (CTIINOUTEN_MAX - 1))
341 return -EINVAL;
342
343 spin_lock(&drvdata->spinlock);
344 drvdata->config.ctiinout_sel = val;
345 spin_unlock(&drvdata->spinlock);
346 return size;
347 }
348 static DEVICE_ATTR_RW(inout_sel);
349
inen_show(struct device * dev,struct device_attribute * attr,char * buf)350 static ssize_t inen_show(struct device *dev,
351 struct device_attribute *attr,
352 char *buf)
353 {
354 unsigned long val;
355 int index;
356 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
357
358 spin_lock(&drvdata->spinlock);
359 index = drvdata->config.ctiinout_sel;
360 val = drvdata->config.ctiinen[index];
361 spin_unlock(&drvdata->spinlock);
362 return sprintf(buf, "%#lx\n", val);
363 }
364
inen_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)365 static ssize_t inen_store(struct device *dev,
366 struct device_attribute *attr,
367 const char *buf, size_t size)
368 {
369 unsigned long val;
370 int index;
371 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
372 struct cti_config *config = &drvdata->config;
373
374 if (kstrtoul(buf, 0, &val))
375 return -EINVAL;
376
377 spin_lock(&drvdata->spinlock);
378 index = config->ctiinout_sel;
379 config->ctiinen[index] = val;
380
381 /* write through if enabled */
382 if (cti_active(config))
383 cti_write_single_reg(drvdata, CTIINEN(index), val);
384 spin_unlock(&drvdata->spinlock);
385 return size;
386 }
387 static DEVICE_ATTR_RW(inen);
388
outen_show(struct device * dev,struct device_attribute * attr,char * buf)389 static ssize_t outen_show(struct device *dev,
390 struct device_attribute *attr,
391 char *buf)
392 {
393 unsigned long val;
394 int index;
395 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
396
397 spin_lock(&drvdata->spinlock);
398 index = drvdata->config.ctiinout_sel;
399 val = drvdata->config.ctiouten[index];
400 spin_unlock(&drvdata->spinlock);
401 return sprintf(buf, "%#lx\n", val);
402 }
403
outen_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)404 static ssize_t outen_store(struct device *dev,
405 struct device_attribute *attr,
406 const char *buf, size_t size)
407 {
408 unsigned long val;
409 int index;
410 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
411 struct cti_config *config = &drvdata->config;
412
413 if (kstrtoul(buf, 0, &val))
414 return -EINVAL;
415
416 spin_lock(&drvdata->spinlock);
417 index = config->ctiinout_sel;
418 config->ctiouten[index] = val;
419
420 /* write through if enabled */
421 if (cti_active(config))
422 cti_write_single_reg(drvdata, CTIOUTEN(index), val);
423 spin_unlock(&drvdata->spinlock);
424 return size;
425 }
426 static DEVICE_ATTR_RW(outen);
427
intack_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)428 static ssize_t intack_store(struct device *dev,
429 struct device_attribute *attr,
430 const char *buf, size_t size)
431 {
432 unsigned long val;
433
434 if (kstrtoul(buf, 0, &val))
435 return -EINVAL;
436
437 cti_write_intack(dev, val);
438 return size;
439 }
440 static DEVICE_ATTR_WO(intack);
441
442 cti_config_reg32_rw(gate, ctigate, CTIGATE);
443 cti_config_reg32_rw(asicctl, asicctl, ASICCTL);
444 cti_config_reg32_rw(appset, ctiappset, CTIAPPSET);
445
appclear_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)446 static ssize_t appclear_store(struct device *dev,
447 struct device_attribute *attr,
448 const char *buf, size_t size)
449 {
450 unsigned long val;
451 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
452 struct cti_config *config = &drvdata->config;
453
454 if (kstrtoul(buf, 0, &val))
455 return -EINVAL;
456
457 spin_lock(&drvdata->spinlock);
458
459 /* a 1'b1 in appclr clears down the same bit in appset*/
460 config->ctiappset &= ~val;
461
462 /* write through if enabled */
463 if (cti_active(config))
464 cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
465 spin_unlock(&drvdata->spinlock);
466 return size;
467 }
468 static DEVICE_ATTR_WO(appclear);
469
apppulse_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)470 static ssize_t apppulse_store(struct device *dev,
471 struct device_attribute *attr,
472 const char *buf, size_t size)
473 {
474 unsigned long val;
475 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
476 struct cti_config *config = &drvdata->config;
477
478 if (kstrtoul(buf, 0, &val))
479 return -EINVAL;
480
481 spin_lock(&drvdata->spinlock);
482
483 /* write through if enabled */
484 if (cti_active(config))
485 cti_write_single_reg(drvdata, CTIAPPPULSE, val);
486 spin_unlock(&drvdata->spinlock);
487 return size;
488 }
489 static DEVICE_ATTR_WO(apppulse);
490
491 /*
492 * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
493 * integration control registers. Normally only used to investigate connection
494 * data.
495 */
496 static struct attribute *coresight_cti_regs_attrs[] = {
497 &dev_attr_inout_sel.attr,
498 &dev_attr_inen.attr,
499 &dev_attr_outen.attr,
500 &dev_attr_gate.attr,
501 &dev_attr_asicctl.attr,
502 &dev_attr_intack.attr,
503 &dev_attr_appset.attr,
504 &dev_attr_appclear.attr,
505 &dev_attr_apppulse.attr,
506 coresight_cti_reg(triginstatus, CTITRIGINSTATUS),
507 coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS),
508 coresight_cti_reg(chinstatus, CTICHINSTATUS),
509 coresight_cti_reg(choutstatus, CTICHOUTSTATUS),
510 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
511 coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL),
512 coresight_cti_reg(ittrigin, ITTRIGIN),
513 coresight_cti_reg(itchin, ITCHIN),
514 coresight_cti_reg_rw(ittrigout, ITTRIGOUT),
515 coresight_cti_reg_rw(itchout, ITCHOUT),
516 coresight_cti_reg(itchoutack, ITCHOUTACK),
517 coresight_cti_reg(ittrigoutack, ITTRIGOUTACK),
518 coresight_cti_reg_wo(ittriginack, ITTRIGINACK),
519 coresight_cti_reg_wo(itchinack, ITCHINACK),
520 #endif
521 NULL,
522 };
523
524 /* CTI channel x-trigger programming */
525 static int
cti_trig_op_parse(struct device * dev,enum cti_chan_op op,enum cti_trig_dir dir,const char * buf,size_t size)526 cti_trig_op_parse(struct device *dev, enum cti_chan_op op,
527 enum cti_trig_dir dir, const char *buf, size_t size)
528 {
529 u32 chan_idx;
530 u32 trig_idx;
531 int items, err = -EINVAL;
532
533 /* extract chan idx and trigger idx */
534 items = sscanf(buf, "%d %d", &chan_idx, &trig_idx);
535 if (items == 2) {
536 err = cti_channel_trig_op(dev, op, dir, chan_idx, trig_idx);
537 if (!err)
538 err = size;
539 }
540 return err;
541 }
542
trigin_attach_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)543 static ssize_t trigin_attach_store(struct device *dev,
544 struct device_attribute *attr,
545 const char *buf, size_t size)
546 {
547 return cti_trig_op_parse(dev, CTI_CHAN_ATTACH, CTI_TRIG_IN,
548 buf, size);
549 }
550 static DEVICE_ATTR_WO(trigin_attach);
551
trigin_detach_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)552 static ssize_t trigin_detach_store(struct device *dev,
553 struct device_attribute *attr,
554 const char *buf, size_t size)
555 {
556 return cti_trig_op_parse(dev, CTI_CHAN_DETACH, CTI_TRIG_IN,
557 buf, size);
558 }
559 static DEVICE_ATTR_WO(trigin_detach);
560
trigout_attach_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)561 static ssize_t trigout_attach_store(struct device *dev,
562 struct device_attribute *attr,
563 const char *buf, size_t size)
564 {
565 return cti_trig_op_parse(dev, CTI_CHAN_ATTACH, CTI_TRIG_OUT,
566 buf, size);
567 }
568 static DEVICE_ATTR_WO(trigout_attach);
569
trigout_detach_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)570 static ssize_t trigout_detach_store(struct device *dev,
571 struct device_attribute *attr,
572 const char *buf, size_t size)
573 {
574 return cti_trig_op_parse(dev, CTI_CHAN_DETACH, CTI_TRIG_OUT,
575 buf, size);
576 }
577 static DEVICE_ATTR_WO(trigout_detach);
578
579
chan_gate_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)580 static ssize_t chan_gate_enable_store(struct device *dev,
581 struct device_attribute *attr,
582 const char *buf, size_t size)
583 {
584 int err = 0, channel = 0;
585
586 if (kstrtoint(buf, 0, &channel))
587 return -EINVAL;
588
589 err = cti_channel_gate_op(dev, CTI_GATE_CHAN_ENABLE, channel);
590 return err ? err : size;
591 }
592
chan_gate_enable_show(struct device * dev,struct device_attribute * attr,char * buf)593 static ssize_t chan_gate_enable_show(struct device *dev,
594 struct device_attribute *attr,
595 char *buf)
596 {
597 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
598 struct cti_config *cfg = &drvdata->config;
599 unsigned long ctigate_bitmask = cfg->ctigate;
600 int size = 0;
601
602 if (cfg->ctigate == 0)
603 size = sprintf(buf, "\n");
604 else
605 size = bitmap_print_to_pagebuf(true, buf, &ctigate_bitmask,
606 cfg->nr_ctm_channels);
607 return size;
608 }
609 static DEVICE_ATTR_RW(chan_gate_enable);
610
chan_gate_disable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)611 static ssize_t chan_gate_disable_store(struct device *dev,
612 struct device_attribute *attr,
613 const char *buf, size_t size)
614 {
615 int err = 0, channel = 0;
616
617 if (kstrtoint(buf, 0, &channel))
618 return -EINVAL;
619
620 err = cti_channel_gate_op(dev, CTI_GATE_CHAN_DISABLE, channel);
621 return err ? err : size;
622 }
623 static DEVICE_ATTR_WO(chan_gate_disable);
624
625 static int
chan_op_parse(struct device * dev,enum cti_chan_set_op op,const char * buf)626 chan_op_parse(struct device *dev, enum cti_chan_set_op op, const char *buf)
627 {
628 int err = 0, channel = 0;
629
630 if (kstrtoint(buf, 0, &channel))
631 return -EINVAL;
632
633 err = cti_channel_setop(dev, op, channel);
634 return err;
635
636 }
637
chan_set_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)638 static ssize_t chan_set_store(struct device *dev,
639 struct device_attribute *attr,
640 const char *buf, size_t size)
641 {
642 int err = chan_op_parse(dev, CTI_CHAN_SET, buf);
643
644 return err ? err : size;
645 }
646 static DEVICE_ATTR_WO(chan_set);
647
chan_clear_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)648 static ssize_t chan_clear_store(struct device *dev,
649 struct device_attribute *attr,
650 const char *buf, size_t size)
651 {
652 int err = chan_op_parse(dev, CTI_CHAN_CLR, buf);
653
654 return err ? err : size;
655 }
656 static DEVICE_ATTR_WO(chan_clear);
657
chan_pulse_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)658 static ssize_t chan_pulse_store(struct device *dev,
659 struct device_attribute *attr,
660 const char *buf, size_t size)
661 {
662 int err = chan_op_parse(dev, CTI_CHAN_PULSE, buf);
663
664 return err ? err : size;
665 }
666 static DEVICE_ATTR_WO(chan_pulse);
667
trig_filter_enable_show(struct device * dev,struct device_attribute * attr,char * buf)668 static ssize_t trig_filter_enable_show(struct device *dev,
669 struct device_attribute *attr,
670 char *buf)
671 {
672 u32 val;
673 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
674
675 spin_lock(&drvdata->spinlock);
676 val = drvdata->config.trig_filter_enable;
677 spin_unlock(&drvdata->spinlock);
678 return sprintf(buf, "%d\n", val);
679 }
680
trig_filter_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)681 static ssize_t trig_filter_enable_store(struct device *dev,
682 struct device_attribute *attr,
683 const char *buf, size_t size)
684 {
685 unsigned long val;
686 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
687
688 if (kstrtoul(buf, 0, &val))
689 return -EINVAL;
690
691 spin_lock(&drvdata->spinlock);
692 drvdata->config.trig_filter_enable = !!val;
693 spin_unlock(&drvdata->spinlock);
694 return size;
695 }
696 static DEVICE_ATTR_RW(trig_filter_enable);
697
trigout_filtered_show(struct device * dev,struct device_attribute * attr,char * buf)698 static ssize_t trigout_filtered_show(struct device *dev,
699 struct device_attribute *attr,
700 char *buf)
701 {
702 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
703 struct cti_config *cfg = &drvdata->config;
704 int size = 0, nr_trig_max = cfg->nr_trig_max;
705 unsigned long mask = cfg->trig_out_filter;
706
707 if (mask)
708 size = bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max);
709 return size;
710 }
711 static DEVICE_ATTR_RO(trigout_filtered);
712
713 /* clear all xtrigger / channel programming */
chan_xtrigs_reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)714 static ssize_t chan_xtrigs_reset_store(struct device *dev,
715 struct device_attribute *attr,
716 const char *buf, size_t size)
717 {
718 int i;
719 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
720 struct cti_config *config = &drvdata->config;
721
722 spin_lock(&drvdata->spinlock);
723
724 /* clear the CTI trigger / channel programming registers */
725 for (i = 0; i < config->nr_trig_max; i++) {
726 config->ctiinen[i] = 0;
727 config->ctiouten[i] = 0;
728 }
729
730 /* clear the other regs */
731 config->ctigate = GENMASK(config->nr_ctm_channels - 1, 0);
732 config->asicctl = 0;
733 config->ctiappset = 0;
734 config->ctiinout_sel = 0;
735 config->xtrig_rchan_sel = 0;
736
737 /* if enabled then write through */
738 if (cti_active(config))
739 cti_write_all_hw_regs(drvdata);
740
741 spin_unlock(&drvdata->spinlock);
742 return size;
743 }
744 static DEVICE_ATTR_WO(chan_xtrigs_reset);
745
746 /*
747 * Write to select a channel to view, read to display the
748 * cross triggers for the selected channel.
749 */
chan_xtrigs_sel_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t size)750 static ssize_t chan_xtrigs_sel_store(struct device *dev,
751 struct device_attribute *attr,
752 const char *buf, size_t size)
753 {
754 unsigned long val;
755 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
756
757 if (kstrtoul(buf, 0, &val))
758 return -EINVAL;
759 if (val > (drvdata->config.nr_ctm_channels - 1))
760 return -EINVAL;
761
762 spin_lock(&drvdata->spinlock);
763 drvdata->config.xtrig_rchan_sel = val;
764 spin_unlock(&drvdata->spinlock);
765 return size;
766 }
767
chan_xtrigs_sel_show(struct device * dev,struct device_attribute * attr,char * buf)768 static ssize_t chan_xtrigs_sel_show(struct device *dev,
769 struct device_attribute *attr,
770 char *buf)
771 {
772 unsigned long val;
773 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
774
775 spin_lock(&drvdata->spinlock);
776 val = drvdata->config.xtrig_rchan_sel;
777 spin_unlock(&drvdata->spinlock);
778
779 return sprintf(buf, "%ld\n", val);
780 }
781 static DEVICE_ATTR_RW(chan_xtrigs_sel);
782
chan_xtrigs_in_show(struct device * dev,struct device_attribute * attr,char * buf)783 static ssize_t chan_xtrigs_in_show(struct device *dev,
784 struct device_attribute *attr,
785 char *buf)
786 {
787 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
788 struct cti_config *cfg = &drvdata->config;
789 int used = 0, reg_idx;
790 int nr_trig_max = drvdata->config.nr_trig_max;
791 u32 chan_mask = BIT(cfg->xtrig_rchan_sel);
792
793 for (reg_idx = 0; reg_idx < nr_trig_max; reg_idx++) {
794 if (chan_mask & cfg->ctiinen[reg_idx])
795 used += sprintf(buf + used, "%d ", reg_idx);
796 }
797
798 used += sprintf(buf + used, "\n");
799 return used;
800 }
801 static DEVICE_ATTR_RO(chan_xtrigs_in);
802
chan_xtrigs_out_show(struct device * dev,struct device_attribute * attr,char * buf)803 static ssize_t chan_xtrigs_out_show(struct device *dev,
804 struct device_attribute *attr,
805 char *buf)
806 {
807 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
808 struct cti_config *cfg = &drvdata->config;
809 int used = 0, reg_idx;
810 int nr_trig_max = drvdata->config.nr_trig_max;
811 u32 chan_mask = BIT(cfg->xtrig_rchan_sel);
812
813 for (reg_idx = 0; reg_idx < nr_trig_max; reg_idx++) {
814 if (chan_mask & cfg->ctiouten[reg_idx])
815 used += sprintf(buf + used, "%d ", reg_idx);
816 }
817
818 used += sprintf(buf + used, "\n");
819 return used;
820 }
821 static DEVICE_ATTR_RO(chan_xtrigs_out);
822
print_chan_list(struct device * dev,char * buf,bool inuse)823 static ssize_t print_chan_list(struct device *dev,
824 char *buf, bool inuse)
825 {
826 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
827 struct cti_config *config = &drvdata->config;
828 int size, i;
829 unsigned long inuse_bits = 0, chan_mask;
830
831 /* scan regs to get bitmap of channels in use. */
832 spin_lock(&drvdata->spinlock);
833 for (i = 0; i < config->nr_trig_max; i++) {
834 inuse_bits |= config->ctiinen[i];
835 inuse_bits |= config->ctiouten[i];
836 }
837 spin_unlock(&drvdata->spinlock);
838
839 /* inverse bits if printing free channels */
840 if (!inuse)
841 inuse_bits = ~inuse_bits;
842
843 /* list of channels, or 'none' */
844 chan_mask = GENMASK(config->nr_ctm_channels - 1, 0);
845 if (inuse_bits & chan_mask)
846 size = bitmap_print_to_pagebuf(true, buf, &inuse_bits,
847 config->nr_ctm_channels);
848 else
849 size = sprintf(buf, "\n");
850 return size;
851 }
852
chan_inuse_show(struct device * dev,struct device_attribute * attr,char * buf)853 static ssize_t chan_inuse_show(struct device *dev,
854 struct device_attribute *attr,
855 char *buf)
856 {
857 return print_chan_list(dev, buf, true);
858 }
859 static DEVICE_ATTR_RO(chan_inuse);
860
chan_free_show(struct device * dev,struct device_attribute * attr,char * buf)861 static ssize_t chan_free_show(struct device *dev,
862 struct device_attribute *attr,
863 char *buf)
864 {
865 return print_chan_list(dev, buf, false);
866 }
867 static DEVICE_ATTR_RO(chan_free);
868
869 static struct attribute *coresight_cti_channel_attrs[] = {
870 &dev_attr_trigin_attach.attr,
871 &dev_attr_trigin_detach.attr,
872 &dev_attr_trigout_attach.attr,
873 &dev_attr_trigout_detach.attr,
874 &dev_attr_trig_filter_enable.attr,
875 &dev_attr_trigout_filtered.attr,
876 &dev_attr_chan_gate_enable.attr,
877 &dev_attr_chan_gate_disable.attr,
878 &dev_attr_chan_set.attr,
879 &dev_attr_chan_clear.attr,
880 &dev_attr_chan_pulse.attr,
881 &dev_attr_chan_inuse.attr,
882 &dev_attr_chan_free.attr,
883 &dev_attr_chan_xtrigs_sel.attr,
884 &dev_attr_chan_xtrigs_in.attr,
885 &dev_attr_chan_xtrigs_out.attr,
886 &dev_attr_chan_xtrigs_reset.attr,
887 NULL,
888 };
889
890 /* Create the connections trigger groups and attrs dynamically */
891 /*
892 * Each connection has dynamic group triggers<N> + name, trigin/out sigs/types
893 * attributes, + each device has static nr_trigger_cons giving the number
894 * of groups. e.g. in sysfs:-
895 * /cti_<name>/triggers0
896 * /cti_<name>/triggers1
897 * /cti_<name>/nr_trigger_cons
898 * where nr_trigger_cons = 2
899 */
con_name_show(struct device * dev,struct device_attribute * attr,char * buf)900 static ssize_t con_name_show(struct device *dev,
901 struct device_attribute *attr,
902 char *buf)
903 {
904 struct dev_ext_attribute *ext_attr =
905 container_of(attr, struct dev_ext_attribute, attr);
906 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
907
908 return sprintf(buf, "%s\n", con->con_dev_name);
909 }
910
trigin_sig_show(struct device * dev,struct device_attribute * attr,char * buf)911 static ssize_t trigin_sig_show(struct device *dev,
912 struct device_attribute *attr,
913 char *buf)
914 {
915 struct dev_ext_attribute *ext_attr =
916 container_of(attr, struct dev_ext_attribute, attr);
917 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
918 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
919 struct cti_config *cfg = &drvdata->config;
920 unsigned long mask = con->con_in->used_mask;
921
922 return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
923 }
924
trigout_sig_show(struct device * dev,struct device_attribute * attr,char * buf)925 static ssize_t trigout_sig_show(struct device *dev,
926 struct device_attribute *attr,
927 char *buf)
928 {
929 struct dev_ext_attribute *ext_attr =
930 container_of(attr, struct dev_ext_attribute, attr);
931 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
932 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
933 struct cti_config *cfg = &drvdata->config;
934 unsigned long mask = con->con_out->used_mask;
935
936 return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
937 }
938
939 /* convert a sig type id to a name */
940 static const char *
cti_sig_type_name(struct cti_trig_con * con,int used_count,bool in)941 cti_sig_type_name(struct cti_trig_con *con, int used_count, bool in)
942 {
943 int idx = 0;
944 struct cti_trig_grp *grp = in ? con->con_in : con->con_out;
945
946 if (used_count < grp->nr_sigs)
947 idx = grp->sig_types[used_count];
948 return sig_type_names[idx];
949 }
950
trigin_type_show(struct device * dev,struct device_attribute * attr,char * buf)951 static ssize_t trigin_type_show(struct device *dev,
952 struct device_attribute *attr,
953 char *buf)
954 {
955 struct dev_ext_attribute *ext_attr =
956 container_of(attr, struct dev_ext_attribute, attr);
957 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
958 int sig_idx, used = 0;
959 const char *name;
960
961 for (sig_idx = 0; sig_idx < con->con_in->nr_sigs; sig_idx++) {
962 name = cti_sig_type_name(con, sig_idx, true);
963 used += sprintf(buf + used, "%s ", name);
964 }
965 used += sprintf(buf + used, "\n");
966 return used;
967 }
968
trigout_type_show(struct device * dev,struct device_attribute * attr,char * buf)969 static ssize_t trigout_type_show(struct device *dev,
970 struct device_attribute *attr,
971 char *buf)
972 {
973 struct dev_ext_attribute *ext_attr =
974 container_of(attr, struct dev_ext_attribute, attr);
975 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
976 int sig_idx, used = 0;
977 const char *name;
978
979 for (sig_idx = 0; sig_idx < con->con_out->nr_sigs; sig_idx++) {
980 name = cti_sig_type_name(con, sig_idx, false);
981 used += sprintf(buf + used, "%s ", name);
982 }
983 used += sprintf(buf + used, "\n");
984 return used;
985 }
986
987 /*
988 * Array of show function names declared above to allow selection
989 * for the connection attributes
990 */
991 static p_show_fn show_fns[CTI_CON_ATTR_MAX] = {
992 con_name_show,
993 trigin_sig_show,
994 trigout_sig_show,
995 trigin_type_show,
996 trigout_type_show,
997 };
998
cti_create_con_sysfs_attr(struct device * dev,struct cti_trig_con * con,enum cti_conn_attr_type attr_type,int attr_idx)999 static int cti_create_con_sysfs_attr(struct device *dev,
1000 struct cti_trig_con *con,
1001 enum cti_conn_attr_type attr_type,
1002 int attr_idx)
1003 {
1004 struct dev_ext_attribute *eattr;
1005 char *name;
1006
1007 eattr = devm_kzalloc(dev, sizeof(struct dev_ext_attribute),
1008 GFP_KERNEL);
1009 if (eattr) {
1010 name = devm_kstrdup(dev, con_attr_names[attr_type],
1011 GFP_KERNEL);
1012 if (name) {
1013 /* fill out the underlying attribute struct */
1014 eattr->attr.attr.name = name;
1015 eattr->attr.attr.mode = 0444;
1016
1017 /* now the device_attribute struct */
1018 eattr->attr.show = show_fns[attr_type];
1019 } else {
1020 return -ENOMEM;
1021 }
1022 } else {
1023 return -ENOMEM;
1024 }
1025 eattr->var = con;
1026 con->con_attrs[attr_idx] = &eattr->attr.attr;
1027 /*
1028 * Initialize the dynamically allocated attribute
1029 * to avoid LOCKDEP splat. See include/linux/sysfs.h
1030 * for more details.
1031 */
1032 sysfs_attr_init(con->con_attrs[attr_idx]);
1033
1034 return 0;
1035 }
1036
1037 static struct attribute_group *
cti_create_con_sysfs_group(struct device * dev,struct cti_device * ctidev,int con_idx,struct cti_trig_con * tc)1038 cti_create_con_sysfs_group(struct device *dev, struct cti_device *ctidev,
1039 int con_idx, struct cti_trig_con *tc)
1040 {
1041 struct attribute_group *group = NULL;
1042 int grp_idx;
1043
1044 group = devm_kzalloc(dev, sizeof(struct attribute_group), GFP_KERNEL);
1045 if (!group)
1046 return NULL;
1047
1048 group->name = devm_kasprintf(dev, GFP_KERNEL, "triggers%d", con_idx);
1049 if (!group->name)
1050 return NULL;
1051
1052 grp_idx = con_idx + CORESIGHT_CTI_STATIC_GROUPS_MAX - 1;
1053 ctidev->con_groups[grp_idx] = group;
1054 tc->attr_group = group;
1055 return group;
1056 }
1057
1058 /* create a triggers connection group and the attributes for that group */
cti_create_con_attr_set(struct device * dev,int con_idx,struct cti_device * ctidev,struct cti_trig_con * tc)1059 static int cti_create_con_attr_set(struct device *dev, int con_idx,
1060 struct cti_device *ctidev,
1061 struct cti_trig_con *tc)
1062 {
1063 struct attribute_group *attr_group = NULL;
1064 int attr_idx = 0;
1065 int err = -ENOMEM;
1066
1067 attr_group = cti_create_con_sysfs_group(dev, ctidev, con_idx, tc);
1068 if (!attr_group)
1069 return -ENOMEM;
1070
1071 /* allocate NULL terminated array of attributes */
1072 tc->con_attrs = devm_kcalloc(dev, CTI_CON_ATTR_MAX + 1,
1073 sizeof(struct attribute *), GFP_KERNEL);
1074 if (!tc->con_attrs)
1075 return -ENOMEM;
1076
1077 err = cti_create_con_sysfs_attr(dev, tc, CTI_CON_ATTR_NAME,
1078 attr_idx++);
1079 if (err)
1080 return err;
1081
1082 if (tc->con_in->nr_sigs > 0) {
1083 err = cti_create_con_sysfs_attr(dev, tc,
1084 CTI_CON_ATTR_TRIGIN_SIG,
1085 attr_idx++);
1086 if (err)
1087 return err;
1088
1089 err = cti_create_con_sysfs_attr(dev, tc,
1090 CTI_CON_ATTR_TRIGIN_TYPES,
1091 attr_idx++);
1092 if (err)
1093 return err;
1094 }
1095
1096 if (tc->con_out->nr_sigs > 0) {
1097 err = cti_create_con_sysfs_attr(dev, tc,
1098 CTI_CON_ATTR_TRIGOUT_SIG,
1099 attr_idx++);
1100 if (err)
1101 return err;
1102
1103 err = cti_create_con_sysfs_attr(dev, tc,
1104 CTI_CON_ATTR_TRIGOUT_TYPES,
1105 attr_idx++);
1106 if (err)
1107 return err;
1108 }
1109 attr_group->attrs = tc->con_attrs;
1110 return 0;
1111 }
1112
1113 /* create the array of group pointers for the CTI sysfs groups */
cti_create_cons_groups(struct device * dev,struct cti_device * ctidev)1114 static int cti_create_cons_groups(struct device *dev, struct cti_device *ctidev)
1115 {
1116 int nr_groups;
1117
1118 /* nr groups = dynamic + static + NULL terminator */
1119 nr_groups = ctidev->nr_trig_con + CORESIGHT_CTI_STATIC_GROUPS_MAX;
1120 ctidev->con_groups = devm_kcalloc(dev, nr_groups,
1121 sizeof(struct attribute_group *),
1122 GFP_KERNEL);
1123 if (!ctidev->con_groups)
1124 return -ENOMEM;
1125 return 0;
1126 }
1127
cti_create_cons_sysfs(struct device * dev,struct cti_drvdata * drvdata)1128 int cti_create_cons_sysfs(struct device *dev, struct cti_drvdata *drvdata)
1129 {
1130 struct cti_device *ctidev = &drvdata->ctidev;
1131 int err, con_idx = 0, i;
1132 struct cti_trig_con *tc;
1133
1134 err = cti_create_cons_groups(dev, ctidev);
1135 if (err)
1136 return err;
1137
1138 /* populate first locations with the static set of groups */
1139 for (i = 0; i < (CORESIGHT_CTI_STATIC_GROUPS_MAX - 1); i++)
1140 ctidev->con_groups[i] = coresight_cti_groups[i];
1141
1142 /* add dynamic set for each connection */
1143 list_for_each_entry(tc, &ctidev->trig_cons, node) {
1144 err = cti_create_con_attr_set(dev, con_idx++, ctidev, tc);
1145 if (err)
1146 break;
1147 }
1148 return err;
1149 }
1150
1151 /* attribute and group sysfs tables. */
1152 static const struct attribute_group coresight_cti_group = {
1153 .attrs = coresight_cti_attrs,
1154 };
1155
1156 static const struct attribute_group coresight_cti_mgmt_group = {
1157 .attrs = coresight_cti_mgmt_attrs,
1158 .name = "mgmt",
1159 };
1160
1161 static const struct attribute_group coresight_cti_regs_group = {
1162 .attrs = coresight_cti_regs_attrs,
1163 .name = "regs",
1164 };
1165
1166 static const struct attribute_group coresight_cti_channels_group = {
1167 .attrs = coresight_cti_channel_attrs,
1168 .name = "channels",
1169 };
1170
1171 const struct attribute_group *
1172 coresight_cti_groups[CORESIGHT_CTI_STATIC_GROUPS_MAX] = {
1173 &coresight_cti_group,
1174 &coresight_cti_mgmt_group,
1175 &coresight_cti_regs_group,
1176 &coresight_cti_channels_group,
1177 NULL,
1178 };
1179