While enabling coresight source device, make a Trace trigger event connection between ETM and CTI. The connection will be made only when the source has valid connection request.
Source device could use this CTI connection to synchronize stop events across cores.
Signed-off-by: Linu Cherian lcherian@marvell.com --- drivers/hwtracing/coresight/coresight-core.c | 41 ++++++++++++++++++- .../hwtracing/coresight/coresight-cti-core.c | 20 +++++++++ drivers/hwtracing/coresight/coresight-cti.h | 4 ++ include/linux/coresight.h | 6 +++ 4 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 8a18c71df37a..9b9a932b982f 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -427,6 +427,38 @@ static void coresight_disable_link(struct coresight_device *csdev, csdev->enable = false; }
+/** + * coresight_config_trace_event - Enable/Disable the trace event + * input and output signals on the ECT. + * + * @csdev: The coresight source device + * + * Returns 0 on success, when a connection is made or removed or + * no connection is requested by the source device. + **/ +static int coresight_config_trace_event(struct coresight_device *csdev, + bool enable) +{ + int ret; + int trig_idx; + struct coresight_device *ect_csdev = csdev->ect_dev; + + if (source_ops(csdev)->get_trace_event_idx) { + trig_idx = source_ops(csdev)->get_trace_event_idx(csdev); + if (trig_idx < 0) + goto out; /* nothing to be done */ + if (!ect_ops(ect_csdev)->trace_event_config) + return -EINVAL; + ret = ect_ops(ect_csdev)->trace_event_config(ect_csdev, + trig_idx, enable); + if (ret) + return ret; + } + +out: + return 0; +} + static int coresight_enable_source(struct coresight_device *csdev, u32 mode) { int ret; @@ -439,11 +471,17 @@ static int coresight_enable_source(struct coresight_device *csdev, u32 mode)
if (!csdev->enable) { if (source_ops(csdev)->enable) { - ret = coresight_control_assoc_ectdev(csdev, true); + ret = coresight_config_trace_event(csdev, true); if (ret) return ret; + ret = coresight_control_assoc_ectdev(csdev, true); + if (ret) { + coresight_config_trace_event(csdev, false); + return ret; + } ret = source_ops(csdev)->enable(csdev, NULL, mode); if (ret) { + coresight_config_trace_event(csdev, false); coresight_control_assoc_ectdev(csdev, false); return ret; } @@ -469,6 +507,7 @@ static bool coresight_disable_source(struct coresight_device *csdev) if (atomic_dec_return(csdev->refcnt) == 0) { if (source_ops(csdev)->disable) source_ops(csdev)->disable(csdev, NULL); + coresight_config_trace_event(csdev, false); coresight_control_assoc_ectdev(csdev, false); csdev->enable = false; } diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c index e2a3620cbf48..ec72d84cbde4 100644 --- a/drivers/hwtracing/coresight/coresight-cti-core.c +++ b/drivers/hwtracing/coresight/coresight-cti-core.c @@ -806,9 +806,29 @@ int cti_disable(struct coresight_device *csdev) return cti_disable_hw(drvdata); }
+static int cti_trace_event_config(struct coresight_device *csdev, int idx, bool enable) +{ + int val; + struct cti_drvdata *drvdata = csdev_to_cti_drvdata(csdev); + struct cti_config *config = &drvdata->config; + + if (enable) + val = BIT(CTI_CHAN_0); + else + val = 0x0; + + config->ctiinen[CTI_TRIGIN_TRACE_EVENT_0 + idx] = val; + config->ctiouten[CTI_TRIGOUT_TRACE_EVENT_0 + idx] = val; + config->ctigate = val; + + return 0; +} + + static const struct coresight_ops_ect cti_ops_ect = { .enable = cti_enable, .disable = cti_disable, + .trace_event_config = cti_trace_event_config, };
static const struct coresight_ops cti_ops = { diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h index acf7b545e6b9..ab94bf2eab29 100644 --- a/drivers/hwtracing/coresight/coresight-cti.h +++ b/drivers/hwtracing/coresight/coresight-cti.h @@ -58,6 +58,10 @@ */ #define CTIINOUTEN_MAX 32
+#define CTI_TRIGIN_TRACE_EVENT_0 0x4 +#define CTI_TRIGOUT_TRACE_EVENT_0 0x4 +#define CTI_CHAN_0 0x0 + /** * Group of related trigger signals * diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 93a2922b7653..17ab5f2bfe4c 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -323,6 +323,7 @@ struct coresight_ops_link { * to the HW. * @enable: enables tracing for a source. * @disable: disables tracing for a source. + * @get_trace_event_idx: returns the value of trace event index to be enabled */ struct coresight_ops_source { int (*cpu_id)(struct coresight_device *csdev); @@ -331,6 +332,7 @@ struct coresight_ops_source { struct perf_event *event, u32 mode); void (*disable)(struct coresight_device *csdev, struct perf_event *event); + int (*get_trace_event_idx)(struct coresight_device *csdev); };
/** @@ -352,10 +354,14 @@ struct coresight_ops_helper { * * @enable : Enable the device * @disable : Disable the device + * @trace_event_config: Enable/Disable Trace Event In/Out index + * */ struct coresight_ops_ect { int (*enable)(struct coresight_device *csdev); int (*disable)(struct coresight_device *csdev); + int (*trace_event_config)(struct coresight_device *csdev, + int idx, bool enable); };
struct coresight_ops {