// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/amba/bus.h>
int rc = -EINVAL;
struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
- if (tpdm_has_dsb_dataset(tpdm_data)) {
+ if (tpdm_data->dsb) {
rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
"qcom,dsb-element-bits", &drvdata->dsb_esize);
}
- if (tpdm_has_cmb_dataset(tpdm_data)) {
+
+ if (tpdm_data->cmb) {
rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
"qcom,cmb-element-bits", &drvdata->cmb_esize);
}
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/amba/bus.h>
DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
+static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
+{
+ return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
+}
+
+static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata)
+{
+ return (drvdata->datasets & TPDM_PIDR0_DS_CMB);
+}
+
+static bool tpdm_has_mcmb_dataset(struct tpdm_drvdata *drvdata)
+{
+ return (drvdata->datasets & TPDM_PIDR0_DS_MCMB);
+}
+
/* Read dataset array member with the index number */
static ssize_t tpdm_simple_dataset_show(struct device *dev,
struct device_attribute *attr,
struct device *dev = kobj_to_dev(kobj);
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (drvdata && tpdm_has_cmb_dataset(drvdata))
+ if (drvdata && drvdata->cmb)
return attr->mode;
return 0;
{
u32 val, i;
- if (!tpdm_has_cmb_dataset(drvdata))
+ if (!drvdata->cmb)
return;
/* Configure pattern registers */
val |= TPDM_CMB_CR_MODE;
else
val &= ~TPDM_CMB_CR_MODE;
+
+ if (tpdm_has_mcmb_dataset(drvdata)) {
+ val &= ~TPDM_CMB_CR_XTRIG_LNSEL;
+ /* Set the lane participates in the output pattern */
+ val |= FIELD_PREP(TPDM_CMB_CR_XTRIG_LNSEL,
+ drvdata->cmb->mcmb.trig_lane);
+
+ /* Set the enablement of the lane */
+ val &= ~TPDM_CMB_CR_E_LN;
+ val |= FIELD_PREP(TPDM_CMB_CR_E_LN,
+ drvdata->cmb->mcmb.lane_select);
+ }
+
/* Set the enable bit of CMB control register to 1 */
val |= TPDM_CMB_CR_ENA;
writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
{
u32 val;
- if (!tpdm_has_cmb_dataset(drvdata))
+ if (!drvdata->cmb)
return;
val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
if (!drvdata->dsb)
return -ENOMEM;
}
- if (tpdm_has_cmb_dataset(drvdata) && (!drvdata->cmb)) {
+ if ((tpdm_has_cmb_dataset(drvdata) || tpdm_has_mcmb_dataset(drvdata))
+ && (!drvdata->cmb)) {
drvdata->cmb = devm_kzalloc(drvdata->dev,
sizeof(*drvdata->cmb), GFP_KERNEL);
if (!drvdata->cmb)
return -ENOMEM;
}
+
tpdm_reset_datasets(drvdata);
return 0;
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _CORESIGHT_CORESIGHT_TPDM_H
/* The max number of the datasets that TPDM supports */
#define TPDM_DATASETS 7
-/* CMB Subunit Registers */
+/* CMB/MCMB Subunit Registers */
#define TPDM_CMB_CR (0xA00)
/* CMB subunit timestamp insertion enable register */
#define TPDM_CMB_TIER (0xA04)
#define TPDM_CMB_CR_ENA BIT(0)
/* Trace collection mode for CMB subunit */
#define TPDM_CMB_CR_MODE BIT(1)
+/* MCMB trigger lane select */
+#define TPDM_CMB_CR_XTRIG_LNSEL GENMASK(20, 18)
+/* MCMB lane enablement */
+#define TPDM_CMB_CR_E_LN GENMASK(17, 10)
/* Timestamp control for pattern match */
#define TPDM_CMB_TIER_PATT_TSENAB BIT(0)
/* CMB CTI timestamp request */
* PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0
* PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0
* PERIPHIDR0[2] : Fix to 1 if CMB subunit present, else 0
+ * PERIPHIDR0[6] : Fix to 1 if MCMB subunit present, else 0
*/
#define TPDM_PIDR0_DS_IMPDEF BIT(0)
#define TPDM_PIDR0_DS_DSB BIT(1)
#define TPDM_PIDR0_DS_CMB BIT(2)
+#define TPDM_PIDR0_DS_MCMB BIT(6)
#define TPDM_DSB_MAX_LINES 256
/* MAX number of EDCR registers */
* @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 mcmb_dataset
+ * @mcmb_trig_lane: Save data for trigger lane
+ * @mcmb_lane_select: Save data for lane enablement
*/
struct cmb_dataset {
u32 trace_mode;
bool patt_ts;
bool trig_ts;
bool ts_all;
+ struct {
+ u8 trig_lane;
+ u8 lane_select;
+ } mcmb;
};
/**
enum dataset_mem mem;
u32 idx;
};
-
-static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
-{
- return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
-}
-
-static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata)
-{
- return (drvdata->datasets & TPDM_PIDR0_DS_CMB);
-}
#endif /* _CORESIGHT_CORESIGHT_TPDM_H */