mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
coresight-tpdm: Add pattern registers support for CMB
Timestamps are requested if the monitor’s CMB data set unit input data matches the value in the Monitor CMB timestamp pattern and mask registers (M_CMB_TPR and M_CMB_TPMR) when CMB timestamp enabled via the timestamp insertion enable register bit(CMB_TIER.PATT_TSENAB). The pattern match trigger output is achieved via setting values into the CMB trigger pattern and mask registers (CMB_XPR and CMB_XPMR). After configuring a pattern through these registers, the TPDM subunit will assert an output trigger every time it receives new input data that matches the configured pattern value. Values in a given bit number of the mask register correspond to the same bit number in the corresponding pattern register. 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-8-git-send-email-quic_taozha@quicinc.com
This commit is contained in:
parent
2d9ab11c26
commit
53d4a017a5
@ -184,3 +184,33 @@ Description: (Write) Set the data collection mode of CMB tpdm. Continuous
|
||||
Accepts only one of the 2 values - 0 or 1.
|
||||
0 : Continuous CMB collection mode.
|
||||
1 : Trace-on-change CMB collection mode.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpr[0:1]
|
||||
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 value of the trigger pattern for the CMB
|
||||
subunit TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpmr[0:1]
|
||||
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 mask of the trigger pattern for the CMB
|
||||
subunit TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpr[0:1]
|
||||
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 value of the pattern for the CMB subunit TPDM.
|
||||
|
||||
What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpmr[0:1]
|
||||
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 mask of the pattern for the CMB subunit TPDM.
|
||||
|
@ -66,6 +66,26 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev,
|
||||
return -EINVAL;
|
||||
return sysfs_emit(buf, "0x%x\n",
|
||||
drvdata->dsb->msr[tpdm_attr->idx]);
|
||||
case CMB_TRIG_PATT:
|
||||
if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
|
||||
return -EINVAL;
|
||||
return sysfs_emit(buf, "0x%x\n",
|
||||
drvdata->cmb->trig_patt[tpdm_attr->idx]);
|
||||
case CMB_TRIG_PATT_MASK:
|
||||
if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
|
||||
return -EINVAL;
|
||||
return sysfs_emit(buf, "0x%x\n",
|
||||
drvdata->cmb->trig_patt_mask[tpdm_attr->idx]);
|
||||
case CMB_PATT:
|
||||
if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
|
||||
return -EINVAL;
|
||||
return sysfs_emit(buf, "0x%x\n",
|
||||
drvdata->cmb->patt_val[tpdm_attr->idx]);
|
||||
case CMB_PATT_MASK:
|
||||
if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
|
||||
return -EINVAL;
|
||||
return sysfs_emit(buf, "0x%x\n",
|
||||
drvdata->cmb->patt_mask[tpdm_attr->idx]);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -118,6 +138,30 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
|
||||
ret = size;
|
||||
}
|
||||
break;
|
||||
case CMB_TRIG_PATT:
|
||||
if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
|
||||
drvdata->cmb->trig_patt[tpdm_attr->idx] = val;
|
||||
ret = size;
|
||||
}
|
||||
break;
|
||||
case CMB_TRIG_PATT_MASK:
|
||||
if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
|
||||
drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val;
|
||||
ret = size;
|
||||
}
|
||||
break;
|
||||
case CMB_PATT:
|
||||
if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
|
||||
drvdata->cmb->patt_val[tpdm_attr->idx] = val;
|
||||
ret = size;
|
||||
}
|
||||
break;
|
||||
case CMB_PATT_MASK:
|
||||
if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
|
||||
drvdata->cmb->patt_mask[tpdm_attr->idx] = val;
|
||||
ret = size;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -280,12 +324,32 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
|
||||
|
||||
static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
|
||||
{
|
||||
u32 val;
|
||||
u32 val, i;
|
||||
|
||||
if (!tpdm_has_cmb_dataset(drvdata))
|
||||
return;
|
||||
|
||||
/* Configure pattern registers */
|
||||
for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
|
||||
writel_relaxed(drvdata->cmb->patt_val[i],
|
||||
drvdata->base + TPDM_CMB_TPR(i));
|
||||
writel_relaxed(drvdata->cmb->patt_mask[i],
|
||||
drvdata->base + TPDM_CMB_TPMR(i));
|
||||
writel_relaxed(drvdata->cmb->trig_patt[i],
|
||||
drvdata->base + TPDM_CMB_XPR(i));
|
||||
writel_relaxed(drvdata->cmb->trig_patt_mask[i],
|
||||
drvdata->base + TPDM_CMB_XPMR(i));
|
||||
}
|
||||
|
||||
val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
|
||||
/*
|
||||
* Set to 0 for continuous CMB collection mode,
|
||||
* 1 for trace-on-change CMB collection mode.
|
||||
*/
|
||||
if (drvdata->cmb->trace_mode)
|
||||
val |= TPDM_CMB_CR_MODE;
|
||||
else
|
||||
val &= ~TPDM_CMB_CR_MODE;
|
||||
/* Set the enable bit of CMB control register to 1 */
|
||||
val |= TPDM_CMB_CR_ENA;
|
||||
writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
|
||||
@ -887,6 +951,22 @@ static struct attribute *tpdm_dsb_msr_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *tpdm_cmb_trig_patt_attrs[] = {
|
||||
CMB_TRIG_PATT_ATTR(0),
|
||||
CMB_TRIG_PATT_ATTR(1),
|
||||
CMB_TRIG_PATT_MASK_ATTR(0),
|
||||
CMB_TRIG_PATT_MASK_ATTR(1),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *tpdm_cmb_patt_attrs[] = {
|
||||
CMB_PATT_ATTR(0),
|
||||
CMB_PATT_ATTR(1),
|
||||
CMB_PATT_MASK_ATTR(0),
|
||||
CMB_PATT_MASK_ATTR(1),
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *tpdm_dsb_attrs[] = {
|
||||
&dev_attr_dsb_mode.attr,
|
||||
&dev_attr_dsb_trig_ts.attr,
|
||||
@ -933,6 +1013,18 @@ static struct attribute_group tpdm_cmb_attr_grp = {
|
||||
.is_visible = tpdm_cmb_is_visible,
|
||||
};
|
||||
|
||||
static struct attribute_group tpdm_cmb_trig_patt_grp = {
|
||||
.attrs = tpdm_cmb_trig_patt_attrs,
|
||||
.is_visible = tpdm_cmb_is_visible,
|
||||
.name = "cmb_trig_patt",
|
||||
};
|
||||
|
||||
static struct attribute_group tpdm_cmb_patt_grp = {
|
||||
.attrs = tpdm_cmb_patt_attrs,
|
||||
.is_visible = tpdm_cmb_is_visible,
|
||||
.name = "cmb_patt",
|
||||
};
|
||||
|
||||
static const struct attribute_group *tpdm_attr_grps[] = {
|
||||
&tpdm_attr_grp,
|
||||
&tpdm_dsb_attr_grp,
|
||||
@ -941,6 +1033,8 @@ static const struct attribute_group *tpdm_attr_grps[] = {
|
||||
&tpdm_dsb_patt_grp,
|
||||
&tpdm_dsb_msr_grp,
|
||||
&tpdm_cmb_attr_grp,
|
||||
&tpdm_cmb_trig_patt_grp,
|
||||
&tpdm_cmb_patt_grp,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -11,12 +11,23 @@
|
||||
|
||||
/* CMB Subunit Registers */
|
||||
#define TPDM_CMB_CR (0xA00)
|
||||
/* CMB subunit timestamp pattern registers */
|
||||
#define TPDM_CMB_TPR(n) (0xA08 + (n * 4))
|
||||
/* CMB subunit timestamp pattern mask registers */
|
||||
#define TPDM_CMB_TPMR(n) (0xA10 + (n * 4))
|
||||
/* CMB subunit trigger pattern registers */
|
||||
#define TPDM_CMB_XPR(n) (0xA18 + (n * 4))
|
||||
/* CMB subunit trigger pattern mask registers */
|
||||
#define TPDM_CMB_XPMR(n) (0xA20 + (n * 4))
|
||||
|
||||
/* Enable bit for CMB subunit */
|
||||
#define TPDM_CMB_CR_ENA BIT(0)
|
||||
/* Trace collection mode for CMB subunit */
|
||||
#define TPDM_CMB_CR_MODE BIT(1)
|
||||
|
||||
/* Patten register number */
|
||||
#define TPDM_CMB_MAX_PATT 2
|
||||
|
||||
/* DSB Subunit Registers */
|
||||
#define TPDM_DSB_CR (0x780)
|
||||
#define TPDM_DSB_TIER (0x784)
|
||||
@ -151,6 +162,22 @@
|
||||
tpdm_simple_dataset_rw(msr##nr, \
|
||||
DSB_MSR, nr)
|
||||
|
||||
#define CMB_TRIG_PATT_ATTR(nr) \
|
||||
tpdm_simple_dataset_rw(xpr##nr, \
|
||||
CMB_TRIG_PATT, nr)
|
||||
|
||||
#define CMB_TRIG_PATT_MASK_ATTR(nr) \
|
||||
tpdm_simple_dataset_rw(xpmr##nr, \
|
||||
CMB_TRIG_PATT_MASK, nr)
|
||||
|
||||
#define CMB_PATT_ATTR(nr) \
|
||||
tpdm_simple_dataset_rw(tpr##nr, \
|
||||
CMB_PATT, nr)
|
||||
|
||||
#define CMB_PATT_MASK_ATTR(nr) \
|
||||
tpdm_simple_dataset_rw(tpmr##nr, \
|
||||
CMB_PATT_MASK, nr)
|
||||
|
||||
/**
|
||||
* struct dsb_dataset - specifics associated to dsb dataset
|
||||
* @mode: DSB programming mode
|
||||
@ -186,9 +213,17 @@ struct dsb_dataset {
|
||||
/**
|
||||
* struct cmb_dataset
|
||||
* @trace_mode: Dataset collection mode
|
||||
* @patt_val: Save value for pattern
|
||||
* @patt_mask: Save value for pattern mask
|
||||
* @trig_patt: Save value for trigger pattern
|
||||
* @trig_patt_mask: Save value for trigger pattern mask
|
||||
*/
|
||||
struct cmb_dataset {
|
||||
u32 trace_mode;
|
||||
u32 patt_val[TPDM_CMB_MAX_PATT];
|
||||
u32 patt_mask[TPDM_CMB_MAX_PATT];
|
||||
u32 trig_patt[TPDM_CMB_MAX_PATT];
|
||||
u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -225,6 +260,10 @@ enum dataset_mem {
|
||||
DSB_PATT,
|
||||
DSB_PATT_MASK,
|
||||
DSB_MSR,
|
||||
CMB_TRIG_PATT,
|
||||
CMB_TRIG_PATT_MASK,
|
||||
CMB_PATT,
|
||||
CMB_PATT_MASK
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user