Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915/perf: Apply Wa_18013179988

OA reports in the OA buffer contain an OA timestamp field that helps
user calculate delta between 2 OA reports. The calculation relies on the
CS timestamp frequency to convert the timestamp value to nanoseconds.
The CS timestamp frequency is a function of the CTC_SHIFT value in
RPM_CONFIG0.

In DG2, OA unit assumes that the CTC_SHIFT is 3, instead of using the
actual value from RPM_CONFIG0. At the user level, this results in an
error in calculating delta between 2 OA reports since the OA timestamp
is not shifted in the same manner as CS timestamp. Also the periodicity
of the reports is different from what the user configured because of
mismatch in the CS and OA frequencies.

The issue also affects MI_REPORT_PERF_COUNT command.

To resolve this, return actual OA timestamp frequency to the user in
i915_getparam_ioctl, so that user can calculate the right OA exponent as
well as interpret the reports correctly.

MR: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18893

v2:
- Use REG_FIELD_GET (Ashutosh)
- Update commit msg

Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221026222102.5526-13-umesh.nerlige.ramappa@intel.com

authored by

Umesh Nerlige Ramappa and committed by
John Harrison
bc7ed4d3 ed6b25aa

+39 -2
+3
drivers/gpu/drm/i915/i915_getparam.c
··· 175 175 case I915_PARAM_PERF_REVISION: 176 176 value = i915_perf_ioctl_version(); 177 177 break; 178 + case I915_PARAM_OA_TIMESTAMP_FREQUENCY: 179 + value = i915_perf_oa_timestamp_frequency(i915); 180 + break; 178 181 default: 179 182 DRM_DEBUG("Unknown parameter %d\n", param->param); 180 183 return -EINVAL;
+28 -2
drivers/gpu/drm/i915/i915_perf.c
··· 3109 3109 return i915_gem_user_to_context_sseu(engine->gt, drm_sseu, out_sseu); 3110 3110 } 3111 3111 3112 + /* 3113 + * OA timestamp frequency = CS timestamp frequency in most platforms. On some 3114 + * platforms OA unit ignores the CTC_SHIFT and the 2 timestamps differ. In such 3115 + * cases, return the adjusted CS timestamp frequency to the user. 3116 + */ 3117 + u32 i915_perf_oa_timestamp_frequency(struct drm_i915_private *i915) 3118 + { 3119 + /* Wa_18013179988:dg2 */ 3120 + if (IS_DG2(i915)) { 3121 + intel_wakeref_t wakeref; 3122 + u32 reg, shift; 3123 + 3124 + with_intel_runtime_pm(to_gt(i915)->uncore->rpm, wakeref) 3125 + reg = intel_uncore_read(to_gt(i915)->uncore, RPM_CONFIG0); 3126 + 3127 + shift = REG_FIELD_GET(GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, 3128 + reg); 3129 + 3130 + return to_gt(i915)->clock_frequency << (3 - shift); 3131 + } 3132 + 3133 + return to_gt(i915)->clock_frequency; 3134 + } 3135 + 3112 3136 /** 3113 3137 * i915_oa_stream_init - validate combined props for OA stream and init 3114 3138 * @stream: An i915 perf stream ··· 3854 3830 3855 3831 static u64 oa_exponent_to_ns(struct i915_perf *perf, int exponent) 3856 3832 { 3857 - return intel_gt_clock_interval_to_ns(to_gt(perf->i915), 3858 - 2ULL << exponent); 3833 + u64 nom = (2ULL << exponent) * NSEC_PER_SEC; 3834 + u32 den = i915_perf_oa_timestamp_frequency(perf->i915); 3835 + 3836 + return div_u64(nom + den - 1, den); 3859 3837 } 3860 3838 3861 3839 static __always_inline bool
+2
drivers/gpu/drm/i915/i915_perf.h
··· 57 57 kref_put(&oa_config->ref, i915_oa_config_release); 58 58 } 59 59 60 + u32 i915_perf_oa_timestamp_frequency(struct drm_i915_private *i915); 61 + 60 62 #endif /* __I915_PERF_H__ */
+6
include/uapi/drm/i915_drm.h
··· 765 765 /* Query if the kernel supports the I915_USERPTR_PROBE flag. */ 766 766 #define I915_PARAM_HAS_USERPTR_PROBE 56 767 767 768 + /* 769 + * Frequency of the timestamps in OA reports. This used to be the same as the CS 770 + * timestamp frequency, but differs on some platforms. 771 + */ 772 + #define I915_PARAM_OA_TIMESTAMP_FREQUENCY 57 773 + 768 774 /* Must be kept compact -- no holes and well documented */ 769 775 770 776 /**