From 9d0db8d4c487efcc722cf77a6304168125234c34 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 23 Jun 2021 19:17:51 +0300 Subject: [PATCH] intel/perf: deal with OA reports timestamp values on DG2 OA reports on XeHP have their timestamp shifted to the left by 1. To get that back in the same time domain as the REG_READ you need to shift it back to the right and you're loosing the top bit. v2: use ull for 64bit constant (Ian) Signed-off-by: Lionel Landwerlin Reviewed-by: Ian Romanick Part-of: --- src/intel/ds/intel_pps_driver.cc | 7 ++++--- src/intel/perf/intel_perf.c | 9 ++++++++- src/intel/perf/intel_perf.h | 12 ++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/intel/ds/intel_pps_driver.cc b/src/intel/ds/intel_pps_driver.cc index 81a46252e2f..c54aaca643e 100644 --- a/src/intel/ds/intel_pps_driver.cc +++ b/src/intel/ds/intel_pps_driver.cc @@ -161,6 +161,7 @@ void IntelDriver::enable_perfcnt(uint64_t sampling_period_ns) { this->sampling_period_ns = sampling_period_ns; + gpu_timestamp_udw = intel_read_gpu_timestamp(drm_device.fd) & ~perf->cfg->oa_timestamp_mask; if (!perf->open(sampling_period_ns, selected_query)) { PPS_LOG_FATAL("Failed to open intel perf"); } @@ -212,10 +213,10 @@ std::vector IntelDriver::parse_perf_records(const std::vectorcfg->oa_timestamp_mask; - uint64_t gpu_timestamp = gpu_timestamp_udw + gpu_timestamp_ldw; + uint64_t gpu_timestamp = gpu_timestamp_udw | gpu_timestamp_ldw; auto duration = intel_device_info_timebase_scale(&perf->devinfo, gpu_timestamp - prev_gpu_timestamp); diff --git a/src/intel/perf/intel_perf.c b/src/intel/perf/intel_perf.c index 88ab9595846..a5ed622439f 100644 --- a/src/intel/perf/intel_perf.c +++ b/src/intel/perf/intel_perf.c @@ -714,6 +714,13 @@ oa_metrics_available(struct intel_perf_config *perf, int fd, perf->i915_query_supported = i915_query_perf_config_supported(perf, fd); perf->i915_perf_version = i915_perf_version(fd); + /* TODO: We should query this from i915 */ + if (intel_device_info_is_dg2(devinfo)) + perf->oa_timestamp_shift = 1; + + perf->oa_timestamp_mask = + 0xffffffffffffffffull >> (32 + perf->oa_timestamp_shift); + /* Record the default SSEU configuration. */ i915_get_sseu(fd, &perf->sseu); @@ -1042,7 +1049,7 @@ uint64_t intel_perf_report_timestamp(const struct intel_perf_query_info *query, const uint32_t *report) { - return report[1]; + return report[1] >> query->perf->oa_timestamp_shift; } void diff --git a/src/intel/perf/intel_perf.h b/src/intel/perf/intel_perf.h index 6f26041c443..bb809a42afc 100644 --- a/src/intel/perf/intel_perf.h +++ b/src/intel/perf/intel_perf.h @@ -326,6 +326,18 @@ struct intel_perf_config { /* Version of the i915-perf subsystem, refer to i915_drm.h. */ int i915_perf_version; + /* Number of bits to shift the OA timestamp values by to match the ring + * timestamp. + */ + int oa_timestamp_shift; + + /* Mask of bits valid from the OA report (for instance you might have the + * lower 31 bits [30:0] of timestamp value). This is useful if you want to + * recombine a full timestamp value captured from the CPU with OA + * timestamps captured on the device but that only include 31bits of data. + */ + uint64_t oa_timestamp_mask; + /* Powergating configuration for the running the query. */ struct drm_i915_gem_context_param_sseu sseu;