Timestamps are currently emitted at the maximum rate possible, which is much too frequent for most use cases. In the next commit, the timestamp field will be widened to take a value, so set the interval using the value now. Granular control is not required, so save space in the config by interpreting it as 2 ^ timestamp. And then 4 bits (0 - 15) will be enough to set the interval to be larger than the existing SYNC timestamp interval.
No sysfs mode support is needed for this attribute because counter generated timestamps are only configured for Perf mode.
Reviewed-by: Leo Yan leo.yan@arm.com Tested-by: Leo Yan leo.yan@arm.com Signed-off-by: James Clark james.clark@linaro.org --- drivers/hwtracing/coresight/coresight-etm4x-core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index b457f182efbe..7e9c923acf4b 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -650,7 +650,7 @@ static void etm4_enable_sysfs_smp_call(void *info) * +--------------+ * | * +------v-------+ - * | Counter x | (reload to 1 on underflow) + * | Counter x | (reload to 2 ^ (ts_level - 1) on underflow) * +--------------+ * | * +------v--------------+ @@ -661,7 +661,8 @@ static void etm4_enable_sysfs_smp_call(void *info) * | Timestamp Generator | (timestamp on resource y) * +----------------------+ */ -static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata) +static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata, + u8 ts_level) { int ctridx; int rselector; @@ -703,12 +704,8 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata) return -ENOSPC; }
- /* - * Initialise original and reload counter value to the smallest - * possible value in order to get as much precision as we can. - */ - config->cntr_val[ctridx] = 1; - config->cntrldvr[ctridx] = 1; + /* Initialise original and reload counter value. */ + config->cntr_val[ctridx] = config->cntrldvr[ctridx] = 1 << (ts_level - 1);
/* * Trace Counter Control Register TRCCNTCTLRn @@ -756,6 +753,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev, struct perf_event_attr *attr = &event->attr; unsigned long cfg_hash; int preset, cc_threshold; + u8 ts_level;
/* Clear configuration from previous run */ memset(config, 0, sizeof(struct etmv4_config)); @@ -791,13 +789,15 @@ static int etm4_parse_event_config(struct coresight_device *csdev, cc_threshold = drvdata->ccitmin; config->ccctlr = cc_threshold; } - if (ATTR_CFG_GET_FLD(attr, timestamp)) { + + ts_level = ATTR_CFG_GET_FLD(attr, timestamp); + if (ts_level) { /* * Configure timestamps to be emitted at regular intervals in * order to correlate instructions executed on different CPUs * (CPU-wide trace scenarios). */ - ret = etm4_config_timestamp_event(drvdata); + ret = etm4_config_timestamp_event(drvdata, ts_level);
/* * No need to go further if timestamp intervals can't