[Intel-gfx] [PATCH 2/2] drm/i915: l3 parity sysfs interface
Ben Widawsky
ben at bwidawsk.net
Sat Apr 14 01:05:14 CEST 2012
Dumb binary interfaces which allow root-only updates of our cache
remapping registers. See intel-gpu-tools for how this can/should be
used.
Signed-off-by: Ben Widawsky <benjamin.widawsky at intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 10 ++++
drivers/gpu/drm/i915/i915_sysfs.c | 103 ++++++++++++++++++++++++++++++++++++-
2 files changed, 111 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index de1685e..1a93395 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4007,6 +4007,16 @@
#define GEN7_PARITY_ERROR_SUBBANK(reg) \
((reg & GEN7_L3CDERRST1_SUBBANK_MASK) >> 8)
+#define GEN7_L3LOG_BASE 0xB070
+#define GEN7_L3LOG_SIZE 0x80
+#if 0
+#define GEN7_L3LOG_ROW1(reg) ((reg>>21) & IVYBRDIGE_L3_ROW_MASK)
+#define GEN7_L3LOG_VLDERR1 (1<<16)
+#define GEN7_L3LOG_ROW0(reg) ((reg>>5) & IVYBRDIGE_L3_ROW_MASK)
+#define GEN7_L3LOG_VLDERR0 (1<<0)
+#endif
+
+
#define G4X_AUD_VID_DID 0x62020
#define INTEL_AUDIO_DEVCL 0x808629FB
#define INTEL_AUDIO_DEVBLC 0x80862801
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index f1b5108..fe37960 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -92,20 +92,119 @@ static struct attribute_group rc6_attr_group = {
.attrs = rc6_attrs
};
+static bool is_l3_access_valid(struct drm_device *dev, loff_t offset)
+{
+ if (!IS_IVYBRIDGE(dev))
+ return false;
+
+ if (offset >= GEN7_L3LOG_SIZE)
+ return false;
+
+ if (offset % 4 != 0)
+ return false;
+
+ return true;
+}
+
+static ssize_t
+i915_l3_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t offset, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ struct drm_device *drm_dev = dminor->dev;
+ struct drm_i915_private *dev_priv = drm_dev->dev_private;
+ int i;
+
+ if (is_l3_access_valid(drm_dev, offset))
+ return 0;
+
+ if (i915_mutex_lock_interruptible(drm_dev))
+ return 0;
+
+ I915_WRITE(GEN7_MISCCPCTL,
+ I915_READ(GEN7_MISCCPCTL) & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+ POSTING_READ(GEN7_MISCCPCTL);
+
+ for (i = offset; count >= 4 && i < GEN7_L3LOG_SIZE; i += 4, count -= 4)
+ buf[i] = I915_READ(GEN7_L3LOG_BASE + i);
+
+ I915_WRITE(GEN7_MISCCPCTL,
+ I915_READ(GEN7_MISCCPCTL) | GEN7_DOP_CLOCK_GATE_ENABLE);
+ POSTING_READ(GEN7_MISCCPCTL);
+
+ mutex_unlock(&drm_dev->struct_mutex);
+
+ return i - offset;
+}
+
+static ssize_t
+i915_l3_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t offset, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
+ struct drm_device *drm_dev = dminor->dev;
+ struct drm_i915_private *dev_priv = drm_dev->dev_private;
+ int i;
+
+ if (is_l3_access_valid(drm_dev, offset))
+ return 0;
+
+ if (i915_mutex_lock_interruptible(drm_dev))
+ return 0;
+
+ I915_WRITE(GEN7_MISCCPCTL,
+ I915_READ(GEN7_MISCCPCTL) & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+ POSTING_READ(GEN7_MISCCPCTL);
+
+
+ for (i = offset; count >= 4 && i < GEN7_L3LOG_SIZE; i += 4, count -= 4) {
+ uint32_t data = *(uint32_t *)(&buf[i]);
+ I915_WRITE(GEN7_L3LOG_BASE + i, data);
+ }
+
+ I915_WRITE(GEN7_MISCCPCTL,
+ I915_READ(GEN7_MISCCPCTL) | GEN7_DOP_CLOCK_GATE_ENABLE);
+ POSTING_READ(GEN7_MISCCPCTL);
+
+ mutex_unlock(&drm_dev->struct_mutex);
+
+ return 0;
+}
+
+static struct bin_attribute dpf_attrs = {
+ .attr = {.name = "l3_parity", .mode = (S_IRWXU)},
+ .size = GEN7_L3LOG_SIZE,
+ .read = i915_l3_read,
+ .write = i915_l3_write,
+ .mmap = NULL
+};
+
void i915_setup_sysfs(struct drm_device *dev)
{
int ret;
- /* ILK doesn't have any residency information */
+ /* ILK and below don't yet have relevant sysfs files */
if (INTEL_INFO(dev)->gen < 6)
return;
ret = sysfs_merge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
if (ret)
- DRM_ERROR("sysfs setup failed\n");
+ DRM_ERROR("RC6 residency sysfs setup failed\n");
+
+ if (!IS_IVYBRIDGE(dev))
+ return;
+
+ ret = device_create_bin_file(&dev->primary->kdev, &dpf_attrs);
+ if (ret)
+ DRM_ERROR("l3 parity sysfs setup failed\n");
}
void i915_teardown_sysfs(struct drm_device *dev)
{
+ device_remove_bin_file(&dev->primary->kdev, &dpf_attrs);
sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
}
--
1.7.10
More information about the Intel-gfx
mailing list