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:
parent
53d4a017a5
commit
dc6ce57e2a
@ -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.
|
||||
|
@ -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",
|
||||
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);
|
||||
guard(spinlock)(&drvdata->spinlock);
|
||||
if (tpdm_attr->mem == DSB_PATT)
|
||||
drvdata->dsb->patt_ts = !!val;
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user