diff options
author | Damien Lespiau <damien.lespiau@intel.com> | 2013-10-15 13:55:29 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-10-16 07:32:10 -0400 |
commit | b2c88f5b1dea77b57759387728917a124eb1c098 (patch) | |
tree | b82258528bfb2cbb7b2ff03cced9ba30e818a30c /drivers/gpu | |
parent | 926321d503406d1fefb2fae9651beca14160529a (diff) |
drm/i915: Keep the CRC values into a circular buffer
There are a few good properties to a circular buffer, for instance it
has a number of entries (before we were always dumping the full buffer).
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 19 |
3 files changed, 29 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0d8a9a397a24..991abff94e1e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -27,6 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/circ_buf.h> | ||
30 | #include <linux/ctype.h> | 31 | #include <linux/ctype.h> |
31 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
32 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
@@ -1739,25 +1740,28 @@ static int i915_pipe_crc(struct seq_file *m, void *data) | |||
1739 | struct drm_device *dev = node->minor->dev; | 1740 | struct drm_device *dev = node->minor->dev; |
1740 | struct drm_i915_private *dev_priv = dev->dev_private; | 1741 | struct drm_i915_private *dev_priv = dev->dev_private; |
1741 | enum pipe pipe = (enum pipe)node->info_ent->data; | 1742 | enum pipe pipe = (enum pipe)node->info_ent->data; |
1742 | const struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; | 1743 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; |
1743 | int i; | 1744 | int head, tail; |
1744 | int start; | ||
1745 | 1745 | ||
1746 | if (dev_priv->pipe_crc[pipe].source == INTEL_PIPE_CRC_SOURCE_NONE) { | 1746 | if (dev_priv->pipe_crc[pipe].source == INTEL_PIPE_CRC_SOURCE_NONE) { |
1747 | seq_puts(m, "none\n"); | 1747 | seq_puts(m, "none\n"); |
1748 | return 0; | 1748 | return 0; |
1749 | } | 1749 | } |
1750 | 1750 | ||
1751 | start = atomic_read(&pipe_crc->slot) + 1; | ||
1752 | seq_puts(m, " timestamp CRC1 CRC2 CRC3 CRC4 CRC5\n"); | 1751 | seq_puts(m, " timestamp CRC1 CRC2 CRC3 CRC4 CRC5\n"); |
1753 | for (i = 0; i < INTEL_PIPE_CRC_ENTRIES_NR; i++) { | 1752 | head = atomic_read(&pipe_crc->head); |
1754 | const struct intel_pipe_crc_entry *entry = | 1753 | tail = atomic_read(&pipe_crc->tail); |
1755 | &pipe_crc->entries[(start + i) % | 1754 | |
1756 | INTEL_PIPE_CRC_ENTRIES_NR]; | 1755 | while (CIRC_CNT(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) >= 1) { |
1756 | struct intel_pipe_crc_entry *entry = &pipe_crc->entries[tail]; | ||
1757 | 1757 | ||
1758 | seq_printf(m, "%12u %8x %8x %8x %8x %8x\n", entry->timestamp, | 1758 | seq_printf(m, "%12u %8x %8x %8x %8x %8x\n", entry->timestamp, |
1759 | entry->crc[0], entry->crc[1], entry->crc[2], | 1759 | entry->crc[0], entry->crc[1], entry->crc[2], |
1760 | entry->crc[3], entry->crc[4]); | 1760 | entry->crc[3], entry->crc[4]); |
1761 | |||
1762 | BUILD_BUG_ON_NOT_POWER_OF_2(INTEL_PIPE_CRC_ENTRIES_NR); | ||
1763 | tail = (tail + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1); | ||
1764 | atomic_set(&pipe_crc->tail, tail); | ||
1761 | } | 1765 | } |
1762 | 1766 | ||
1763 | return 0; | 1767 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bfaaaaee8a5b..a29a4a1d300a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1230,11 +1230,11 @@ struct intel_pipe_crc_entry { | |||
1230 | uint32_t crc[5]; | 1230 | uint32_t crc[5]; |
1231 | }; | 1231 | }; |
1232 | 1232 | ||
1233 | #define INTEL_PIPE_CRC_ENTRIES_NR 200 | 1233 | #define INTEL_PIPE_CRC_ENTRIES_NR 128 |
1234 | struct intel_pipe_crc { | 1234 | struct intel_pipe_crc { |
1235 | struct intel_pipe_crc_entry entries[INTEL_PIPE_CRC_ENTRIES_NR]; | 1235 | struct intel_pipe_crc_entry entries[INTEL_PIPE_CRC_ENTRIES_NR]; |
1236 | enum intel_pipe_crc_source source; | 1236 | enum intel_pipe_crc_source source; |
1237 | atomic_t slot; | 1237 | atomic_t head, tail; |
1238 | }; | 1238 | }; |
1239 | 1239 | ||
1240 | typedef struct drm_i915_private { | 1240 | typedef struct drm_i915_private { |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d2074f129a36..73d76af13ed4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <linux/sysrq.h> | 31 | #include <linux/sysrq.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/circ_buf.h> | ||
33 | #include <drm/drmP.h> | 34 | #include <drm/drmP.h> |
34 | #include <drm/i915_drm.h> | 35 | #include <drm/i915_drm.h> |
35 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
@@ -1195,20 +1196,30 @@ static void ivb_pipe_crc_update(struct drm_device *dev, enum pipe pipe) | |||
1195 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; | 1196 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; |
1196 | struct intel_pipe_crc_entry *entry; | 1197 | struct intel_pipe_crc_entry *entry; |
1197 | ktime_t now; | 1198 | ktime_t now; |
1198 | int ts, slot; | 1199 | int ts, head, tail; |
1200 | |||
1201 | head = atomic_read(&pipe_crc->head); | ||
1202 | tail = atomic_read(&pipe_crc->tail); | ||
1203 | |||
1204 | if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) { | ||
1205 | DRM_ERROR("CRC buffer overflowing\n"); | ||
1206 | return; | ||
1207 | } | ||
1208 | |||
1209 | entry = &pipe_crc->entries[head]; | ||
1199 | 1210 | ||
1200 | now = ktime_get(); | 1211 | now = ktime_get(); |
1201 | ts = ktime_to_us(now); | 1212 | ts = ktime_to_us(now); |
1202 | 1213 | ||
1203 | slot = (atomic_read(&pipe_crc->slot) + 1) % INTEL_PIPE_CRC_ENTRIES_NR; | ||
1204 | entry = &pipe_crc->entries[slot]; | ||
1205 | entry->timestamp = ts; | 1214 | entry->timestamp = ts; |
1206 | entry->crc[0] = I915_READ(PIPE_CRC_RES_1_IVB(pipe)); | 1215 | entry->crc[0] = I915_READ(PIPE_CRC_RES_1_IVB(pipe)); |
1207 | entry->crc[1] = I915_READ(PIPE_CRC_RES_2_IVB(pipe)); | 1216 | entry->crc[1] = I915_READ(PIPE_CRC_RES_2_IVB(pipe)); |
1208 | entry->crc[2] = I915_READ(PIPE_CRC_RES_3_IVB(pipe)); | 1217 | entry->crc[2] = I915_READ(PIPE_CRC_RES_3_IVB(pipe)); |
1209 | entry->crc[3] = I915_READ(PIPE_CRC_RES_4_IVB(pipe)); | 1218 | entry->crc[3] = I915_READ(PIPE_CRC_RES_4_IVB(pipe)); |
1210 | entry->crc[4] = I915_READ(PIPE_CRC_RES_5_IVB(pipe)); | 1219 | entry->crc[4] = I915_READ(PIPE_CRC_RES_5_IVB(pipe)); |
1211 | atomic_set(&dev_priv->pipe_crc[pipe].slot, slot); | 1220 | |
1221 | head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1); | ||
1222 | atomic_set(&pipe_crc->head, head); | ||
1212 | } | 1223 | } |
1213 | #else | 1224 | #else |
1214 | static void ivb_pipe_crc_update(struct drm_device *dev, int pipe) {} | 1225 | static void ivb_pipe_crc_update(struct drm_device *dev, int pipe) {} |