coresight-tpdm: Add timestamp control register support for the CMB

CMB_TIER register is CMB subunit timestamp insertion enable register.
Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
Set this bit to 1 to request a timestamp following a CMB CTI timestamp
request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
for all packets.

Reviewed-by: James Clark <james.clark@arm.com>
Signed-off-by: Tao Zhang <quic_taozha@quicinc.com>
Signed-off-by: Jinlong Mao <quic_jinlmao@quicinc.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/1707024641-22460-9-git-send-email-quic_taozha@quicinc.com
This commit is contained in:
Tao Zhang 2024-02-04 13:30:39 +08:00 committed by Suzuki K Poulose
parent 53d4a017a5
commit dc6ce57e2a
3 changed files with 180 additions and 7 deletions

View File

@ -214,3 +214,38 @@ KernelVersion 6.9
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
Description:
(RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
Date: January 2024
KernelVersion 6.9
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
Description:
(Write) Set the pattern timestamp of CMB tpdm. Read
the pattern timestamp of CMB tpdm.
Accepts only one of the 2 values - 0 or 1.
0 : Disable CMB pattern timestamp.
1 : Enable CMB pattern timestamp.
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
Date: January 2024
KernelVersion 6.9
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
Description:
(RW) Set/Get the trigger timestamp of the CMB for tpdm.
Accepts only one of the 2 values - 0 or 1.
0 : Set the CMB trigger type to false
1 : Set the CMB trigger type to true
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
Date: January 2024
KernelVersion 6.9
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
Description:
(RW) Read or write the status of timestamp upon all interface.
Only value 0 and 1 can be written to this node. Set this node to 1 to requeset
timestamp to all trace packet.
Accepts only one of the 2 values - 0 or 1.
0 : Disable the timestamp of all trace packets.
1 : Enable the timestamp of all trace packets.

View File

@ -322,6 +322,31 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
}
static void set_cmb_tier(struct tpdm_drvdata *drvdata)
{
u32 val;
val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
/* Clear all relevant fields */
val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
TPDM_CMB_TIER_XTRIG_TSENAB);
/* Set pattern timestamp type and enablement */
if (drvdata->cmb->patt_ts)
val |= TPDM_CMB_TIER_PATT_TSENAB;
/* Set trigger timestamp */
if (drvdata->cmb->trig_ts)
val |= TPDM_CMB_TIER_XTRIG_TSENAB;
/* Set all timestamp enablement*/
if (drvdata->cmb->ts_all)
val |= TPDM_CMB_TIER_TS_ALL;
writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
}
static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
{
u32 val, i;
@ -341,6 +366,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
drvdata->base + TPDM_CMB_XPMR(i));
}
set_cmb_tier(drvdata);
val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
/*
* Set to 0 for continuous CMB collection mode,
@ -687,9 +714,18 @@ static ssize_t enable_ts_show(struct device *dev,
char *buf)
{
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct tpdm_dataset_attribute *tpdm_attr =
container_of(attr, struct tpdm_dataset_attribute, attr);
ssize_t size = -EINVAL;
return sysfs_emit(buf, "%u\n",
(unsigned int)drvdata->dsb->patt_ts);
if (tpdm_attr->mem == DSB_PATT)
size = sysfs_emit(buf, "%u\n",
(unsigned int)drvdata->dsb->patt_ts);
else if (tpdm_attr->mem == CMB_PATT)
size = sysfs_emit(buf, "%u\n",
(unsigned int)drvdata->cmb->patt_ts);
return size;
}
/*
@ -701,17 +737,23 @@ static ssize_t enable_ts_store(struct device *dev,
size_t size)
{
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct tpdm_dataset_attribute *tpdm_attr =
container_of(attr, struct tpdm_dataset_attribute, attr);
unsigned long val;
if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
return -EINVAL;
spin_lock(&drvdata->spinlock);
drvdata->dsb->patt_ts = !!val;
spin_unlock(&drvdata->spinlock);
guard(spinlock)(&drvdata->spinlock);
if (tpdm_attr->mem == DSB_PATT)
drvdata->dsb->patt_ts = !!val;
else if (tpdm_attr->mem == CMB_PATT)
drvdata->cmb->patt_ts = !!val;
else
return -EINVAL;
return size;
}
static DEVICE_ATTR_RW(enable_ts);
static ssize_t set_type_show(struct device *dev,
struct device_attribute *attr,
@ -842,6 +884,68 @@ static ssize_t cmb_mode_store(struct device *dev,
}
static DEVICE_ATTR_RW(cmb_mode);
static ssize_t cmb_ts_all_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
return sysfs_emit(buf, "%u\n",
(unsigned int)drvdata->cmb->ts_all);
}
static ssize_t cmb_ts_all_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t size)
{
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val;
if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
return -EINVAL;
guard(spinlock)(&drvdata->spinlock);
if (val)
drvdata->cmb->ts_all = true;
else
drvdata->cmb->ts_all = false;
return size;
}
static DEVICE_ATTR_RW(cmb_ts_all);
static ssize_t cmb_trig_ts_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
return sysfs_emit(buf, "%u\n",
(unsigned int)drvdata->cmb->trig_ts);
}
static ssize_t cmb_trig_ts_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t size)
{
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
unsigned long val;
if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
return -EINVAL;
guard(spinlock)(&drvdata->spinlock);
if (val)
drvdata->cmb->trig_ts = true;
else
drvdata->cmb->trig_ts = false;
return size;
}
static DEVICE_ATTR_RW(cmb_trig_ts);
static struct attribute *tpdm_dsb_edge_attrs[] = {
&dev_attr_ctrl_idx.attr,
&dev_attr_ctrl_val.attr,
@ -910,7 +1014,7 @@ static struct attribute *tpdm_dsb_patt_attrs[] = {
DSB_PATT_MASK_ATTR(5),
DSB_PATT_MASK_ATTR(6),
DSB_PATT_MASK_ATTR(7),
&dev_attr_enable_ts.attr,
DSB_PATT_ENABLE_TS,
&dev_attr_set_type.attr,
NULL,
};
@ -964,6 +1068,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
CMB_PATT_ATTR(1),
CMB_PATT_MASK_ATTR(0),
CMB_PATT_MASK_ATTR(1),
CMB_PATT_ENABLE_TS,
NULL,
};
@ -976,6 +1081,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
static struct attribute *tpdm_cmb_attrs[] = {
&dev_attr_cmb_mode.attr,
&dev_attr_cmb_ts_all.attr,
&dev_attr_cmb_trig_ts.attr,
NULL,
};

View File

@ -11,6 +11,8 @@
/* CMB Subunit Registers */
#define TPDM_CMB_CR (0xA00)
/* CMB subunit timestamp insertion enable register */
#define TPDM_CMB_TIER (0xA04)
/* CMB subunit timestamp pattern registers */
#define TPDM_CMB_TPR(n) (0xA08 + (n * 4))
/* CMB subunit timestamp pattern mask registers */
@ -24,6 +26,12 @@
#define TPDM_CMB_CR_ENA BIT(0)
/* Trace collection mode for CMB subunit */
#define TPDM_CMB_CR_MODE BIT(1)
/* Timestamp control for pattern match */
#define TPDM_CMB_TIER_PATT_TSENAB BIT(0)
/* CMB CTI timestamp request */
#define TPDM_CMB_TIER_XTRIG_TSENAB BIT(1)
/* For timestamp fo all trace */
#define TPDM_CMB_TIER_TS_ALL BIT(2)
/* Patten register number */
#define TPDM_CMB_MAX_PATT 2
@ -134,6 +142,15 @@
} \
})[0].attr.attr)
#define tpdm_patt_enable_ts(name, mem) \
(&((struct tpdm_dataset_attribute[]) { \
{ \
__ATTR(name, 0644, enable_ts_show, \
enable_ts_store), \
mem, \
} \
})[0].attr.attr)
#define DSB_EDGE_CTRL_ATTR(nr) \
tpdm_simple_dataset_ro(edcr##nr, \
DSB_EDGE_CTRL, nr)
@ -158,6 +175,10 @@
tpdm_simple_dataset_rw(tpmr##nr, \
DSB_PATT_MASK, nr)
#define DSB_PATT_ENABLE_TS \
tpdm_patt_enable_ts(enable_ts, \
DSB_PATT)
#define DSB_MSR_ATTR(nr) \
tpdm_simple_dataset_rw(msr##nr, \
DSB_MSR, nr)
@ -178,6 +199,10 @@
tpdm_simple_dataset_rw(tpmr##nr, \
CMB_PATT_MASK, nr)
#define CMB_PATT_ENABLE_TS \
tpdm_patt_enable_ts(enable_ts, \
CMB_PATT)
/**
* struct dsb_dataset - specifics associated to dsb dataset
* @mode: DSB programming mode
@ -217,6 +242,9 @@ struct dsb_dataset {
* @patt_mask: Save value for pattern mask
* @trig_patt: Save value for trigger pattern
* @trig_patt_mask: Save value for trigger pattern mask
* @patt_ts: Indicates if pattern match for timestamp is enabled.
* @trig_ts: Indicates if CTI trigger for timestamp is enabled.
* @ts_all: Indicates if timestamp is enabled for all packets.
*/
struct cmb_dataset {
u32 trace_mode;
@ -224,6 +252,9 @@ struct cmb_dataset {
u32 patt_mask[TPDM_CMB_MAX_PATT];
u32 trig_patt[TPDM_CMB_MAX_PATT];
u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
bool patt_ts;
bool trig_ts;
bool ts_all;
};
/**