[Intel-gfx] [PATCH v2] drm/i915: Expose all 36-bits of TIMESTAMP register on x86_64

Michał Winiarski michal.winiarski at intel.com
Wed Oct 8 18:34:23 CEST 2014


Reading timestamp register using I915_READ64 returns incorrect value
containing only 32-bits of usable timestamp on x86_64.
Let's use I915_READ64_2x32 to expose missing bits and swap dwords to
stay compatible with old userspace.

v2: Renamed macro used for swapping dwords to be more like swab.h
macros. Added comments.

Signed-off-by: Michał Winiarski <michal.winiarski at intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 0b0f4f8..c47372e 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -40,6 +40,13 @@
 
 #define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__)
 
+/* swap half-words in qword
+ * __swahw64(0x0123456789ABCDEF) is 0x89ABCDEF01234567
+ */
+#define __swahw64(x) ((__u64)(					\
+	(((__u64)(x) & (__u64)0x00000000ffffffffULL) << 32) |	\
+	(((__u64)(x) & (__u64)0xffffffff00000000ULL) >> 32)))
+
 static void
 assert_device_not_suspended(struct drm_i915_private *dev_priv)
 {
@@ -989,7 +996,8 @@ int i915_reg_read_ioctl(struct drm_device *dev,
 
 	switch (entry->size) {
 	case 8:
-		reg->val = I915_READ64(reg->offset);
+		/* Use 2x32 read, otherwise it's possible to get corrupted results */
+		reg->val = I915_READ64_2x32(reg->offset, reg->offset + 4);
 		break;
 	case 4:
 		reg->val = I915_READ(reg->offset);
@@ -1006,6 +1014,10 @@ int i915_reg_read_ioctl(struct drm_device *dev,
 		goto out;
 	}
 
+	/* To maintain compatibility with old userspace we need to swap dwords */
+	if (reg->offset == RING_TIMESTAMP(RENDER_RING_BASE))
+		reg->val = __swahw64(reg->val);
+
 out:
 	intel_runtime_pm_put(dev_priv);
 	return ret;
-- 
1.9.3




More information about the Intel-gfx mailing list