Hi,
On Mon, 20 Oct 2025 at 08:12, Yingchao Deng yingchao.deng@oss.qualcomm.com wrote:
The QCOM extended CTI is a heavily parameterized version of ARM’s CSCTI. It allows a debugger to send to trigger events to a processor or to send a trigger event to one or more processors when a trigger event occurs on another processor on the same SoC, or even between SoCs. Qualcomm CTI implementation differs from the standard CTI in the following aspects:
- The number of supported triggers is extended to 128.
- Several register offsets differ from the CoreSight specification.
Signed-off-by: Jinlong Mao jinglong.mao@oss.qualcomm.com Signed-off-by: Yingchao Deng yingchao.deng@oss.qualcomm.com
drivers/hwtracing/coresight/coresight-cti-core.c | 86 +++++++++-- drivers/hwtracing/coresight/coresight-cti-sysfs.c | 174 +++++++++++++++++----- drivers/hwtracing/coresight/coresight-cti.h | 43 +++++- drivers/hwtracing/coresight/qcom-cti.h | 29 ++++ 4 files changed, 281 insertions(+), 51 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c index 8c9cec832898..5330db7eecf1 100644 --- a/drivers/hwtracing/coresight/coresight-cti-core.c +++ b/drivers/hwtracing/coresight/coresight-cti-core.c @@ -21,6 +21,55 @@
#include "coresight-priv.h" #include "coresight-cti.h" +#include "qcom-cti.h"
+static const u32 cti_normal_offset[] = {
[INDEX_CTIINTACK] = CTIINTACK,[INDEX_CTIAPPSET] = CTIAPPSET,[INDEX_CTIAPPCLEAR] = CTIAPPCLEAR,[INDEX_CTIAPPPULSE] = CTIAPPPULSE,[INDEX_CTIINEN] = CTIINEN(0),[INDEX_CTIOUTEN] = CTIOUTEN(0),[INDEX_CTITRIGINSTATUS] = CTITRIGINSTATUS,[INDEX_CTITRIGOUTSTATUS] = CTITRIGOUTSTATUS,[INDEX_CTICHINSTATUS] = CTICHINSTATUS,[INDEX_CTICHOUTSTATUS] = CTICHOUTSTATUS,[INDEX_CTIGATE] = CTIGATE,[INDEX_ASICCTL] = ASICCTL,[INDEX_ITCHINACK] = ITCHINACK,[INDEX_ITTRIGINACK] = ITTRIGINACK,[INDEX_ITCHOUT] = ITCHOUT,[INDEX_ITTRIGOUT] = ITTRIGOUT,[INDEX_ITCHOUTACK] = ITCHOUTACK,[INDEX_ITTRIGOUTACK] = ITTRIGOUTACK,[INDEX_ITCHIN] = ITCHIN,[INDEX_ITTRIGIN] = ITTRIGIN,[INDEX_ITCTRL] = CORESIGHT_ITCTRL,+};
+static const u32 cti_extended_offset[] = {
[INDEX_CTIINTACK] = QCOM_CTIINTACK,[INDEX_CTIAPPSET] = QCOM_CTIAPPSET,[INDEX_CTIAPPCLEAR] = QCOM_CTIAPPCLEAR,[INDEX_CTIAPPPULSE] = QCOM_CTIAPPPULSE,[INDEX_CTIINEN] = QCOM_CTIINEN,[INDEX_CTIOUTEN] = QCOM_CTIOUTEN,[INDEX_CTITRIGINSTATUS] = QCOM_CTITRIGINSTATUS,[INDEX_CTITRIGOUTSTATUS] = QCOM_CTITRIGOUTSTATUS,[INDEX_CTICHINSTATUS] = QCOM_CTICHINSTATUS,[INDEX_CTICHOUTSTATUS] = QCOM_CTICHOUTSTATUS,[INDEX_CTIGATE] = QCOM_CTIGATE,[INDEX_ASICCTL] = QCOM_ASICCTL,[INDEX_ITCHINACK] = QCOM_ITCHINACK,[INDEX_ITTRIGINACK] = QCOM_ITTRIGINACK,[INDEX_ITCHOUT] = QCOM_ITCHOUT,[INDEX_ITTRIGOUT] = QCOM_ITTRIGOUT,[INDEX_ITCHOUTACK] = QCOM_ITCHOUTACK,[INDEX_ITTRIGOUTACK] = QCOM_ITTRIGOUTACK,[INDEX_ITCHIN] = QCOM_ITCHIN,[INDEX_ITTRIGIN] = QCOM_ITTRIGIN,[INDEX_ITCTRL] = CORESIGHT_ITCTRL,+};
/*
- CTI devices can be associated with a PE, or be connected to CoreSight
@@ -70,15 +119,16 @@ void cti_write_all_hw_regs(struct cti_drvdata *drvdata)
/* write the CTI trigger registers */ for (i = 0; i < config->nr_trig_max; i++) {
writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN(i));
writel_relaxed(config->ctiinen[i],drvdata->base + cti_offset(drvdata, INDEX_CTIINEN, i)); writel_relaxed(config->ctiouten[i],
drvdata->base + CTIOUTEN(i));
drvdata->base + cti_offset(drvdata, INDEX_CTIOUTEN, i)); } /* other regs */
writel_relaxed(config->ctigate, drvdata->base + CTIGATE);writel_relaxed(config->asicctl, drvdata->base + ASICCTL);writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET);
writel_relaxed(config->ctigate, drvdata->base + cti_offset(drvdata, INDEX_CTIGATE, 0));writel_relaxed(config->asicctl, drvdata->base + cti_offset(drvdata, INDEX_ASICCTL, 0));writel_relaxed(config->ctiappset, drvdata->base + cti_offset(drvdata, INDEX_CTIAPPSET, 0)); /* re-enable CTI */ writel_relaxed(1, drvdata->base + CTICONTROL);@@ -214,6 +264,9 @@ void cti_write_intack(struct device *dev, u32 ackval) /* DEVID[19:16] - number of CTM channels */ #define CTI_DEVID_CTMCHANNELS(devid_val) ((int) BMVAL(devid_val, 16, 19))
+/* DEVARCH[31:21] - ARCHITECT */ +#define CTI_DEVARCH_ARCHITECT(devarch_val) ((int)BMVAL(devarch_val, 21, 31))
static int cti_set_default_config(struct device *dev, struct cti_drvdata *drvdata) { @@ -394,8 +447,8 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op,
/* update the local register values */ chan_bitmask = BIT(channel_idx);
reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) :CTIOUTEN(trigger_idx));
reg_offset = (direction == CTI_TRIG_IN ? cti_offset(drvdata, INDEX_CTIINEN, trigger_idx) :cti_offset(drvdata, INDEX_CTIOUTEN, trigger_idx)); raw_spin_lock(&drvdata->spinlock);@@ -479,19 +532,19 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op, case CTI_CHAN_SET: config->ctiappset |= chan_bitmask; reg_value = config->ctiappset;
reg_offset = CTIAPPSET;
reg_offset = cti_offset(drvdata, INDEX_CTIAPPSET, 0); break; case CTI_CHAN_CLR: config->ctiappset &= ~chan_bitmask; reg_value = chan_bitmask;
reg_offset = CTIAPPCLEAR;
reg_offset = cti_offset(drvdata, INDEX_CTIAPPCLEAR, 0); break; case CTI_CHAN_PULSE: config->ctiappset &= ~chan_bitmask; reg_value = chan_bitmask;
reg_offset = CTIAPPPULSE;
reg_offset = cti_offset(drvdata, INDEX_CTIAPPPULSE, 0); break; default:@@ -894,6 +947,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) struct coresight_desc cti_desc; struct coresight_platform_data *pdata = NULL; struct resource *res = &adev->res;
u32 devarch; /* driver data*/ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);@@ -980,9 +1034,19 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) drvdata->csdev_release = drvdata->csdev->dev.release; drvdata->csdev->dev.release = cti_device_release;
/* qcom_cti*/
perhaps this comment could be "check architect value"?
devarch = readl_relaxed(drvdata->base + CORESIGHT_DEVARCH);if (CTI_DEVARCH_ARCHITECT(devarch) == ARCHITECT_QCOM) {drvdata->subtype = QCOM_CTI;drvdata->offsets = cti_extended_offset;} else {drvdata->subtype = ARM_STD_CTI;drvdata->offsets = cti_normal_offset;}/* all done - dec pm refcount */ pm_runtime_put(&adev->dev);
dev_info(&drvdata->csdev->dev, "CTI initialized\n");
dev_info(&drvdata->csdev->dev, "CTI initialized %d\n", drvdata->subtype);
Here extend string to "CTI Intialized; subtype=%d\n"
return 0;pm_release: diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c index a9df77215141..88fd1c9c0101 100644 --- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c @@ -172,9 +172,8 @@ static struct attribute *coresight_cti_attrs[] = {
/* register based attributes */
-/* Read registers with power check only (no enable check). */ -static ssize_t coresight_cti_reg_show(struct device *dev,
struct device_attribute *attr, char *buf)+static ssize_t coresight_cti_mgmt_reg_show(struct device *dev,
struct device_attribute *attr, char *buf){ struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr); @@ -189,6 +188,39 @@ static ssize_t coresight_cti_reg_show(struct device *dev, return sysfs_emit(buf, "0x%x\n", val); }
+/* Read registers with power check only (no enable check). */ +static ssize_t coresight_cti_reg_show(struct device *dev,
struct device_attribute *attr, char *buf)+{
struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr);u32 val = 0, idx = drvdata->config.regs_idx;
This needs to be inside the spin lock
pm_runtime_get_sync(dev->parent);raw_spin_lock(&drvdata->spinlock);if (drvdata->config.hw_powered) {switch (cti_attr->off) {case INDEX_CTITRIGINSTATUS:case INDEX_CTITRIGOUTSTATUS:case INDEX_ITTRIGINACK:case INDEX_ITTRIGOUT:case INDEX_ITTRIGOUTACK:case INDEX_ITTRIGIN:val = readl_relaxed(drvdata->base +cti_offset(drvdata, cti_attr->off, idx));break;default:val = readl_relaxed(drvdata->base + cti_offset(drvdata, cti_attr->off, 0));break;}}raw_spin_unlock(&drvdata->spinlock);pm_runtime_put_sync(dev->parent);return sysfs_emit(buf, "0x%x\n", val);+}
/* Write registers with power check only (no enable check). */ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev, struct device_attribute *attr, @@ -197,19 +229,38 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev, struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr); unsigned long val = 0;
u32 idx = drvdata->config.regs_idx;
this needs to be inside the spinlock
if (kstrtoul(buf, 0, &val)) return -EINVAL; pm_runtime_get_sync(dev->parent); raw_spin_lock(&drvdata->spinlock);
if (drvdata->config.hw_powered)cti_write_single_reg(drvdata, cti_attr->off, val);
if (drvdata->config.hw_powered) {switch (cti_attr->off) {case INDEX_ITTRIGINACK:case INDEX_ITTRIGOUT:cti_write_single_reg(drvdata, cti_offset(drvdata, cti_attr->off, idx), val);break;default:cti_write_single_reg(drvdata, cti_offset(drvdata, cti_attr->off, 0), val);break;}} raw_spin_unlock(&drvdata->spinlock); pm_runtime_put_sync(dev->parent); return size;}
+#define coresight_cti_mgmt_reg(name, offset) \
(&((struct cs_off_attribute[]) { \{ \__ATTR(name, 0444, coresight_cti_mgmt_reg_show, NULL), \offset \} \})[0].attr.attr)#define coresight_cti_reg(name, offset) \ (&((struct cs_off_attribute[]) { \ { \ @@ -237,17 +288,17 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev,
/* coresight management registers */ static struct attribute *coresight_cti_mgmt_attrs[] = {
coresight_cti_reg(devaff0, CTIDEVAFF0),coresight_cti_reg(devaff1, CTIDEVAFF1),coresight_cti_reg(authstatus, CORESIGHT_AUTHSTATUS),coresight_cti_reg(devarch, CORESIGHT_DEVARCH),coresight_cti_reg(devid, CORESIGHT_DEVID),coresight_cti_reg(devtype, CORESIGHT_DEVTYPE),coresight_cti_reg(pidr0, CORESIGHT_PERIPHIDR0),coresight_cti_reg(pidr1, CORESIGHT_PERIPHIDR1),coresight_cti_reg(pidr2, CORESIGHT_PERIPHIDR2),coresight_cti_reg(pidr3, CORESIGHT_PERIPHIDR3),coresight_cti_reg(pidr4, CORESIGHT_PERIPHIDR4),
coresight_cti_mgmt_reg(devaff0, CTIDEVAFF0),coresight_cti_mgmt_reg(devaff1, CTIDEVAFF1),coresight_cti_mgmt_reg(authstatus, CORESIGHT_AUTHSTATUS),coresight_cti_mgmt_reg(devarch, CORESIGHT_DEVARCH),coresight_cti_mgmt_reg(devid, CORESIGHT_DEVID),coresight_cti_mgmt_reg(devtype, CORESIGHT_DEVTYPE),coresight_cti_mgmt_reg(pidr0, CORESIGHT_PERIPHIDR0),coresight_cti_mgmt_reg(pidr1, CORESIGHT_PERIPHIDR1),coresight_cti_mgmt_reg(pidr2, CORESIGHT_PERIPHIDR2),coresight_cti_mgmt_reg(pidr3, CORESIGHT_PERIPHIDR3),coresight_cti_mgmt_reg(pidr4, CORESIGHT_PERIPHIDR4), NULL,};
@@ -258,13 +309,15 @@ static struct attribute *coresight_cti_mgmt_attrs[] = {
- If inaccessible & pcached_val not NULL then show cached value.
*/ static ssize_t cti_reg32_show(struct device *dev, char *buf,
u32 *pcached_val, int reg_offset)
u32 *pcached_val, int index){ u32 val = 0; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config;
int reg_offset; raw_spin_lock(&drvdata->spinlock);reg_offset = cti_offset(drvdata, index, 0); if ((reg_offset >= 0) && cti_active(config)) { CS_UNLOCK(drvdata->base); val = readl_relaxed(drvdata->base + reg_offset);@@ -284,11 +337,12 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf,
- if reg_offset >= 0 then write through if enabled.
*/ static ssize_t cti_reg32_store(struct device *dev, const char *buf,
size_t size, u32 *pcached_val, int reg_offset)
size_t size, u32 *pcached_val, int index){ unsigned long val; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config;
int reg_offset; if (kstrtoul(buf, 0, &val)) return -EINVAL;@@ -298,6 +352,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf, if (pcached_val) *pcached_val = (u32)val;
reg_offset = cti_offset(drvdata, index, 0); /* write through if offset and enabled */ if ((reg_offset >= 0) && cti_active(config)) cti_write_single_reg(drvdata, reg_offset, val);@@ -306,14 +361,14 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf, }
/* Standard macro for simple rw cti config registers */ -#define cti_config_reg32_rw(name, cfgname, offset) \ +#define cti_config_reg32_rw(name, cfgname, index) \ static ssize_t name##_show(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ { \ struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \ return cti_reg32_show(dev, buf, \
&drvdata->config.cfgname, offset); \
&drvdata->config.cfgname, index); \} \ \ static ssize_t name##_store(struct device *dev, \ @@ -322,7 +377,7 @@ static ssize_t name##_store(struct device *dev, \ { \ struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \ return cti_reg32_store(dev, buf, size, \
&drvdata->config.cfgname, offset); \
&drvdata->config.cfgname, index); \} \ static DEVICE_ATTR_RW(name)
@@ -356,6 +411,46 @@ static ssize_t inout_sel_store(struct device *dev, } static DEVICE_ATTR_RW(inout_sel);
+/*
- QCOM CTI supports up to 128 triggers, there are 6 registers need to be
- expanded to up to 4 instances, and regs_idx can be used to indicate which
- one is in use.
- CTITRIGINSTATUS, CTITRIGOUTSTATUS,
- ITTRIGIN, ITTRIGOUT,
- ITTRIGINACK, ITTRIGOUTACK.
All the other selection indexes are of the form xxx_sel - this should be something along the lines of "ext_reg_sel" for consistency
Additionally this information needs to appear as an entry in the documentation file Documentation/ABI/testing/sysfs-bus-coresight-devices-cti so users are aware of which registers this select relates to.
- */
+static ssize_t regs_idx_show(struct device *dev,
struct device_attribute *attr,char *buf)+{
u32 val;struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);raw_spin_lock(&drvdata->spinlock);val = drvdata->config.regs_idx;raw_spin_unlock(&drvdata->spinlock);return sprintf(buf, "%d\n", val);+}
+static ssize_t regs_idx_store(struct device *dev,
struct device_attribute *attr,const char *buf, size_t size)+{
unsigned long val;struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);if (kstrtoul(buf, 0, &val))return -EINVAL;if (val > ((drvdata->config.nr_trig_max + 31) / 32 - 1))return -EINVAL;raw_spin_lock(&drvdata->spinlock);drvdata->config.regs_idx = val;raw_spin_unlock(&drvdata->spinlock);return size;+} +static DEVICE_ATTR_RW(regs_idx);
see above - cheange to ..._sel
static ssize_t inen_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -389,7 +484,7 @@ static ssize_t inen_store(struct device *dev,
/* write through if enabled */ if (cti_active(config))
cti_write_single_reg(drvdata, CTIINEN(index), val);
cti_write_single_reg(drvdata, cti_offset(drvdata, INDEX_CTIINEN, index), val); raw_spin_unlock(&drvdata->spinlock); return size;} @@ -428,7 +523,7 @@ static ssize_t outen_store(struct device *dev,
/* write through if enabled */ if (cti_active(config))
cti_write_single_reg(drvdata, CTIOUTEN(index), val);
cti_write_single_reg(drvdata, cti_offset(drvdata, INDEX_CTIOUTEN, index), val); raw_spin_unlock(&drvdata->spinlock); return size;} @@ -448,9 +543,9 @@ static ssize_t intack_store(struct device *dev, } static DEVICE_ATTR_WO(intack);
-cti_config_reg32_rw(gate, ctigate, CTIGATE); -cti_config_reg32_rw(asicctl, asicctl, ASICCTL); -cti_config_reg32_rw(appset, ctiappset, CTIAPPSET); +cti_config_reg32_rw(gate, ctigate, INDEX_CTIGATE); +cti_config_reg32_rw(asicctl, asicctl, INDEX_ASICCTL); +cti_config_reg32_rw(appset, ctiappset, INDEX_CTIAPPSET);
static ssize_t appclear_store(struct device *dev, struct device_attribute *attr, @@ -504,6 +599,7 @@ static DEVICE_ATTR_WO(apppulse); */ static struct attribute *coresight_cti_regs_attrs[] = { &dev_attr_inout_sel.attr,
&dev_attr_regs_idx.attr, &dev_attr_inen.attr, &dev_attr_outen.attr, &dev_attr_gate.attr,@@ -512,20 +608,20 @@ static struct attribute *coresight_cti_regs_attrs[] = { &dev_attr_appset.attr, &dev_attr_appclear.attr, &dev_attr_apppulse.attr,
coresight_cti_reg(triginstatus, CTITRIGINSTATUS),coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS),coresight_cti_reg(chinstatus, CTICHINSTATUS),coresight_cti_reg(choutstatus, CTICHOUTSTATUS),
coresight_cti_reg(triginstatus, INDEX_CTITRIGINSTATUS),coresight_cti_reg(trigoutstatus, INDEX_CTITRIGOUTSTATUS),coresight_cti_reg(chinstatus, INDEX_CTICHINSTATUS),coresight_cti_reg(choutstatus, INDEX_CTICHOUTSTATUS),#ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL),coresight_cti_reg(ittrigin, ITTRIGIN),coresight_cti_reg(itchin, ITCHIN),coresight_cti_reg_rw(ittrigout, ITTRIGOUT),coresight_cti_reg_rw(itchout, ITCHOUT),coresight_cti_reg(itchoutack, ITCHOUTACK),coresight_cti_reg(ittrigoutack, ITTRIGOUTACK),coresight_cti_reg_wo(ittriginack, ITTRIGINACK),coresight_cti_reg_wo(itchinack, ITCHINACK),
coresight_cti_reg_rw(itctrl, INDEX_ITCTRL),coresight_cti_reg(ittrigin, INDEX_ITTRIGIN),coresight_cti_reg(itchin, INDEX_ITCHIN),coresight_cti_reg_rw(ittrigout, INDEX_ITTRIGOUT),coresight_cti_reg_rw(itchout, INDEX_ITCHOUT),coresight_cti_reg(itchoutack, INDEX_ITCHOUTACK),coresight_cti_reg(ittrigoutack, INDEX_ITTRIGOUTACK),coresight_cti_reg_wo(ittriginack, INDEX_ITTRIGINACK),coresight_cti_reg_wo(itchinack, INDEX_ITCHINACK),#endif NULL, }; diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h index 0bd71407ef34..034d6fd1590b 100644 --- a/drivers/hwtracing/coresight/coresight-cti.h +++ b/drivers/hwtracing/coresight/coresight-cti.h @@ -57,7 +57,38 @@ struct fwnode_handle;
- Max of in and out defined in the DEVID register.
- pick up actual number used from .dts parameters if present.
*/ -#define CTIINOUTEN_MAX 32 +#define CTIINOUTEN_MAX 128
+/* Qcom CTI supports up to 128 triggers*/ +enum cti_subtype {
ARM_STD_CTI,QCOM_CTI,+};
+/* These registers are remapped in Qcom CTI*/ +enum cti_offset_index {
INDEX_CTIINTACK,INDEX_CTIAPPSET,INDEX_CTIAPPCLEAR,INDEX_CTIAPPPULSE,INDEX_CTIINEN,INDEX_CTIOUTEN,INDEX_CTITRIGINSTATUS,INDEX_CTITRIGOUTSTATUS,INDEX_CTICHINSTATUS,INDEX_CTICHOUTSTATUS,INDEX_CTIGATE,INDEX_ASICCTL,INDEX_ITCHINACK,INDEX_ITTRIGINACK,INDEX_ITCHOUT,INDEX_ITTRIGOUT,INDEX_ITCHOUTACK,INDEX_ITTRIGOUTACK,INDEX_ITCHIN,INDEX_ITTRIGIN,INDEX_ITCTRL,+};
/**
- Group of related trigger signals
@@ -149,6 +180,9 @@ struct cti_config { bool trig_filter_enable; u8 xtrig_rchan_sel;
/* qcom_cti regs' index */u8 regs_idx;
rename to ..._sel as per comments above.
This value also needs to be reset in the chan_xtrigs_reset_store() function in coresight-cti-sysfs.c
/* cti cross trig programmable regs */ u8 ctiinout_sel; u32 ctiappset;@@ -181,6 +215,8 @@ struct cti_drvdata { struct cti_config config; struct list_head node; void (*csdev_release)(struct device *dev);
enum cti_subtype subtype;const u32 *offsets;};
/* @@ -234,6 +270,11 @@ struct coresight_platform_data * coresight_cti_get_platform_data(struct device *dev); const char *cti_plat_get_node_name(struct fwnode_handle *fwnode);
+static inline u32 cti_offset(struct cti_drvdata *drvdata, int index, int num) +{
return drvdata->offsets[index] + 4 * num;+}
/* cti powered and enabled */ static inline bool cti_active(struct cti_config *cfg) { diff --git a/drivers/hwtracing/coresight/qcom-cti.h b/drivers/hwtracing/coresight/qcom-cti.h new file mode 100644 index 000000000000..eaa551ff118a --- /dev/null +++ b/drivers/hwtracing/coresight/qcom-cti.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only
- Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
- */
+#define ARCHITECT_QCOM 0x477
This value which is an 11 bit value, in bits 31:21 of the DEVARCH register, is co-incidentally the same as the top 12 bits 31:20 of the ARM DEVARCH register for standard ARM component.
Bit 20 of DEVARCH is 1'b1 for present - the 11 bits 31:21 make the archiitect value. ARMs assigned JEDEC architect value 11h'23B which when shifted left by one and ORed with bit 20 gives a value of 12h'477 for bits 31:20.
Assuming that your 11 bit JEDEC architect value is 0x477 then the top 12 bits of the qcom devarch register must be 12h'8EF
I'd like to be sure that no errors have been made, please confim that bits 31:20 in your DEVARCH register are 0x8EF, and this patch has been tested as working on your system.
Thanks and Regards
Mike
+/* CTI programming registers */ +#define QCOM_CTIINTACK 0x020 +#define QCOM_CTIAPPSET 0x004 +#define QCOM_CTIAPPCLEAR 0x008 +#define QCOM_CTIAPPPULSE 0x00C +#define QCOM_CTIINEN 0x400 +#define QCOM_CTIOUTEN 0x800 +#define QCOM_CTITRIGINSTATUS 0x040 +#define QCOM_CTITRIGOUTSTATUS 0x060 +#define QCOM_CTICHINSTATUS 0x080 +#define QCOM_CTICHOUTSTATUS 0x084 +#define QCOM_CTIGATE 0x088 +#define QCOM_ASICCTL 0x08c +/* Integration test registers */ +#define QCOM_ITCHINACK 0xE70 +#define QCOM_ITTRIGINACK 0xE80 +#define QCOM_ITCHOUT 0xE74 +#define QCOM_ITTRIGOUT 0xEA0 +#define QCOM_ITCHOUTACK 0xE78 +#define QCOM_ITTRIGOUTACK 0xEC0 +#define QCOM_ITCHIN 0xE7C +#define QCOM_ITTRIGIN 0xEE0
-- 2.43.0
-- Mike Leach Principal Engineer, ARM Ltd. Manchester Design Centre. UK