From patchwork Fri Jul 25 03:27:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dheeraj Jamwal X-Patchwork-Id: 4708391 Return-Path: X-Original-To: patchwork-ltsi-dev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8F7DF9F375 for ; Mon, 11 Aug 2014 18:43:16 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 74F3820122 for ; Mon, 11 Aug 2014 18:43:15 +0000 (UTC) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 566492011E for ; Mon, 11 Aug 2014 18:43:14 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id BBA94B0D; Mon, 11 Aug 2014 18:42:52 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 5904999F for ; Fri, 25 Jul 2014 03:25:38 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 870F01FD46 for ; Fri, 25 Jul 2014 03:25:37 +0000 (UTC) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 24 Jul 2014 20:18:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,727,1400050800"; d="scan'208";a="566985246" Received: from ubuntu-desktop.png.intel.com ([10.221.122.23]) by fmsmga001.fm.intel.com with ESMTP; 24 Jul 2014 20:25:19 -0700 From: Dheeraj Jamwal To: ltsi-dev@lists.linuxfoundation.org Date: Fri, 25 Jul 2014 11:27:52 +0800 Message-Id: <1406258918-18934-5-git-send-email-dheerajx.s.jamwal@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1406258918-18934-1-git-send-email-dheerajx.s.jamwal@intel.com> References: <1406258918-18934-1-git-send-email-dheerajx.s.jamwal@intel.com> X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Mailman-Approved-At: Mon, 11 Aug 2014 18:42:51 +0000 Subject: [LTSI-dev] [PATCH 04/50] drm/i915: Expose latest 200 CRC value for pipe through debugfs X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org X-Virus-Scanned: ClamAV using ClamSMTP From: Shuang He 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 Signed-off-by: Damien Lespiau [danvet: Fix intermediate compile file reported by Wu Fengguang's kernel builder.] Signed-off-by: Daniel Vetter (cherry picked from commit 8bf1e9f1d2aa1fafd2b262683a13cbb7f934c6d0) Signed-off-by: Dheeraj Jamwal --- drivers/gpu/drm/i915/i915_debugfs.c | 33 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 15 +++++++++++++++ drivers/gpu/drm/i915/i915_irq.c | 35 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 36 ++++++++++++++++++++++++++++++++++- 4 files changed, 118 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 32a3be3..6ec44c2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1217,6 +1217,17 @@ 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]; + atomic_t slot; +}; + typedef struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1421,6 +1432,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 } 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; + 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 b334751..e4775dd 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)