+
+ return 0;
+}
+
static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
{
if (tpdm_has_dsb_dataset(drvdata)) {
@@ -193,6 +216,15 @@ static void set_dsb_tier(struct tpdm_drvdata
*drvdata)
writel_relaxed(val, drvdata->base + TPDM_DSB_TIER);
}
+static void set_dsb_msr(struct tpdm_drvdata *drvdata)
+{
+ int i;
+
+ for (i = 0; i < drvdata->dsb_msr_num; i++)
+ writel_relaxed(drvdata->dsb->msr[i],
+ drvdata->base + TPDM_DSB_MSR(i));
+}
+
static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
{
u32 val, i;
@@ -216,6 +248,8 @@ static void tpdm_enable_dsb(struct tpdm_drvdata
*drvdata)
set_dsb_tier(drvdata);
+ set_dsb_msr(drvdata);
+
val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
/* Set the mode of DSB dataset */
set_dsb_mode(drvdata, &val);
@@ -739,6 +773,42 @@ static struct attribute *tpdm_dsb_patt_attrs[] = {
NULL,
};
+static struct attribute *tpdm_dsb_msr_attrs[] = {
+ DSB_MSR_ATTR(0),
+ DSB_MSR_ATTR(1),
+ DSB_MSR_ATTR(2),
+ DSB_MSR_ATTR(3),
+ DSB_MSR_ATTR(4),
+ DSB_MSR_ATTR(5),
+ DSB_MSR_ATTR(6),
+ DSB_MSR_ATTR(7),
+ DSB_MSR_ATTR(8),
+ DSB_MSR_ATTR(9),
+ DSB_MSR_ATTR(10),
+ DSB_MSR_ATTR(11),
+ DSB_MSR_ATTR(12),
+ DSB_MSR_ATTR(13),
+ DSB_MSR_ATTR(14),
+ DSB_MSR_ATTR(15),
+ DSB_MSR_ATTR(16),
+ DSB_MSR_ATTR(17),
+ DSB_MSR_ATTR(18),
+ DSB_MSR_ATTR(19),
+ DSB_MSR_ATTR(20),
+ DSB_MSR_ATTR(21),
+ DSB_MSR_ATTR(22),
+ DSB_MSR_ATTR(23),
+ DSB_MSR_ATTR(24),
+ DSB_MSR_ATTR(25),
+ DSB_MSR_ATTR(26),
+ DSB_MSR_ATTR(27),
+ DSB_MSR_ATTR(28),
+ DSB_MSR_ATTR(29),
+ DSB_MSR_ATTR(30),
+ DSB_MSR_ATTR(31),
+ NULL,
+};
+
static struct attribute *tpdm_dsb_attrs[] = {
&dev_attr_dsb_mode.attr,
&dev_attr_dsb_trig_ts.attr,
@@ -769,12 +839,19 @@ static struct attribute_group tpdm_dsb_patt_grp
= {
.name = "dsb_patt",
};
+static struct attribute_group tpdm_dsb_msr_grp = {
+ .attrs = tpdm_dsb_msr_attrs,
+ .is_visible = tpdm_dsb_msr_is_visible,
+ .name = "dsb_msr",
+};
+
static const struct attribute_group *tpdm_attr_grps[] = {
&tpdm_attr_grp,
&tpdm_dsb_attrs_grp,
&tpdm_dsb_edge_grp,
&tpdm_dsb_trig_patt_grp,
&tpdm_dsb_patt_grp,
+ &tpdm_dsb_msr_grp,
NULL,
};
@@ -809,6 +886,10 @@ static int tpdm_probe(struct amba_device
*adev, const struct amba_id *id)
if (ret)
return ret;
+ if (drvdata && tpdm_has_dsb_dataset(drvdata))
+ of_property_read_u32(drvdata->dev->of_node,
+ "qcom,dsb_msr_num", &drvdata->dsb_msr_num);
+
/* Set up coresight component description */
desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
if (!desc.name)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
b/drivers/hwtracing/coresight/coresight-tpdm.h
index 891979d..4115b2a1 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -18,6 +18,7 @@
#define TPDM_DSB_XPMR(n) (0x7E8 + (n * 4))
#define TPDM_DSB_EDCR(n) (0x808 + (n * 4))
#define TPDM_DSB_EDCMR(n) (0x848 + (n * 4))
+#define TPDM_DSB_MSR(n) (0x980 + (n * 4))
/* Enable bit for DSB subunit */
#define TPDM_DSB_CR_ENA BIT(0)
@@ -90,6 +91,8 @@
#define TPDM_DSB_MAX_EDCMR 8
/* MAX number of DSB pattern */
#define TPDM_DSB_MAX_PATT 8
+/* MAX number of DSB MSR */
+#define TPDM_DSB_MAX_MSR 32
#define tpdm_simple_dataset_ro(name, mem, idx) \
(&((struct tpdm_dataset_attribute[]) { \
@@ -134,6 +137,10 @@
tpdm_simple_dataset_rw(tpmr##nr, \
DSB_PATT_MASK, nr)
+#define DSB_MSR_ATTR(nr) \
+ tpdm_simple_dataset_rw(msr##nr, \
+ DSB_MSR, nr)
+
/**
* struct dsb_dataset - specifics associated to dsb dataset
* @mode: DSB programming mode
@@ -144,6 +151,7 @@
* @patt_mask: Save value for pattern mask
* @trig_patt: Save value for trigger pattern
* @trig_patt_mask: Save value for trigger pattern mask
+ * @msr Save value for MSR
* @patt_ts: Enable/Disable pattern timestamp
* @patt_type: Set pattern type
* @trig_ts: Enable/Disable trigger timestamp.
@@ -158,6 +166,7 @@ struct dsb_dataset {
u32 patt_mask[TPDM_DSB_MAX_PATT];
u32 trig_patt[TPDM_DSB_MAX_PATT];
u32 trig_patt_mask[TPDM_DSB_MAX_PATT];
+ u32 msr[TPDM_DSB_MAX_MSR];
bool patt_ts;
bool patt_type;
bool trig_ts;
@@ -173,6 +182,7 @@ struct dsb_dataset {
* @enable: enable status of the component.
* @datasets: The datasets types present of the TPDM.
* @dsb Specifics associated to TPDM DSB.
+ * @dsb_msr_num Number of MSR supported by DSB TPDM
*/
struct tpdm_drvdata {
@@ -183,6 +193,7 @@ struct tpdm_drvdata {
bool enable;
unsigned long datasets;
struct dsb_dataset *dsb;
+ u32 dsb_msr_num;
};
/* Enumerate members of various datasets */
@@ -193,6 +204,7 @@ enum dataset_mem {
DSB_TRIG_PATT_MASK,
DSB_PATT,
DSB_PATT_MASK,
+ DSB_MSR,
};
/**