From patchwork Sun Apr 19 14:31:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 6238591 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 045AEBF4A6 for ; Sun, 19 Apr 2015 14:31:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E9482203E5 for ; Sun, 19 Apr 2015 14:31:56 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 028F92026D for ; Sun, 19 Apr 2015 14:31:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4E2776E2C5; Sun, 19 Apr 2015 07:31:54 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qk0-f176.google.com (mail-qk0-f176.google.com [209.85.220.176]) by gabe.freedesktop.org (Postfix) with ESMTP id EA47D6E2C3; Sun, 19 Apr 2015 07:31:52 -0700 (PDT) Received: by qkx62 with SMTP id 62so174262775qkx.0; Sun, 19 Apr 2015 07:31:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=he8WSj1HRCNsb2GmwR0d/5zVHmZZJVbMaBGQqKrzjDY=; b=v4BNRJvRKwXx04wQQiMvVrBCLnczwi6BX+vmw/d5ZDd1XC8ZwAmlPpmUvQ1SqnW1p0 WhCibjgMnnB4kHtZa61rxSMYHYKF8z4QwjCpAzb7TX3W0OmFHq1SvQstxxhXyR4/zBfg Iz2ZUqjE7zkkqRxoBx/AwMn2UkMSBvHqe9Zk6vQlMt/YwpIvkUGPWixy8xH1wS45VFuS Gm7OIF8h1nRuypxNEVEOn7S9DxsH8DTQAXg7W2GaCRVNMxV16ar1dfqYP/NlDzcHw5gt bqVJKmbWgXORf7L1caxM058tQCCYCNzxpPOw2nl5rVScguiAYAx6bAPjr6RYx9N0b0U/ bvhA== X-Received: by 10.140.17.50 with SMTP id 47mr12768013qgc.20.1429453912199; Sun, 19 Apr 2015 07:31:52 -0700 (PDT) Received: from localhost ([2601:6:2c00:943:5e51:4fff:fee8:58fa]) by mx.google.com with ESMTPSA id 33sm12292351qkv.22.2015.04.19.07.31.51 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 19 Apr 2015 07:31:51 -0700 (PDT) From: Rob Clark To: dri-devel@lists.freedesktop.org Subject: [PATCH] drm/msm/adreno: dump scratch regs and other info on hang Date: Sun, 19 Apr 2015 10:31:42 -0400 Message-Id: <1429453902-21447-1-git-send-email-robdclark@gmail.com> X-Mailer: git-send-email 2.1.0 Cc: linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_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-Virus-Scanned: ClamAV using ClamSMTP Dump a bit more info when the GPU hangs, without having hang_debug enabled (which dumps a *lot* of registers). Also dump the scratch registers, as they are useful for determining where in the cmdstream the GPU hung (and they seem always safe to read when GPU has hung). Note that the freedreno gallium driver emits increasing counter values to SCRATCH6 (to identify tile #) and SCRATCH7 (to identify draw #), so these two in particular can be used to "triangulate" where in the cmdstream the GPU hung. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 3 +++ drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 3 ++- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 21 +++++++++++++++++++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index b66c53b..0f0c456 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -295,9 +295,12 @@ static int a3xx_hw_init(struct msm_gpu *gpu) static void a3xx_recover(struct msm_gpu *gpu) { + adreno_dump_info(gpu); + /* dump registers before resetting gpu, if enabled: */ if (hang_debug) a3xx_dump(gpu); + gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 1); gpu_read(gpu, REG_A3XX_RBBM_SW_RESET_CMD); gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 0); diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 5997517..2dc98518 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -268,6 +268,8 @@ static int a4xx_hw_init(struct msm_gpu *gpu) static void a4xx_recover(struct msm_gpu *gpu) { + adreno_dump_info(gpu); + /* dump registers before resetting gpu, if enabled: */ if (hang_debug) a4xx_dump(gpu); @@ -505,7 +507,6 @@ static const unsigned int a4xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { static void a4xx_dump(struct msm_gpu *gpu) { - adreno_dump(gpu); printk("status: %08x\n", gpu_read(gpu, REG_A4XX_RBBM_STATUS)); adreno_dump(gpu); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 94a5bee..80c4b6c 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -249,8 +249,13 @@ void adreno_show(struct msm_gpu *gpu, struct seq_file *m) } #endif -/* would be nice to not have to duplicate the _show() stuff with printk(): */ -void adreno_dump(struct msm_gpu *gpu) +/* Dump common gpu status and scratch registers on any hang, to make + * the hangcheck logs more useful. The scratch registers seem always + * safe to read when GPU has hung (unlike some other regs, depending + * on how the GPU hung), and they are useful to match up to cmdstream + * dumps when debugging hangs: + */ +void adreno_dump_info(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); int i; @@ -266,6 +271,18 @@ void adreno_dump(struct msm_gpu *gpu) printk("wptr: %d\n", adreno_gpu->memptrs->wptr); printk("rb wptr: %d\n", get_wptr(gpu->rb)); + for (i = 0; i < 8; i++) { + printk("CP_SCRATCH_REG%d: %u\n", i, + gpu_read(gpu, REG_AXXX_CP_SCRATCH_REG0 + i)); + } +} + +/* would be nice to not have to duplicate the _show() stuff with printk(): */ +void adreno_dump(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + int i; + /* dump these out in a form that can be parsed by demsm: */ printk("IO:region %s 00000000 00020000\n", gpu->name); for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) { diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index a0cc309..2b6b57b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -233,6 +233,7 @@ void adreno_idle(struct msm_gpu *gpu); #ifdef CONFIG_DEBUG_FS void adreno_show(struct msm_gpu *gpu, struct seq_file *m); #endif +void adreno_dump_info(struct msm_gpu *gpu); void adreno_dump(struct msm_gpu *gpu); void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords);