1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019 Linaro Limited, All rights reserved.
4 * Author: Mike Leach <mike.leach@linaro.org>
7 #include <linux/coresight.h>
9 #include "coresight-cti.h"
12 * Declare the number of static declared attribute groups
13 * Value includes groups + NULL value at end of table.
15 #define CORESIGHT_CTI_STATIC_GROUPS_MAX 5
18 * List of trigger signal type names. Match the constants declared in
19 * include\dt-bindings\arm\coresight-cti-dt.h
21 static const char * const sig_type_names
[] = {
23 "intreq", /* GEN_INTREQ */
24 "intack", /* GEN_INTACK */
25 "haltreq", /* GEN_HALTREQ */
26 "restartreq", /* GEN_RESTARTREQ */
27 "pe_edbgreq", /* PE_EDBGREQ */
28 "pe_dbgrestart",/* PE_DBGRESTART */
29 "pe_ctiirq", /* PE_CTIIRQ */
30 "pe_pmuirq", /* PE_PMUIRQ */
31 "pe_dbgtrigger",/* PE_DBGTRIGGER */
32 "etm_extout", /* ETM_EXTOUT */
33 "etm_extin", /* ETM_EXTIN */
34 "snk_full", /* SNK_FULL */
35 "snk_acqcomp", /* SNK_ACQCOMP */
36 "snk_flushcomp",/* SNK_FLUSHCOMP */
37 "snk_flushin", /* SNK_FLUSHIN */
38 "snk_trigin", /* SNK_TRIGIN */
39 "stm_asyncout", /* STM_ASYNCOUT */
40 "stm_tout_spte",/* STM_TOUT_SPTE */
41 "stm_tout_sw", /* STM_TOUT_SW */
42 "stm_tout_hete",/* STM_TOUT_HETE */
43 "stm_hwevent", /* STM_HWEVENT */
44 "ela_tstart", /* ELA_TSTART */
45 "ela_tstop", /* ELA_TSTOP */
46 "ela_dbgreq", /* ELA_DBGREQ */
49 /* Show function pointer used in the connections dynamic declared attributes*/
50 typedef ssize_t (*p_show_fn
)(struct device
*dev
, struct device_attribute
*attr
,
53 /* Connection attribute types */
54 enum cti_conn_attr_type
{
56 CTI_CON_ATTR_TRIGIN_SIG
,
57 CTI_CON_ATTR_TRIGOUT_SIG
,
58 CTI_CON_ATTR_TRIGIN_TYPES
,
59 CTI_CON_ATTR_TRIGOUT_TYPES
,
63 /* Names for the connection attributes */
64 static const char * const con_attr_names
[CTI_CON_ATTR_MAX
] = {
72 /* basic attributes */
73 static ssize_t
enable_show(struct device
*dev
,
74 struct device_attribute
*attr
,
78 bool enabled
, powered
;
79 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
81 enable_req
= atomic_read(&drvdata
->config
.enable_req_count
);
82 spin_lock(&drvdata
->spinlock
);
83 powered
= drvdata
->config
.hw_powered
;
84 enabled
= drvdata
->config
.hw_enabled
;
85 spin_unlock(&drvdata
->spinlock
);
88 return sprintf(buf
, "%d\n", enabled
);
90 return sprintf(buf
, "%d\n", !!enable_req
);
93 static ssize_t
enable_store(struct device
*dev
,
94 struct device_attribute
*attr
,
95 const char *buf
, size_t size
)
99 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
101 ret
= kstrtoul(buf
, 0, &val
);
106 ret
= cti_enable(drvdata
->csdev
);
108 ret
= cti_disable(drvdata
->csdev
);
113 static DEVICE_ATTR_RW(enable
);
115 static ssize_t
powered_show(struct device
*dev
,
116 struct device_attribute
*attr
,
120 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
122 spin_lock(&drvdata
->spinlock
);
123 powered
= drvdata
->config
.hw_powered
;
124 spin_unlock(&drvdata
->spinlock
);
126 return sprintf(buf
, "%d\n", powered
);
128 static DEVICE_ATTR_RO(powered
);
130 static ssize_t
ctmid_show(struct device
*dev
,
131 struct device_attribute
*attr
, char *buf
)
133 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
135 return sprintf(buf
, "%d\n", drvdata
->ctidev
.ctm_id
);
137 static DEVICE_ATTR_RO(ctmid
);
139 static ssize_t
nr_trigger_cons_show(struct device
*dev
,
140 struct device_attribute
*attr
,
143 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
145 return sprintf(buf
, "%d\n", drvdata
->ctidev
.nr_trig_con
);
147 static DEVICE_ATTR_RO(nr_trigger_cons
);
149 /* attribute and group sysfs tables. */
150 static struct attribute
*coresight_cti_attrs
[] = {
151 &dev_attr_enable
.attr
,
152 &dev_attr_powered
.attr
,
153 &dev_attr_ctmid
.attr
,
154 &dev_attr_nr_trigger_cons
.attr
,
158 /* register based attributes */
160 /* macro to access RO registers with power check only (no enable check). */
161 #define coresight_cti_reg(name, offset) \
162 static ssize_t name##_show(struct device *dev, \
163 struct device_attribute *attr, char *buf) \
165 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
167 pm_runtime_get_sync(dev->parent); \
168 spin_lock(&drvdata->spinlock); \
169 if (drvdata->config.hw_powered) \
170 val = readl_relaxed(drvdata->base + offset); \
171 spin_unlock(&drvdata->spinlock); \
172 pm_runtime_put_sync(dev->parent); \
173 return sprintf(buf, "0x%x\n", val); \
175 static DEVICE_ATTR_RO(name)
177 /* coresight management registers */
178 coresight_cti_reg(devaff0
, CTIDEVAFF0
);
179 coresight_cti_reg(devaff1
, CTIDEVAFF1
);
180 coresight_cti_reg(authstatus
, CORESIGHT_AUTHSTATUS
);
181 coresight_cti_reg(devarch
, CORESIGHT_DEVARCH
);
182 coresight_cti_reg(devid
, CORESIGHT_DEVID
);
183 coresight_cti_reg(devtype
, CORESIGHT_DEVTYPE
);
184 coresight_cti_reg(pidr0
, CORESIGHT_PERIPHIDR0
);
185 coresight_cti_reg(pidr1
, CORESIGHT_PERIPHIDR1
);
186 coresight_cti_reg(pidr2
, CORESIGHT_PERIPHIDR2
);
187 coresight_cti_reg(pidr3
, CORESIGHT_PERIPHIDR3
);
188 coresight_cti_reg(pidr4
, CORESIGHT_PERIPHIDR4
);
190 static struct attribute
*coresight_cti_mgmt_attrs
[] = {
191 &dev_attr_devaff0
.attr
,
192 &dev_attr_devaff1
.attr
,
193 &dev_attr_authstatus
.attr
,
194 &dev_attr_devarch
.attr
,
195 &dev_attr_devid
.attr
,
196 &dev_attr_devtype
.attr
,
197 &dev_attr_pidr0
.attr
,
198 &dev_attr_pidr1
.attr
,
199 &dev_attr_pidr2
.attr
,
200 &dev_attr_pidr3
.attr
,
201 &dev_attr_pidr4
.attr
,
205 /* CTI low level programming registers */
208 * Show a simple 32 bit value if enabled and powered.
209 * If inaccessible & pcached_val not NULL then show cached value.
211 static ssize_t
cti_reg32_show(struct device
*dev
, char *buf
,
212 u32
*pcached_val
, int reg_offset
)
215 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
216 struct cti_config
*config
= &drvdata
->config
;
218 spin_lock(&drvdata
->spinlock
);
219 if ((reg_offset
>= 0) && cti_active(config
)) {
220 CS_UNLOCK(drvdata
->base
);
221 val
= readl_relaxed(drvdata
->base
+ reg_offset
);
224 CS_LOCK(drvdata
->base
);
225 } else if (pcached_val
) {
228 spin_unlock(&drvdata
->spinlock
);
229 return sprintf(buf
, "%#x\n", val
);
233 * Store a simple 32 bit value.
234 * If pcached_val not NULL, then copy to here too,
235 * if reg_offset >= 0 then write through if enabled.
237 static ssize_t
cti_reg32_store(struct device
*dev
, const char *buf
,
238 size_t size
, u32
*pcached_val
, int reg_offset
)
241 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
242 struct cti_config
*config
= &drvdata
->config
;
244 if (kstrtoul(buf
, 0, &val
))
247 spin_lock(&drvdata
->spinlock
);
250 *pcached_val
= (u32
)val
;
252 /* write through if offset and enabled */
253 if ((reg_offset
>= 0) && cti_active(config
))
254 cti_write_single_reg(drvdata
, reg_offset
, val
);
255 spin_unlock(&drvdata
->spinlock
);
259 /* Standard macro for simple rw cti config registers */
260 #define cti_config_reg32_rw(name, cfgname, offset) \
261 static ssize_t name##_show(struct device *dev, \
262 struct device_attribute *attr, \
265 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
266 return cti_reg32_show(dev, buf, \
267 &drvdata->config.cfgname, offset); \
270 static ssize_t name##_store(struct device *dev, \
271 struct device_attribute *attr, \
272 const char *buf, size_t size) \
274 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
275 return cti_reg32_store(dev, buf, size, \
276 &drvdata->config.cfgname, offset); \
278 static DEVICE_ATTR_RW(name)
280 static ssize_t
inout_sel_show(struct device
*dev
,
281 struct device_attribute
*attr
,
285 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
287 val
= (u32
)drvdata
->config
.ctiinout_sel
;
288 return sprintf(buf
, "%d\n", val
);
291 static ssize_t
inout_sel_store(struct device
*dev
,
292 struct device_attribute
*attr
,
293 const char *buf
, size_t size
)
296 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
298 if (kstrtoul(buf
, 0, &val
))
300 if (val
> (CTIINOUTEN_MAX
- 1))
303 spin_lock(&drvdata
->spinlock
);
304 drvdata
->config
.ctiinout_sel
= val
;
305 spin_unlock(&drvdata
->spinlock
);
308 static DEVICE_ATTR_RW(inout_sel
);
310 static ssize_t
inen_show(struct device
*dev
,
311 struct device_attribute
*attr
,
316 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
318 spin_lock(&drvdata
->spinlock
);
319 index
= drvdata
->config
.ctiinout_sel
;
320 val
= drvdata
->config
.ctiinen
[index
];
321 spin_unlock(&drvdata
->spinlock
);
322 return sprintf(buf
, "%#lx\n", val
);
325 static ssize_t
inen_store(struct device
*dev
,
326 struct device_attribute
*attr
,
327 const char *buf
, size_t size
)
331 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
332 struct cti_config
*config
= &drvdata
->config
;
334 if (kstrtoul(buf
, 0, &val
))
337 spin_lock(&drvdata
->spinlock
);
338 index
= config
->ctiinout_sel
;
339 config
->ctiinen
[index
] = val
;
341 /* write through if enabled */
342 if (cti_active(config
))
343 cti_write_single_reg(drvdata
, CTIINEN(index
), val
);
344 spin_unlock(&drvdata
->spinlock
);
347 static DEVICE_ATTR_RW(inen
);
349 static ssize_t
outen_show(struct device
*dev
,
350 struct device_attribute
*attr
,
355 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
357 spin_lock(&drvdata
->spinlock
);
358 index
= drvdata
->config
.ctiinout_sel
;
359 val
= drvdata
->config
.ctiouten
[index
];
360 spin_unlock(&drvdata
->spinlock
);
361 return sprintf(buf
, "%#lx\n", val
);
364 static ssize_t
outen_store(struct device
*dev
,
365 struct device_attribute
*attr
,
366 const char *buf
, size_t size
)
370 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
371 struct cti_config
*config
= &drvdata
->config
;
373 if (kstrtoul(buf
, 0, &val
))
376 spin_lock(&drvdata
->spinlock
);
377 index
= config
->ctiinout_sel
;
378 config
->ctiouten
[index
] = val
;
380 /* write through if enabled */
381 if (cti_active(config
))
382 cti_write_single_reg(drvdata
, CTIOUTEN(index
), val
);
383 spin_unlock(&drvdata
->spinlock
);
386 static DEVICE_ATTR_RW(outen
);
388 static ssize_t
intack_store(struct device
*dev
,
389 struct device_attribute
*attr
,
390 const char *buf
, size_t size
)
394 if (kstrtoul(buf
, 0, &val
))
397 cti_write_intack(dev
, val
);
400 static DEVICE_ATTR_WO(intack
);
402 cti_config_reg32_rw(gate
, ctigate
, CTIGATE
);
403 cti_config_reg32_rw(asicctl
, asicctl
, ASICCTL
);
404 cti_config_reg32_rw(appset
, ctiappset
, CTIAPPSET
);
406 static ssize_t
appclear_store(struct device
*dev
,
407 struct device_attribute
*attr
,
408 const char *buf
, size_t size
)
411 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
412 struct cti_config
*config
= &drvdata
->config
;
414 if (kstrtoul(buf
, 0, &val
))
417 spin_lock(&drvdata
->spinlock
);
419 /* a 1'b1 in appclr clears down the same bit in appset*/
420 config
->ctiappset
&= ~val
;
422 /* write through if enabled */
423 if (cti_active(config
))
424 cti_write_single_reg(drvdata
, CTIAPPCLEAR
, val
);
425 spin_unlock(&drvdata
->spinlock
);
428 static DEVICE_ATTR_WO(appclear
);
430 static ssize_t
apppulse_store(struct device
*dev
,
431 struct device_attribute
*attr
,
432 const char *buf
, size_t size
)
435 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
436 struct cti_config
*config
= &drvdata
->config
;
438 if (kstrtoul(buf
, 0, &val
))
441 spin_lock(&drvdata
->spinlock
);
443 /* write through if enabled */
444 if (cti_active(config
))
445 cti_write_single_reg(drvdata
, CTIAPPPULSE
, val
);
446 spin_unlock(&drvdata
->spinlock
);
449 static DEVICE_ATTR_WO(apppulse
);
451 coresight_cti_reg(triginstatus
, CTITRIGINSTATUS
);
452 coresight_cti_reg(trigoutstatus
, CTITRIGOUTSTATUS
);
453 coresight_cti_reg(chinstatus
, CTICHINSTATUS
);
454 coresight_cti_reg(choutstatus
, CTICHOUTSTATUS
);
457 * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
458 * integration control registers. Normally only used to investigate connection
461 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
463 /* macro to access RW registers with power check only (no enable check). */
464 #define coresight_cti_reg_rw(name, offset) \
465 static ssize_t name##_show(struct device *dev, \
466 struct device_attribute *attr, char *buf) \
468 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
470 pm_runtime_get_sync(dev->parent); \
471 spin_lock(&drvdata->spinlock); \
472 if (drvdata->config.hw_powered) \
473 val = readl_relaxed(drvdata->base + offset); \
474 spin_unlock(&drvdata->spinlock); \
475 pm_runtime_put_sync(dev->parent); \
476 return sprintf(buf, "0x%x\n", val); \
479 static ssize_t name##_store(struct device *dev, \
480 struct device_attribute *attr, \
481 const char *buf, size_t size) \
483 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
484 unsigned long val = 0; \
485 if (kstrtoul(buf, 0, &val)) \
488 pm_runtime_get_sync(dev->parent); \
489 spin_lock(&drvdata->spinlock); \
490 if (drvdata->config.hw_powered) \
491 cti_write_single_reg(drvdata, offset, val); \
492 spin_unlock(&drvdata->spinlock); \
493 pm_runtime_put_sync(dev->parent); \
496 static DEVICE_ATTR_RW(name)
498 /* macro to access WO registers with power check only (no enable check). */
499 #define coresight_cti_reg_wo(name, offset) \
500 static ssize_t name##_store(struct device *dev, \
501 struct device_attribute *attr, \
502 const char *buf, size_t size) \
504 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
505 unsigned long val = 0; \
506 if (kstrtoul(buf, 0, &val)) \
509 pm_runtime_get_sync(dev->parent); \
510 spin_lock(&drvdata->spinlock); \
511 if (drvdata->config.hw_powered) \
512 cti_write_single_reg(drvdata, offset, val); \
513 spin_unlock(&drvdata->spinlock); \
514 pm_runtime_put_sync(dev->parent); \
517 static DEVICE_ATTR_WO(name)
519 coresight_cti_reg_rw(itchout
, ITCHOUT
);
520 coresight_cti_reg_rw(ittrigout
, ITTRIGOUT
);
521 coresight_cti_reg_rw(itctrl
, CORESIGHT_ITCTRL
);
522 coresight_cti_reg_wo(itchinack
, ITCHINACK
);
523 coresight_cti_reg_wo(ittriginack
, ITTRIGINACK
);
524 coresight_cti_reg(ittrigin
, ITTRIGIN
);
525 coresight_cti_reg(itchin
, ITCHIN
);
526 coresight_cti_reg(itchoutack
, ITCHOUTACK
);
527 coresight_cti_reg(ittrigoutack
, ITTRIGOUTACK
);
529 #endif /* CORESIGHT_CTI_INTEGRATION_REGS */
531 static struct attribute
*coresight_cti_regs_attrs
[] = {
532 &dev_attr_inout_sel
.attr
,
534 &dev_attr_outen
.attr
,
536 &dev_attr_asicctl
.attr
,
537 &dev_attr_intack
.attr
,
538 &dev_attr_appset
.attr
,
539 &dev_attr_appclear
.attr
,
540 &dev_attr_apppulse
.attr
,
541 &dev_attr_triginstatus
.attr
,
542 &dev_attr_trigoutstatus
.attr
,
543 &dev_attr_chinstatus
.attr
,
544 &dev_attr_choutstatus
.attr
,
545 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
546 &dev_attr_itctrl
.attr
,
547 &dev_attr_ittrigin
.attr
,
548 &dev_attr_itchin
.attr
,
549 &dev_attr_ittrigout
.attr
,
550 &dev_attr_itchout
.attr
,
551 &dev_attr_itchoutack
.attr
,
552 &dev_attr_ittrigoutack
.attr
,
553 &dev_attr_ittriginack
.attr
,
554 &dev_attr_itchinack
.attr
,
559 /* CTI channel x-trigger programming */
561 cti_trig_op_parse(struct device
*dev
, enum cti_chan_op op
,
562 enum cti_trig_dir dir
, const char *buf
, size_t size
)
566 int items
, err
= -EINVAL
;
568 /* extract chan idx and trigger idx */
569 items
= sscanf(buf
, "%d %d", &chan_idx
, &trig_idx
);
571 err
= cti_channel_trig_op(dev
, op
, dir
, chan_idx
, trig_idx
);
578 static ssize_t
trigin_attach_store(struct device
*dev
,
579 struct device_attribute
*attr
,
580 const char *buf
, size_t size
)
582 return cti_trig_op_parse(dev
, CTI_CHAN_ATTACH
, CTI_TRIG_IN
,
585 static DEVICE_ATTR_WO(trigin_attach
);
587 static ssize_t
trigin_detach_store(struct device
*dev
,
588 struct device_attribute
*attr
,
589 const char *buf
, size_t size
)
591 return cti_trig_op_parse(dev
, CTI_CHAN_DETACH
, CTI_TRIG_IN
,
594 static DEVICE_ATTR_WO(trigin_detach
);
596 static ssize_t
trigout_attach_store(struct device
*dev
,
597 struct device_attribute
*attr
,
598 const char *buf
, size_t size
)
600 return cti_trig_op_parse(dev
, CTI_CHAN_ATTACH
, CTI_TRIG_OUT
,
603 static DEVICE_ATTR_WO(trigout_attach
);
605 static ssize_t
trigout_detach_store(struct device
*dev
,
606 struct device_attribute
*attr
,
607 const char *buf
, size_t size
)
609 return cti_trig_op_parse(dev
, CTI_CHAN_DETACH
, CTI_TRIG_OUT
,
612 static DEVICE_ATTR_WO(trigout_detach
);
615 static ssize_t
chan_gate_enable_store(struct device
*dev
,
616 struct device_attribute
*attr
,
617 const char *buf
, size_t size
)
619 int err
= 0, channel
= 0;
621 if (kstrtoint(buf
, 0, &channel
))
624 err
= cti_channel_gate_op(dev
, CTI_GATE_CHAN_ENABLE
, channel
);
625 return err
? err
: size
;
628 static ssize_t
chan_gate_enable_show(struct device
*dev
,
629 struct device_attribute
*attr
,
632 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
633 struct cti_config
*cfg
= &drvdata
->config
;
634 unsigned long ctigate_bitmask
= cfg
->ctigate
;
637 if (cfg
->ctigate
== 0)
638 size
= sprintf(buf
, "\n");
640 size
= bitmap_print_to_pagebuf(true, buf
, &ctigate_bitmask
,
641 cfg
->nr_ctm_channels
);
644 static DEVICE_ATTR_RW(chan_gate_enable
);
646 static ssize_t
chan_gate_disable_store(struct device
*dev
,
647 struct device_attribute
*attr
,
648 const char *buf
, size_t size
)
650 int err
= 0, channel
= 0;
652 if (kstrtoint(buf
, 0, &channel
))
655 err
= cti_channel_gate_op(dev
, CTI_GATE_CHAN_DISABLE
, channel
);
656 return err
? err
: size
;
658 static DEVICE_ATTR_WO(chan_gate_disable
);
661 chan_op_parse(struct device
*dev
, enum cti_chan_set_op op
, const char *buf
)
663 int err
= 0, channel
= 0;
665 if (kstrtoint(buf
, 0, &channel
))
668 err
= cti_channel_setop(dev
, op
, channel
);
673 static ssize_t
chan_set_store(struct device
*dev
,
674 struct device_attribute
*attr
,
675 const char *buf
, size_t size
)
677 int err
= chan_op_parse(dev
, CTI_CHAN_SET
, buf
);
679 return err
? err
: size
;
681 static DEVICE_ATTR_WO(chan_set
);
683 static ssize_t
chan_clear_store(struct device
*dev
,
684 struct device_attribute
*attr
,
685 const char *buf
, size_t size
)
687 int err
= chan_op_parse(dev
, CTI_CHAN_CLR
, buf
);
689 return err
? err
: size
;
691 static DEVICE_ATTR_WO(chan_clear
);
693 static ssize_t
chan_pulse_store(struct device
*dev
,
694 struct device_attribute
*attr
,
695 const char *buf
, size_t size
)
697 int err
= chan_op_parse(dev
, CTI_CHAN_PULSE
, buf
);
699 return err
? err
: size
;
701 static DEVICE_ATTR_WO(chan_pulse
);
703 static ssize_t
trig_filter_enable_show(struct device
*dev
,
704 struct device_attribute
*attr
,
708 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
710 spin_lock(&drvdata
->spinlock
);
711 val
= drvdata
->config
.trig_filter_enable
;
712 spin_unlock(&drvdata
->spinlock
);
713 return sprintf(buf
, "%d\n", val
);
716 static ssize_t
trig_filter_enable_store(struct device
*dev
,
717 struct device_attribute
*attr
,
718 const char *buf
, size_t size
)
721 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
723 if (kstrtoul(buf
, 0, &val
))
726 spin_lock(&drvdata
->spinlock
);
727 drvdata
->config
.trig_filter_enable
= !!val
;
728 spin_unlock(&drvdata
->spinlock
);
731 static DEVICE_ATTR_RW(trig_filter_enable
);
733 static ssize_t
trigout_filtered_show(struct device
*dev
,
734 struct device_attribute
*attr
,
737 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
738 struct cti_config
*cfg
= &drvdata
->config
;
739 int size
= 0, nr_trig_max
= cfg
->nr_trig_max
;
740 unsigned long mask
= cfg
->trig_out_filter
;
743 size
= bitmap_print_to_pagebuf(true, buf
, &mask
, nr_trig_max
);
746 static DEVICE_ATTR_RO(trigout_filtered
);
748 /* clear all xtrigger / channel programming */
749 static ssize_t
chan_xtrigs_reset_store(struct device
*dev
,
750 struct device_attribute
*attr
,
751 const char *buf
, size_t size
)
754 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
755 struct cti_config
*config
= &drvdata
->config
;
757 spin_lock(&drvdata
->spinlock
);
759 /* clear the CTI trigger / channel programming registers */
760 for (i
= 0; i
< config
->nr_trig_max
; i
++) {
761 config
->ctiinen
[i
] = 0;
762 config
->ctiouten
[i
] = 0;
765 /* clear the other regs */
766 config
->ctigate
= GENMASK(config
->nr_ctm_channels
- 1, 0);
768 config
->ctiappset
= 0;
769 config
->ctiinout_sel
= 0;
770 config
->xtrig_rchan_sel
= 0;
772 /* if enabled then write through */
773 if (cti_active(config
))
774 cti_write_all_hw_regs(drvdata
);
776 spin_unlock(&drvdata
->spinlock
);
779 static DEVICE_ATTR_WO(chan_xtrigs_reset
);
782 * Write to select a channel to view, read to display the
783 * cross triggers for the selected channel.
785 static ssize_t
chan_xtrigs_sel_store(struct device
*dev
,
786 struct device_attribute
*attr
,
787 const char *buf
, size_t size
)
790 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
792 if (kstrtoul(buf
, 0, &val
))
794 if (val
> (drvdata
->config
.nr_ctm_channels
- 1))
797 spin_lock(&drvdata
->spinlock
);
798 drvdata
->config
.xtrig_rchan_sel
= val
;
799 spin_unlock(&drvdata
->spinlock
);
803 static ssize_t
chan_xtrigs_sel_show(struct device
*dev
,
804 struct device_attribute
*attr
,
808 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
810 spin_lock(&drvdata
->spinlock
);
811 val
= drvdata
->config
.xtrig_rchan_sel
;
812 spin_unlock(&drvdata
->spinlock
);
814 return sprintf(buf
, "%ld\n", val
);
816 static DEVICE_ATTR_RW(chan_xtrigs_sel
);
818 static ssize_t
chan_xtrigs_in_show(struct device
*dev
,
819 struct device_attribute
*attr
,
822 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
823 struct cti_config
*cfg
= &drvdata
->config
;
824 int used
= 0, reg_idx
;
825 int nr_trig_max
= drvdata
->config
.nr_trig_max
;
826 u32 chan_mask
= BIT(cfg
->xtrig_rchan_sel
);
828 for (reg_idx
= 0; reg_idx
< nr_trig_max
; reg_idx
++) {
829 if (chan_mask
& cfg
->ctiinen
[reg_idx
])
830 used
+= sprintf(buf
+ used
, "%d ", reg_idx
);
833 used
+= sprintf(buf
+ used
, "\n");
836 static DEVICE_ATTR_RO(chan_xtrigs_in
);
838 static ssize_t
chan_xtrigs_out_show(struct device
*dev
,
839 struct device_attribute
*attr
,
842 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
843 struct cti_config
*cfg
= &drvdata
->config
;
844 int used
= 0, reg_idx
;
845 int nr_trig_max
= drvdata
->config
.nr_trig_max
;
846 u32 chan_mask
= BIT(cfg
->xtrig_rchan_sel
);
848 for (reg_idx
= 0; reg_idx
< nr_trig_max
; reg_idx
++) {
849 if (chan_mask
& cfg
->ctiouten
[reg_idx
])
850 used
+= sprintf(buf
+ used
, "%d ", reg_idx
);
853 used
+= sprintf(buf
+ used
, "\n");
856 static DEVICE_ATTR_RO(chan_xtrigs_out
);
858 static ssize_t
print_chan_list(struct device
*dev
,
859 char *buf
, bool inuse
)
861 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
862 struct cti_config
*config
= &drvdata
->config
;
864 unsigned long inuse_bits
= 0, chan_mask
;
866 /* scan regs to get bitmap of channels in use. */
867 spin_lock(&drvdata
->spinlock
);
868 for (i
= 0; i
< config
->nr_trig_max
; i
++) {
869 inuse_bits
|= config
->ctiinen
[i
];
870 inuse_bits
|= config
->ctiouten
[i
];
872 spin_unlock(&drvdata
->spinlock
);
874 /* inverse bits if printing free channels */
876 inuse_bits
= ~inuse_bits
;
878 /* list of channels, or 'none' */
879 chan_mask
= GENMASK(config
->nr_ctm_channels
- 1, 0);
880 if (inuse_bits
& chan_mask
)
881 size
= bitmap_print_to_pagebuf(true, buf
, &inuse_bits
,
882 config
->nr_ctm_channels
);
884 size
= sprintf(buf
, "\n");
888 static ssize_t
chan_inuse_show(struct device
*dev
,
889 struct device_attribute
*attr
,
892 return print_chan_list(dev
, buf
, true);
894 static DEVICE_ATTR_RO(chan_inuse
);
896 static ssize_t
chan_free_show(struct device
*dev
,
897 struct device_attribute
*attr
,
900 return print_chan_list(dev
, buf
, false);
902 static DEVICE_ATTR_RO(chan_free
);
904 static struct attribute
*coresight_cti_channel_attrs
[] = {
905 &dev_attr_trigin_attach
.attr
,
906 &dev_attr_trigin_detach
.attr
,
907 &dev_attr_trigout_attach
.attr
,
908 &dev_attr_trigout_detach
.attr
,
909 &dev_attr_trig_filter_enable
.attr
,
910 &dev_attr_trigout_filtered
.attr
,
911 &dev_attr_chan_gate_enable
.attr
,
912 &dev_attr_chan_gate_disable
.attr
,
913 &dev_attr_chan_set
.attr
,
914 &dev_attr_chan_clear
.attr
,
915 &dev_attr_chan_pulse
.attr
,
916 &dev_attr_chan_inuse
.attr
,
917 &dev_attr_chan_free
.attr
,
918 &dev_attr_chan_xtrigs_sel
.attr
,
919 &dev_attr_chan_xtrigs_in
.attr
,
920 &dev_attr_chan_xtrigs_out
.attr
,
921 &dev_attr_chan_xtrigs_reset
.attr
,
925 /* Create the connections trigger groups and attrs dynamically */
927 * Each connection has dynamic group triggers<N> + name, trigin/out sigs/types
928 * attributes, + each device has static nr_trigger_cons giving the number
929 * of groups. e.g. in sysfs:-
930 * /cti_<name>/triggers0
931 * /cti_<name>/triggers1
932 * /cti_<name>/nr_trigger_cons
933 * where nr_trigger_cons = 2
935 static ssize_t
con_name_show(struct device
*dev
,
936 struct device_attribute
*attr
,
939 struct dev_ext_attribute
*ext_attr
=
940 container_of(attr
, struct dev_ext_attribute
, attr
);
941 struct cti_trig_con
*con
= (struct cti_trig_con
*)ext_attr
->var
;
943 return sprintf(buf
, "%s\n", con
->con_dev_name
);
946 static ssize_t
trigin_sig_show(struct device
*dev
,
947 struct device_attribute
*attr
,
950 struct dev_ext_attribute
*ext_attr
=
951 container_of(attr
, struct dev_ext_attribute
, attr
);
952 struct cti_trig_con
*con
= (struct cti_trig_con
*)ext_attr
->var
;
953 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
954 struct cti_config
*cfg
= &drvdata
->config
;
955 unsigned long mask
= con
->con_in
->used_mask
;
957 return bitmap_print_to_pagebuf(true, buf
, &mask
, cfg
->nr_trig_max
);
960 static ssize_t
trigout_sig_show(struct device
*dev
,
961 struct device_attribute
*attr
,
964 struct dev_ext_attribute
*ext_attr
=
965 container_of(attr
, struct dev_ext_attribute
, attr
);
966 struct cti_trig_con
*con
= (struct cti_trig_con
*)ext_attr
->var
;
967 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
968 struct cti_config
*cfg
= &drvdata
->config
;
969 unsigned long mask
= con
->con_out
->used_mask
;
971 return bitmap_print_to_pagebuf(true, buf
, &mask
, cfg
->nr_trig_max
);
974 /* convert a sig type id to a name */
976 cti_sig_type_name(struct cti_trig_con
*con
, int used_count
, bool in
)
979 struct cti_trig_grp
*grp
= in
? con
->con_in
: con
->con_out
;
981 if (used_count
< grp
->nr_sigs
)
982 idx
= grp
->sig_types
[used_count
];
983 return sig_type_names
[idx
];
986 static ssize_t
trigin_type_show(struct device
*dev
,
987 struct device_attribute
*attr
,
990 struct dev_ext_attribute
*ext_attr
=
991 container_of(attr
, struct dev_ext_attribute
, attr
);
992 struct cti_trig_con
*con
= (struct cti_trig_con
*)ext_attr
->var
;
993 int sig_idx
, used
= 0;
996 for (sig_idx
= 0; sig_idx
< con
->con_in
->nr_sigs
; sig_idx
++) {
997 name
= cti_sig_type_name(con
, sig_idx
, true);
998 used
+= sprintf(buf
+ used
, "%s ", name
);
1000 used
+= sprintf(buf
+ used
, "\n");
1004 static ssize_t
trigout_type_show(struct device
*dev
,
1005 struct device_attribute
*attr
,
1008 struct dev_ext_attribute
*ext_attr
=
1009 container_of(attr
, struct dev_ext_attribute
, attr
);
1010 struct cti_trig_con
*con
= (struct cti_trig_con
*)ext_attr
->var
;
1011 int sig_idx
, used
= 0;
1014 for (sig_idx
= 0; sig_idx
< con
->con_out
->nr_sigs
; sig_idx
++) {
1015 name
= cti_sig_type_name(con
, sig_idx
, false);
1016 used
+= sprintf(buf
+ used
, "%s ", name
);
1018 used
+= sprintf(buf
+ used
, "\n");
1023 * Array of show function names declared above to allow selection
1024 * for the connection attributes
1026 static p_show_fn show_fns
[CTI_CON_ATTR_MAX
] = {
1034 static int cti_create_con_sysfs_attr(struct device
*dev
,
1035 struct cti_trig_con
*con
,
1036 enum cti_conn_attr_type attr_type
,
1039 struct dev_ext_attribute
*eattr
= 0;
1042 eattr
= devm_kzalloc(dev
, sizeof(struct dev_ext_attribute
),
1045 name
= devm_kstrdup(dev
, con_attr_names
[attr_type
],
1048 /* fill out the underlying attribute struct */
1049 eattr
->attr
.attr
.name
= name
;
1050 eattr
->attr
.attr
.mode
= 0444;
1052 /* now the device_attribute struct */
1053 eattr
->attr
.show
= show_fns
[attr_type
];
1061 con
->con_attrs
[attr_idx
] = &eattr
->attr
.attr
;
1065 static struct attribute_group
*
1066 cti_create_con_sysfs_group(struct device
*dev
, struct cti_device
*ctidev
,
1067 int con_idx
, struct cti_trig_con
*tc
)
1069 struct attribute_group
*group
= NULL
;
1072 group
= devm_kzalloc(dev
, sizeof(struct attribute_group
), GFP_KERNEL
);
1076 group
->name
= devm_kasprintf(dev
, GFP_KERNEL
, "triggers%d", con_idx
);
1080 grp_idx
= con_idx
+ CORESIGHT_CTI_STATIC_GROUPS_MAX
- 1;
1081 ctidev
->con_groups
[grp_idx
] = group
;
1082 tc
->attr_group
= group
;
1086 /* create a triggers connection group and the attributes for that group */
1087 static int cti_create_con_attr_set(struct device
*dev
, int con_idx
,
1088 struct cti_device
*ctidev
,
1089 struct cti_trig_con
*tc
)
1091 struct attribute_group
*attr_group
= NULL
;
1095 attr_group
= cti_create_con_sysfs_group(dev
, ctidev
, con_idx
, tc
);
1099 /* allocate NULL terminated array of attributes */
1100 tc
->con_attrs
= devm_kcalloc(dev
, CTI_CON_ATTR_MAX
+ 1,
1101 sizeof(struct attribute
*), GFP_KERNEL
);
1105 err
= cti_create_con_sysfs_attr(dev
, tc
, CTI_CON_ATTR_NAME
,
1110 if (tc
->con_in
->nr_sigs
> 0) {
1111 err
= cti_create_con_sysfs_attr(dev
, tc
,
1112 CTI_CON_ATTR_TRIGIN_SIG
,
1117 err
= cti_create_con_sysfs_attr(dev
, tc
,
1118 CTI_CON_ATTR_TRIGIN_TYPES
,
1124 if (tc
->con_out
->nr_sigs
> 0) {
1125 err
= cti_create_con_sysfs_attr(dev
, tc
,
1126 CTI_CON_ATTR_TRIGOUT_SIG
,
1131 err
= cti_create_con_sysfs_attr(dev
, tc
,
1132 CTI_CON_ATTR_TRIGOUT_TYPES
,
1137 attr_group
->attrs
= tc
->con_attrs
;
1141 /* create the array of group pointers for the CTI sysfs groups */
1142 int cti_create_cons_groups(struct device
*dev
, struct cti_device
*ctidev
)
1146 /* nr groups = dynamic + static + NULL terminator */
1147 nr_groups
= ctidev
->nr_trig_con
+ CORESIGHT_CTI_STATIC_GROUPS_MAX
;
1148 ctidev
->con_groups
= devm_kcalloc(dev
, nr_groups
,
1149 sizeof(struct attribute_group
*),
1151 if (!ctidev
->con_groups
)
1156 int cti_create_cons_sysfs(struct device
*dev
, struct cti_drvdata
*drvdata
)
1158 struct cti_device
*ctidev
= &drvdata
->ctidev
;
1159 int err
= 0, con_idx
= 0, i
;
1160 struct cti_trig_con
*tc
= NULL
;
1162 err
= cti_create_cons_groups(dev
, ctidev
);
1166 /* populate first locations with the static set of groups */
1167 for (i
= 0; i
< (CORESIGHT_CTI_STATIC_GROUPS_MAX
- 1); i
++)
1168 ctidev
->con_groups
[i
] = coresight_cti_groups
[i
];
1170 /* add dynamic set for each connection */
1171 list_for_each_entry(tc
, &ctidev
->trig_cons
, node
) {
1172 err
= cti_create_con_attr_set(dev
, con_idx
++, ctidev
, tc
);
1179 /* attribute and group sysfs tables. */
1180 static const struct attribute_group coresight_cti_group
= {
1181 .attrs
= coresight_cti_attrs
,
1184 static const struct attribute_group coresight_cti_mgmt_group
= {
1185 .attrs
= coresight_cti_mgmt_attrs
,
1189 static const struct attribute_group coresight_cti_regs_group
= {
1190 .attrs
= coresight_cti_regs_attrs
,
1194 static const struct attribute_group coresight_cti_channels_group
= {
1195 .attrs
= coresight_cti_channel_attrs
,
1199 const struct attribute_group
*
1200 coresight_cti_groups
[CORESIGHT_CTI_STATIC_GROUPS_MAX
] = {
1201 &coresight_cti_group
,
1202 &coresight_cti_mgmt_group
,
1203 &coresight_cti_regs_group
,
1204 &coresight_cti_channels_group
,