From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Damien Lespiau <damien.lespiau@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 01/16] drm/i915: Expose latest 200 CRC value for pipe through debugfs
Date: Wed, 16 Oct 2013 13:29:32 +0300 [thread overview]
Message-ID: <20131016102932.GV13047@intel.com> (raw)
In-Reply-To: <1381859742-24887-2-git-send-email-damien.lespiau@intel.com>
On Tue, Oct 15, 2013 at 06:55:27PM +0100, Damien Lespiau wrote:
> From: Shuang He <shuang.he@intel.com>
>
> There are several points in the display pipeline where CRCs can be
> computed on the bits flowing there. For instance, it's usually possible
> to compute the CRCs of the primary plane, the sprite plane or the CRCs
> of the bits after the panel fitter (collectively called pipe CRCs).
>
> v2: Quite a bit of rework here and there (Damien)
>
> Signed-off-by: Shuang He <shuang.he@intel.com>
> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 33 +++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_drv.h | 16 ++++++++++++++++
> drivers/gpu/drm/i915/i915_irq.c | 35 +++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_reg.h | 36 +++++++++++++++++++++++++++++++++++-
> 4 files changed, 119 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 72d0458..e1d45aa 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1732,6 +1732,36 @@ static int i915_pc8_status(struct seq_file *m, void *unused)
> return 0;
> }
>
> +static int i915_pipe_crc(struct seq_file *m, void *data)
> +{
> + struct drm_info_node *node = (struct drm_info_node *) m->private;
> + struct drm_device *dev = node->minor->dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + enum pipe pipe = (enum pipe)node->info_ent->data;
> + const struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
> + int i;
> + int start;
> +
> + if (!IS_IVYBRIDGE(dev)) {
> + seq_puts(m, "unsupported\n");
> + return 0;
> + }
> +
> + start = atomic_read(&pipe_crc->slot) + 1;
> + seq_puts(m, " timestamp CRC1 CRC2 CRC3 CRC4 CRC5\n");
> + for (i = 0; i < INTEL_PIPE_CRC_ENTRIES_NR; i++) {
> + const struct intel_pipe_crc_entry *entry =
> + &pipe_crc->entries[(start + i) %
> + INTEL_PIPE_CRC_ENTRIES_NR];
> +
> + seq_printf(m, "%12u %8x %8x %8x %8x %8x\n", entry->timestamp,
> + entry->crc[0], entry->crc[1], entry->crc[2],
> + entry->crc[3], entry->crc[4]);
> + }
> +
> + return 0;
> +}
> +
> static int
> i915_wedged_get(void *data, u64 *val)
> {
> @@ -2247,6 +2277,9 @@ static struct drm_info_list i915_debugfs_list[] = {
> {"i915_edp_psr_status", i915_edp_psr_status, 0},
> {"i915_energy_uJ", i915_energy_uJ, 0},
> {"i915_pc8_status", i915_pc8_status, 0},
> + {"i915_pipe_A_crc", i915_pipe_crc, 0, (void *)PIPE_A},
> + {"i915_pipe_B_crc", i915_pipe_crc, 0, (void *)PIPE_B},
> + {"i915_pipe_C_crc", i915_pipe_crc, 0, (void *)PIPE_C},
> };
> #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 6106d3d..6855d91 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1219,6 +1219,18 @@ struct i915_package_c8 {
> } regsave;
> };
>
> +struct intel_pipe_crc_entry {
> + uint32_t timestamp;
> + uint32_t crc[5];
> +};
> +
> +#define INTEL_PIPE_CRC_ENTRIES_NR 200
> +struct intel_pipe_crc {
> + struct intel_pipe_crc_entry entries[INTEL_PIPE_CRC_ENTRIES_NR];
> + enum intel_pipe_crc_source source;
> + atomic_t slot;
> +};
> +
> typedef struct drm_i915_private {
> struct drm_device *dev;
> struct kmem_cache *slab;
> @@ -1423,6 +1435,10 @@ typedef struct drm_i915_private {
> struct i915_dri1_state dri1;
> /* Old ums support infrastructure, same warning applies. */
> struct i915_ums_state ums;
> +
> +#ifdef CONFIG_DEBUG_FS
> + struct intel_pipe_crc pipe_crc[I915_MAX_PIPES];
> +#endif
Should we keep this in intel_crtc perhaps?
> } drm_i915_private_t;
>
> static inline struct drm_i915_private *to_i915(const struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 26753b6..d2074f1 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1188,6 +1188,32 @@ static void dp_aux_irq_handler(struct drm_device *dev)
> wake_up_all(&dev_priv->gmbus_wait_queue);
> }
>
> +#if defined(CONFIG_DEBUG_FS)
> +static void ivb_pipe_crc_update(struct drm_device *dev, enum pipe pipe)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
> + struct intel_pipe_crc_entry *entry;
> + ktime_t now;
> + int ts, slot;
> +
> + now = ktime_get();
> + ts = ktime_to_us(now);
> +
> + slot = (atomic_read(&pipe_crc->slot) + 1) % INTEL_PIPE_CRC_ENTRIES_NR;
Looks like using atomic_t for 'slot' doesn't really help us in any way.
> + entry = &pipe_crc->entries[slot];
> + entry->timestamp = ts;
> + entry->crc[0] = I915_READ(PIPE_CRC_RES_1_IVB(pipe));
> + entry->crc[1] = I915_READ(PIPE_CRC_RES_2_IVB(pipe));
> + entry->crc[2] = I915_READ(PIPE_CRC_RES_3_IVB(pipe));
> + entry->crc[3] = I915_READ(PIPE_CRC_RES_4_IVB(pipe));
> + entry->crc[4] = I915_READ(PIPE_CRC_RES_5_IVB(pipe));
> + atomic_set(&dev_priv->pipe_crc[pipe].slot, slot);
> +}
> +#else
> +static void ivb_pipe_crc_update(struct drm_device *dev, int pipe) {}
> +#endif
> +
> /* The RPS events need forcewake, so we add them to a work queue and mask their
> * IMR bits until the work is done. Other interrupts can be processed without
> * the work queue. */
> @@ -1366,6 +1392,15 @@ static void ivb_err_int_handler(struct drm_device *dev)
> if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_C, false))
> DRM_DEBUG_DRIVER("Pipe C FIFO underrun\n");
>
> + if (err_int & ERR_INT_PIPE_CRC_DONE_A)
> + ivb_pipe_crc_update(dev, PIPE_A);
> +
> + if (err_int & ERR_INT_PIPE_CRC_DONE_B)
> + ivb_pipe_crc_update(dev, PIPE_B);
> +
> + if (err_int & ERR_INT_PIPE_CRC_DONE_C)
> + ivb_pipe_crc_update(dev, PIPE_C);
> +
> I915_WRITE(GEN7_ERR_INT, err_int);
> }
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 13153c3..4d01eaf 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -722,8 +722,11 @@
> #define GEN7_ERR_INT 0x44040
> #define ERR_INT_POISON (1<<31)
> #define ERR_INT_MMIO_UNCLAIMED (1<<13)
> +#define ERR_INT_PIPE_CRC_DONE_C (1<<8)
> #define ERR_INT_FIFO_UNDERRUN_C (1<<6)
> +#define ERR_INT_PIPE_CRC_DONE_B (1<<5)
> #define ERR_INT_FIFO_UNDERRUN_B (1<<3)
> +#define ERR_INT_PIPE_CRC_DONE_A (1<<2)
> #define ERR_INT_FIFO_UNDERRUN_A (1<<0)
> #define ERR_INT_FIFO_UNDERRUN(pipe) (1<<(pipe*3))
>
> @@ -1835,6 +1838,38 @@
> * Display engine regs
> */
>
> +/* Pipe A CRC regs */
> +#define _PIPE_CRC_CTL_A (dev_priv->info->display_mmio_offset + 0x60050)
> +#define PIPE_CRC_ENABLE (1 << 31)
> +#define PIPE_CRC_SOURCE_PRIMARY_IVB (0 << 29)
> +#define PIPE_CRC_SOURCE_SPRITE_IVB (1 << 29)
> +#define PIPE_CRC_SOURCE_PF_IVB (2 << 29)
> +#define _PIPE_CRC_RES_1_A_IVB (dev_priv->info->display_mmio_offset + 0x60064)
> +#define _PIPE_CRC_RES_2_A_IVB (dev_priv->info->display_mmio_offset + 0x60068)
> +#define _PIPE_CRC_RES_3_A_IVB (dev_priv->info->display_mmio_offset + 0x6006c)
> +#define _PIPE_CRC_RES_4_A_IVB (dev_priv->info->display_mmio_offset + 0x60070)
> +#define _PIPE_CRC_RES_5_A_IVB (dev_priv->info->display_mmio_offset + 0x60074)
> +
> +/* Pipe B CRC regs */
> +#define _PIPE_CRC_CTL_B (dev_priv->info->display_mmio_offset + 0x61050)
> +#define _PIPE_CRC_RES_1_B_IVB (dev_priv->info->display_mmio_offset + 0x61064)
> +#define _PIPE_CRC_RES_2_B_IVB (dev_priv->info->display_mmio_offset + 0x61068)
> +#define _PIPE_CRC_RES_3_B_IVB (dev_priv->info->display_mmio_offset + 0x6106c)
> +#define _PIPE_CRC_RES_4_B_IVB (dev_priv->info->display_mmio_offset + 0x61070)
> +#define _PIPE_CRC_RES_5_B_IVB (dev_priv->info->display_mmio_offset + 0x61074)
> +
> +#define PIPE_CRC_CTL(pipe) _PIPE(pipe, _PIPE_CRC_CTL_A, _PIPE_CRC_CTL_B)
> +#define PIPE_CRC_RES_1_IVB(pipe) \
> + _PIPE(pipe, _PIPE_CRC_RES_1_A_IVB, _PIPE_CRC_RES_1_B_IVB)
> +#define PIPE_CRC_RES_2_IVB(pipe) \
> + _PIPE(pipe, _PIPE_CRC_RES_2_A_IVB, _PIPE_CRC_RES_2_B_IVB)
> +#define PIPE_CRC_RES_3_IVB(pipe) \
> + _PIPE(pipe, _PIPE_CRC_RES_3_A_IVB, _PIPE_CRC_RES_3_B_IVB)
> +#define PIPE_CRC_RES_4_IVB(pipe) \
> + _PIPE(pipe, _PIPE_CRC_RES_4_A_IVB, _PIPE_CRC_RES_4_B_IVB)
> +#define PIPE_CRC_RES_5_IVB(pipe) \
> + _PIPE(pipe, _PIPE_CRC_RES_5_A_IVB, _PIPE_CRC_RES_5_B_IVB)
> +
> /* Pipe A timing regs */
> #define _HTOTAL_A (dev_priv->info->display_mmio_offset + 0x60000)
> #define _HBLANK_A (dev_priv->info->display_mmio_offset + 0x60004)
> @@ -1857,7 +1892,6 @@
> #define _BCLRPAT_B (dev_priv->info->display_mmio_offset + 0x61020)
> #define _VSYNCSHIFT_B (dev_priv->info->display_mmio_offset + 0x61028)
>
> -
> #define HTOTAL(trans) _TRANSCODER(trans, _HTOTAL_A, _HTOTAL_B)
> #define HBLANK(trans) _TRANSCODER(trans, _HBLANK_A, _HBLANK_B)
> #define HSYNC(trans) _TRANSCODER(trans, _HSYNC_A, _HSYNC_B)
> --
> 1.8.3.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel OTC
next prev parent reply other threads:[~2013-10-16 10:29 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-15 17:55 Pipe CRCs v1 Damien Lespiau
2013-10-15 17:55 ` [PATCH 01/16] drm/i915: Expose latest 200 CRC value for pipe through debugfs Damien Lespiau
2013-10-16 10:29 ` Ville Syrjälä [this message]
2013-10-17 11:32 ` He, Shuang
2013-10-15 17:55 ` [PATCH 02/16] drm/i915: Add a control file for pipe CRCs Damien Lespiau
2013-10-15 17:55 ` [PATCH 03/16] drm/i915: Keep the CRC values into a circular buffer Damien Lespiau
2013-10-15 17:55 ` [PATCH 04/16] drm/i915: Sample the frame counter instead of a timestamp for CRCs Damien Lespiau
2013-10-16 13:29 ` Ville Syrjälä
2013-10-16 13:51 ` Daniel Vetter
2013-10-16 13:58 ` Ville Syrjälä
2013-10-16 14:04 ` Ville Syrjälä
2013-10-15 17:55 ` [PATCH 05/16] drm/i915: Make switching to the same CRC source a no-op Damien Lespiau
2013-10-15 17:55 ` [PATCH 06/16] drm/i915: Enforce going back to none before changing CRC source Damien Lespiau
2013-10-15 17:55 ` [PATCH 07/16] drm/i915: Empty the circular buffer when asked for a new source Damien Lespiau
2013-10-15 17:55 ` [PATCH 08/16] drm/i915: Dynamically allocate the CRC circular buffer Damien Lespiau
2013-10-15 17:55 ` [PATCH 09/16] drm/i915: Generalize the CRC command format for future work Damien Lespiau
2013-10-15 17:55 ` [PATCH 10/16] drm/i915: Rename i915_pipe_crc_ctl to i915_display_crc_ctl Damien Lespiau
2013-10-15 17:55 ` [PATCH 11/16] drm/i915: Warn if we receive an interrupt after freeing the buffer Damien Lespiau
2013-10-15 17:55 ` [PATCH 12/16] drm/i915: Add log messages when CRCs collection is started/stopped Damien Lespiau
2013-10-15 17:55 ` [PATCH 13/16] drm/i915: Move drm_add_fake_info_node() higher in the file Damien Lespiau
2013-10-15 17:55 ` [PATCH 14/16] drm/i915: Implement blocking read for pipe CRC files Damien Lespiau
2013-10-15 17:55 ` [PATCH 15/16] drm/i915: Only one open() allowed on pipe CRC result files Damien Lespiau
2013-10-15 17:55 ` [PATCH 16/16] drm/i915: Enable pipe CRCs Damien Lespiau
2013-10-16 10:02 ` Pipe CRCs v1 Daniel Vetter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131016102932.GV13047@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=damien.lespiau@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.