diff options
| -rw-r--r-- | drivers/gpu/drm/i915/intel_uncore.c | 26 | ||||
| -rw-r--r-- | include/uapi/drm/i915_drm.h | 8 |
2 files changed, 27 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index a6d8a3ee7750..260389acfb77 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
| @@ -1274,10 +1274,12 @@ int i915_reg_read_ioctl(struct drm_device *dev, | |||
| 1274 | struct drm_i915_private *dev_priv = dev->dev_private; | 1274 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1275 | struct drm_i915_reg_read *reg = data; | 1275 | struct drm_i915_reg_read *reg = data; |
| 1276 | struct register_whitelist const *entry = whitelist; | 1276 | struct register_whitelist const *entry = whitelist; |
| 1277 | unsigned size; | ||
| 1278 | u64 offset; | ||
| 1277 | int i, ret = 0; | 1279 | int i, ret = 0; |
| 1278 | 1280 | ||
| 1279 | for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) { | 1281 | for (i = 0; i < ARRAY_SIZE(whitelist); i++, entry++) { |
| 1280 | if (entry->offset == reg->offset && | 1282 | if (entry->offset == (reg->offset & -entry->size) && |
| 1281 | (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask)) | 1283 | (1 << INTEL_INFO(dev)->gen & entry->gen_bitmask)) |
| 1282 | break; | 1284 | break; |
| 1283 | } | 1285 | } |
| @@ -1285,23 +1287,33 @@ int i915_reg_read_ioctl(struct drm_device *dev, | |||
| 1285 | if (i == ARRAY_SIZE(whitelist)) | 1287 | if (i == ARRAY_SIZE(whitelist)) |
| 1286 | return -EINVAL; | 1288 | return -EINVAL; |
| 1287 | 1289 | ||
| 1290 | /* We use the low bits to encode extra flags as the register should | ||
| 1291 | * be naturally aligned (and those that are not so aligned merely | ||
| 1292 | * limit the available flags for that register). | ||
| 1293 | */ | ||
| 1294 | offset = entry->offset; | ||
| 1295 | size = entry->size; | ||
| 1296 | size |= reg->offset ^ offset; | ||
| 1297 | |||
| 1288 | intel_runtime_pm_get(dev_priv); | 1298 | intel_runtime_pm_get(dev_priv); |
| 1289 | 1299 | ||
| 1290 | switch (entry->size) { | 1300 | switch (size) { |
| 1301 | case 8 | 1: | ||
| 1302 | reg->val = I915_READ64_2x32(offset, offset+4); | ||
| 1303 | break; | ||
| 1291 | case 8: | 1304 | case 8: |
| 1292 | reg->val = I915_READ64(reg->offset); | 1305 | reg->val = I915_READ64(offset); |
| 1293 | break; | 1306 | break; |
| 1294 | case 4: | 1307 | case 4: |
| 1295 | reg->val = I915_READ(reg->offset); | 1308 | reg->val = I915_READ(offset); |
| 1296 | break; | 1309 | break; |
| 1297 | case 2: | 1310 | case 2: |
| 1298 | reg->val = I915_READ16(reg->offset); | 1311 | reg->val = I915_READ16(offset); |
| 1299 | break; | 1312 | break; |
| 1300 | case 1: | 1313 | case 1: |
| 1301 | reg->val = I915_READ8(reg->offset); | 1314 | reg->val = I915_READ8(offset); |
| 1302 | break; | 1315 | break; |
| 1303 | default: | 1316 | default: |
| 1304 | MISSING_CASE(entry->size); | ||
| 1305 | ret = -EINVAL; | 1317 | ret = -EINVAL; |
| 1306 | goto out; | 1318 | goto out; |
| 1307 | } | 1319 | } |
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 6e1a2ed116cb..db809b722985 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h | |||
| @@ -1070,6 +1070,14 @@ struct drm_i915_reg_read { | |||
| 1070 | __u64 offset; | 1070 | __u64 offset; |
| 1071 | __u64 val; /* Return value */ | 1071 | __u64 val; /* Return value */ |
| 1072 | }; | 1072 | }; |
| 1073 | /* Known registers: | ||
| 1074 | * | ||
| 1075 | * Render engine timestamp - 0x2358 + 64bit - gen7+ | ||
| 1076 | * - Note this register returns an invalid value if using the default | ||
| 1077 | * single instruction 8byte read, in order to workaround that use | ||
| 1078 | * offset (0x2538 | 1) instead. | ||
| 1079 | * | ||
| 1080 | */ | ||
| 1073 | 1081 | ||
| 1074 | struct drm_i915_reset_stats { | 1082 | struct drm_i915_reset_stats { |
| 1075 | __u32 ctx_id; | 1083 | __u32 ctx_id; |
