]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
coresight-tpdm: Add MCMB dataset support
authorMao Jinlong <quic_jinlmao@quicinc.com>
Wed, 26 Feb 2025 06:40:06 +0000 (22:40 -0800)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Wed, 26 Feb 2025 11:25:10 +0000 (11:25 +0000)
MCMB (Multi-lane CMB) is a special form of CMB dataset type. MCMB
subunit TPDM has the same number and usage of registers as CMB
subunit TPDM. MCMB subunit can be enabled for data collection by
writing 1 to the first bit of CMB_CR register. The difference is
that MCMB subunit TPDM needs to select the lane and enable it in
using it.

Signed-off-by: Tao Zhang <quic_taozha@quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20250226064008.2531037-2-quic_jinlmao@quicinc.com
drivers/hwtracing/coresight/coresight-tpda.c
drivers/hwtracing/coresight/coresight-tpdm.c
drivers/hwtracing/coresight/coresight-tpdm.h

index 573da8427428d430ab7f11398d1980193e21481f..c88c548e6d491eac395c5958c4f2d4cb87e0e4ef 100644 (file)
@@ -1,6 +1,6 @@
 // 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>
@@ -68,11 +68,12 @@ static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
        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);
        }
index afc4c18dd35d0ab1cc474214b1df6f816e1aed68..311727f15c32f84ba0ad26fa5ecd7b8bae2bc8bb 100644 (file)
@@ -1,6 +1,6 @@
 // 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,
@@ -198,7 +213,7 @@ static umode_t tpdm_cmb_is_visible(struct kobject *kobj,
        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;
@@ -388,7 +403,7 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
 {
        u32 val, i;
 
-       if (!tpdm_has_cmb_dataset(drvdata))
+       if (!drvdata->cmb)
                return;
 
        /* Configure pattern registers */
@@ -415,6 +430,19 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
                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);
@@ -480,7 +508,7 @@ static void tpdm_disable_cmb(struct tpdm_drvdata *drvdata)
 {
        u32 val;
 
-       if (!tpdm_has_cmb_dataset(drvdata))
+       if (!drvdata->cmb)
                return;
 
        val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
@@ -542,12 +570,14 @@ static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata)
                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;
index e08d212642e351a3797d54f5d56c3b2196c9a23d..62a3fd5ddec7c786b287561b79ef6401094fd3c8 100644 (file)
@@ -1,6 +1,6 @@
 /* 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
@@ -9,7 +9,7 @@
 /* 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 */
@@ -256,6 +262,9 @@ struct dsb_dataset {
  * @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;
@@ -267,6 +276,10 @@ struct cmb_dataset {
        bool                    patt_ts;
        bool                    trig_ts;
        bool                    ts_all;
+       struct {
+               u8              trig_lane;
+               u8              lane_select;
+       } mcmb;
 };
 
 /**
@@ -324,14 +337,4 @@ struct tpdm_dataset_attribute {
        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 */