Skip to content

Commit dd60b99

Browse files
Tao ZhangSuzuki K Poulose
authored andcommitted
coresight-tpdm: Add nodes for dsb edge control
Add the nodes to set value for DSB edge control and DSB edge control mask. Each DSB subunit TPDM has maximum of n(n<16) EDCR resgisters to configure edge control. DSB edge detection control 00: Rising edge detection 01: Falling edge detection 10: Rising and falling edge detection (toggle detection) And each DSB subunit TPDM has maximum of m(m<8) ECDMR registers to configure mask. Eight 32 bit registers providing DSB interface edge detection mask control. Add the nodes to configure DSB edge control and DSB edge control mask. Each DSB subunit TPDM maximum of 256 edge detections can be configured. The index and value sysfs files need to be paired and written to order. The index sysfs file is to set the index number of the edge detection which needs to be configured. And the value sysfs file is to set the control or mask for the edge detection. DSB edge detection control should be set as the following values. 00: Rising edge detection 01: Falling edge detection 10: Rising and falling edge detection (toggle detection) And DSB edge mask should be set as 0 or 1. Each DSB subunit TPDM has maximum of n(n<16) EDCR resgisters to configure edge control. And each DSB subunit TPDM has maximum of m(m<8) ECDMR registers to configure mask. Add the nodes to read a set of the edge control value and mask of the DSB in TPDM. Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/1695882586-10306-10-git-send-email-quic_taozha@quicinc.com
1 parent 535d80d commit dd60b99

3 files changed

Lines changed: 284 additions & 1 deletion

File tree

Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,54 @@ Description:
5757
Bit[3] : Set to 0 for low performance mode.
5858
Set to 1 for high performance mode.
5959
Bit[4:8] : Select byte lane for high performance mode.
60+
61+
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/ctrl_idx
62+
Date: March 2023
63+
KernelVersion 6.7
64+
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
65+
Description:
66+
(RW) Set/Get the index number of the edge detection for the DSB
67+
subunit TPDM. Since there are at most 256 edge detections, this
68+
value ranges from 0 to 255.
69+
70+
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/ctrl_val
71+
Date: March 2023
72+
KernelVersion 6.7
73+
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
74+
Description:
75+
Write a data to control the edge detection corresponding to
76+
the index number. Before writing data to this sysfs file,
77+
"ctrl_idx" should be written first to configure the index
78+
number of the edge detection which needs to be controlled.
79+
80+
Accepts only one of the following values.
81+
0 - Rising edge detection
82+
1 - Falling edge detection
83+
2 - Rising and falling edge detection (toggle detection)
84+
85+
86+
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/ctrl_mask
87+
Date: March 2023
88+
KernelVersion 6.7
89+
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
90+
Description:
91+
Write a data to mask the edge detection corresponding to the index
92+
number. Before writing data to this sysfs file, "ctrl_idx" should
93+
be written first to configure the index number of the edge detection
94+
which needs to be masked.
95+
96+
Accepts only one of the 2 values - 0 or 1.
97+
98+
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/edcr[0:15]
99+
Date: March 2023
100+
KernelVersion 6.7
101+
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
102+
Description:
103+
Read a set of the edge control value of the DSB in TPDM.
104+
105+
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge/edcmr[0:7]
106+
Date: March 2023
107+
KernelVersion 6.7
108+
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
109+
Description:
110+
Read a set of the edge control mask of the DSB in TPDM.

drivers/hwtracing/coresight/coresight-tpdm.c

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,30 @@
2121

2222
DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
2323

24+
/* Read dataset array member with the index number */
25+
static ssize_t tpdm_simple_dataset_show(struct device *dev,
26+
struct device_attribute *attr,
27+
char *buf)
28+
{
29+
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
30+
struct tpdm_dataset_attribute *tpdm_attr =
31+
container_of(attr, struct tpdm_dataset_attribute, attr);
32+
33+
switch (tpdm_attr->mem) {
34+
case DSB_EDGE_CTRL:
35+
if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCR)
36+
return -EINVAL;
37+
return sysfs_emit(buf, "0x%x\n",
38+
drvdata->dsb->edge_ctrl[tpdm_attr->idx]);
39+
case DSB_EDGE_CTRL_MASK:
40+
if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCMR)
41+
return -EINVAL;
42+
return sysfs_emit(buf, "0x%x\n",
43+
drvdata->dsb->edge_ctrl_mask[tpdm_attr->idx]);
44+
}
45+
return -EINVAL;
46+
}
47+
2448
static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
2549
{
2650
return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
@@ -71,7 +95,14 @@ static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val)
7195

7296
static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
7397
{
74-
u32 val;
98+
u32 val, i;
99+
100+
for (i = 0; i < TPDM_DSB_MAX_EDCR; i++)
101+
writel_relaxed(drvdata->dsb->edge_ctrl[i],
102+
drvdata->base + TPDM_DSB_EDCR(i));
103+
for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++)
104+
writel_relaxed(drvdata->dsb->edge_ctrl_mask[i],
105+
drvdata->base + TPDM_DSB_EDCMR(i));
75106

76107
val = readl_relaxed(drvdata->base + TPDM_DSB_TIER);
77108
/* Set trigger timestamp */
@@ -296,6 +327,109 @@ static ssize_t dsb_mode_store(struct device *dev,
296327
}
297328
static DEVICE_ATTR_RW(dsb_mode);
298329

330+
static ssize_t ctrl_idx_show(struct device *dev,
331+
struct device_attribute *attr,
332+
char *buf)
333+
{
334+
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
335+
336+
return sysfs_emit(buf, "%u\n",
337+
(unsigned int)drvdata->dsb->edge_ctrl_idx);
338+
}
339+
340+
/*
341+
* The EDCR registers can include up to 16 32-bit registers, and each
342+
* one can be configured to control up to 16 edge detections(2 bits
343+
* control one edge detection). So a total 256 edge detections can be
344+
* configured. This function provides a way to set the index number of
345+
* the edge detection which needs to be configured.
346+
*/
347+
static ssize_t ctrl_idx_store(struct device *dev,
348+
struct device_attribute *attr,
349+
const char *buf,
350+
size_t size)
351+
{
352+
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
353+
unsigned long val;
354+
355+
if ((kstrtoul(buf, 0, &val)) || (val >= TPDM_DSB_MAX_LINES))
356+
return -EINVAL;
357+
358+
spin_lock(&drvdata->spinlock);
359+
drvdata->dsb->edge_ctrl_idx = val;
360+
spin_unlock(&drvdata->spinlock);
361+
362+
return size;
363+
}
364+
static DEVICE_ATTR_RW(ctrl_idx);
365+
366+
/*
367+
* This function is used to control the edge detection according
368+
* to the index number that has been set.
369+
* "edge_ctrl" should be one of the following values.
370+
* 0 - Rising edge detection
371+
* 1 - Falling edge detection
372+
* 2 - Rising and falling edge detection (toggle detection)
373+
*/
374+
static ssize_t ctrl_val_store(struct device *dev,
375+
struct device_attribute *attr,
376+
const char *buf,
377+
size_t size)
378+
{
379+
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
380+
unsigned long val, edge_ctrl;
381+
int reg;
382+
383+
if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2))
384+
return -EINVAL;
385+
386+
spin_lock(&drvdata->spinlock);
387+
/*
388+
* There are 2 bit per DSB Edge Control line.
389+
* Thus we have 16 lines in a 32bit word.
390+
*/
391+
reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx);
392+
val = drvdata->dsb->edge_ctrl[reg];
393+
val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx);
394+
val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx);
395+
drvdata->dsb->edge_ctrl[reg] = val;
396+
spin_unlock(&drvdata->spinlock);
397+
398+
return size;
399+
}
400+
static DEVICE_ATTR_WO(ctrl_val);
401+
402+
static ssize_t ctrl_mask_store(struct device *dev,
403+
struct device_attribute *attr,
404+
const char *buf,
405+
size_t size)
406+
{
407+
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
408+
unsigned long val;
409+
u32 set;
410+
int reg;
411+
412+
if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
413+
return -EINVAL;
414+
415+
spin_lock(&drvdata->spinlock);
416+
/*
417+
* There is 1 bit per DSB Edge Control Mark line.
418+
* Thus we have 32 lines in a 32bit word.
419+
*/
420+
reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx);
421+
set = drvdata->dsb->edge_ctrl_mask[reg];
422+
if (val)
423+
set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx));
424+
else
425+
set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx));
426+
drvdata->dsb->edge_ctrl_mask[reg] = set;
427+
spin_unlock(&drvdata->spinlock);
428+
429+
return size;
430+
}
431+
static DEVICE_ATTR_WO(ctrl_mask);
432+
299433
static ssize_t dsb_trig_type_show(struct device *dev,
300434
struct device_attribute *attr, char *buf)
301435
{
@@ -367,6 +501,37 @@ static ssize_t dsb_trig_ts_store(struct device *dev,
367501
}
368502
static DEVICE_ATTR_RW(dsb_trig_ts);
369503

504+
static struct attribute *tpdm_dsb_edge_attrs[] = {
505+
&dev_attr_ctrl_idx.attr,
506+
&dev_attr_ctrl_val.attr,
507+
&dev_attr_ctrl_mask.attr,
508+
DSB_EDGE_CTRL_ATTR(0),
509+
DSB_EDGE_CTRL_ATTR(1),
510+
DSB_EDGE_CTRL_ATTR(2),
511+
DSB_EDGE_CTRL_ATTR(3),
512+
DSB_EDGE_CTRL_ATTR(4),
513+
DSB_EDGE_CTRL_ATTR(5),
514+
DSB_EDGE_CTRL_ATTR(6),
515+
DSB_EDGE_CTRL_ATTR(7),
516+
DSB_EDGE_CTRL_ATTR(8),
517+
DSB_EDGE_CTRL_ATTR(9),
518+
DSB_EDGE_CTRL_ATTR(10),
519+
DSB_EDGE_CTRL_ATTR(11),
520+
DSB_EDGE_CTRL_ATTR(12),
521+
DSB_EDGE_CTRL_ATTR(13),
522+
DSB_EDGE_CTRL_ATTR(14),
523+
DSB_EDGE_CTRL_ATTR(15),
524+
DSB_EDGE_CTRL_MASK_ATTR(0),
525+
DSB_EDGE_CTRL_MASK_ATTR(1),
526+
DSB_EDGE_CTRL_MASK_ATTR(2),
527+
DSB_EDGE_CTRL_MASK_ATTR(3),
528+
DSB_EDGE_CTRL_MASK_ATTR(4),
529+
DSB_EDGE_CTRL_MASK_ATTR(5),
530+
DSB_EDGE_CTRL_MASK_ATTR(6),
531+
DSB_EDGE_CTRL_MASK_ATTR(7),
532+
NULL,
533+
};
534+
370535
static struct attribute *tpdm_dsb_attrs[] = {
371536
&dev_attr_dsb_mode.attr,
372537
&dev_attr_dsb_trig_ts.attr,
@@ -379,9 +544,16 @@ static struct attribute_group tpdm_dsb_attr_grp = {
379544
.is_visible = tpdm_dsb_is_visible,
380545
};
381546

547+
static struct attribute_group tpdm_dsb_edge_grp = {
548+
.attrs = tpdm_dsb_edge_attrs,
549+
.is_visible = tpdm_dsb_is_visible,
550+
.name = "dsb_edge",
551+
};
552+
382553
static const struct attribute_group *tpdm_attr_grps[] = {
383554
&tpdm_attr_grp,
384555
&tpdm_dsb_attr_grp,
556+
&tpdm_dsb_edge_grp,
385557
NULL,
386558
};
387559

drivers/hwtracing/coresight/coresight-tpdm.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
/* DSB Subunit Registers */
1313
#define TPDM_DSB_CR (0x780)
1414
#define TPDM_DSB_TIER (0x784)
15+
#define TPDM_DSB_EDCR(n) (0x808 + (n * 4))
16+
#define TPDM_DSB_EDCMR(n) (0x848 + (n * 4))
1517

1618
/* Enable bit for DSB subunit */
1719
#define TPDM_DSB_CR_ENA BIT(0)
@@ -37,6 +39,16 @@
3739
/* High performance mode */
3840
#define TPDM_DSB_MODE_HPBYTESEL(val) (val & GENMASK(8, 4))
3941

42+
#define EDCRS_PER_WORD 16
43+
#define EDCR_TO_WORD_IDX(r) ((r) / EDCRS_PER_WORD)
44+
#define EDCR_TO_WORD_SHIFT(r) ((r % EDCRS_PER_WORD) * 2)
45+
#define EDCR_TO_WORD_VAL(val, r) (val << EDCR_TO_WORD_SHIFT(r))
46+
#define EDCR_TO_WORD_MASK(r) EDCR_TO_WORD_VAL(0x3, r)
47+
48+
#define EDCMRS_PER_WORD 32
49+
#define EDCMR_TO_WORD_IDX(r) ((r) / EDCMRS_PER_WORD)
50+
#define EDCMR_TO_WORD_SHIFT(r) ((r) % EDCMRS_PER_WORD)
51+
4052
/* TPDM integration test registers */
4153
#define TPDM_ITATBCNTRL (0xEF0)
4254
#define TPDM_ITCNTRL (0xF00)
@@ -63,14 +75,43 @@
6375
#define TPDM_PIDR0_DS_IMPDEF BIT(0)
6476
#define TPDM_PIDR0_DS_DSB BIT(1)
6577

78+
#define TPDM_DSB_MAX_LINES 256
79+
/* MAX number of EDCR registers */
80+
#define TPDM_DSB_MAX_EDCR 16
81+
/* MAX number of EDCMR registers */
82+
#define TPDM_DSB_MAX_EDCMR 8
83+
84+
#define tpdm_simple_dataset_ro(name, mem, idx) \
85+
(&((struct tpdm_dataset_attribute[]) { \
86+
{ \
87+
__ATTR(name, 0444, tpdm_simple_dataset_show, NULL), \
88+
mem, \
89+
idx, \
90+
} \
91+
})[0].attr.attr)
92+
93+
#define DSB_EDGE_CTRL_ATTR(nr) \
94+
tpdm_simple_dataset_ro(edcr##nr, \
95+
DSB_EDGE_CTRL, nr)
96+
97+
#define DSB_EDGE_CTRL_MASK_ATTR(nr) \
98+
tpdm_simple_dataset_ro(edcmr##nr, \
99+
DSB_EDGE_CTRL_MASK, nr)
100+
66101
/**
67102
* struct dsb_dataset - specifics associated to dsb dataset
68103
* @mode: DSB programming mode
104+
* @edge_ctrl_idx Index number of the edge control
105+
* @edge_ctrl: Save value for edge control
106+
* @edge_ctrl_mask: Save value for edge control mask
69107
* @trig_ts: Enable/Disable trigger timestamp.
70108
* @trig_type: Enable/Disable trigger type.
71109
*/
72110
struct dsb_dataset {
73111
u32 mode;
112+
u32 edge_ctrl_idx;
113+
u32 edge_ctrl[TPDM_DSB_MAX_EDCR];
114+
u32 edge_ctrl_mask[TPDM_DSB_MAX_EDCMR];
74115
bool trig_ts;
75116
bool trig_type;
76117
};
@@ -96,4 +137,23 @@ struct tpdm_drvdata {
96137
struct dsb_dataset *dsb;
97138
};
98139

140+
/* Enumerate members of various datasets */
141+
enum dataset_mem {
142+
DSB_EDGE_CTRL,
143+
DSB_EDGE_CTRL_MASK,
144+
};
145+
146+
/**
147+
* struct tpdm_dataset_attribute - Record the member variables and
148+
* index number of datasets that need to be operated by sysfs file
149+
* @attr: The device attribute
150+
* @mem: The member in the dataset data structure
151+
* @idx: The index number of the array data
152+
*/
153+
struct tpdm_dataset_attribute {
154+
struct device_attribute attr;
155+
enum dataset_mem mem;
156+
u32 idx;
157+
};
158+
99159
#endif /* _CORESIGHT_CORESIGHT_TPDM_H */

0 commit comments

Comments
 (0)