From patchwork Fri Mar 18 15:58:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jerome Glisse X-Patchwork-Id: 8621531 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 91B129F44D for ; Fri, 18 Mar 2016 15:59:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4C12A20386 for ; Fri, 18 Mar 2016 15:59:25 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id CFF262038F for ; Fri, 18 Mar 2016 15:59:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 340366EC0D; Fri, 18 Mar 2016 15:59:18 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTPS id 777436EC0D for ; Fri, 18 Mar 2016 15:59:15 +0000 (UTC) Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 2A21380517; Fri, 18 Mar 2016 15:59:15 +0000 (UTC) Received: from localhost.localdomain.com (vpn-60-213.rdu2.redhat.com [10.10.60.213]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u2IFwjEs028500; Fri, 18 Mar 2016 11:59:12 -0400 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= To: dri-devel@lists.freedesktop.org Subject: [PATCH 13/14] drm/radeon: allow to force hard GPU reset. Date: Fri, 18 Mar 2016 16:58:38 +0100 Message-Id: <1458316719-30104-14-git-send-email-jglisse@redhat.com> In-Reply-To: <1458316719-30104-1-git-send-email-jglisse@redhat.com> References: <1458316719-30104-1-git-send-email-jglisse@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 Cc: Alex Deucher , =?UTF-8?q?J=C3=A9rome=20Glisse?= , =?UTF-8?q?Christian=20K=C3=B6nig?= 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: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.2 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-Virus-Scanned: ClamAV using ClamSMTP From: Jérome Glisse In some cases, like when freezing for hibernation, we need to be able to force hard reset even if no engine are stuck. This patch add a bool option to current asic reset callback to allow to force hard reset on asic that supports it. Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König --- drivers/gpu/drm/radeon/cik.c | 8 +++++++- drivers/gpu/drm/radeon/evergreen.c | 7 ++++++- drivers/gpu/drm/radeon/ni.c | 7 ++++++- drivers/gpu/drm/radeon/r100.c | 2 +- drivers/gpu/drm/radeon/r300.c | 2 +- drivers/gpu/drm/radeon/r600.c | 7 ++++++- drivers/gpu/drm/radeon/radeon.h | 4 ++-- drivers/gpu/drm/radeon/radeon_asic.h | 16 ++++++++-------- drivers/gpu/drm/radeon/rs600.c | 2 +- drivers/gpu/drm/radeon/si.c | 7 ++++++- 10 files changed, 44 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index b5bc9cf..7ee9304 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -5620,15 +5620,21 @@ static void cik_gpu_pci_config_reset(struct radeon_device *rdev) * cik_asic_reset - soft reset GPU * * @rdev: radeon_device pointer + * @hard: force hard reset * * Look up which blocks are hung and attempt * to reset them. * Returns 0 for success. */ -int cik_asic_reset(struct radeon_device *rdev) +int cik_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + cik_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = cik_gpu_check_soft_reset(rdev); if (reset_mask) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index cc0cf9a..e483b07 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3984,10 +3984,15 @@ void evergreen_gpu_pci_config_reset(struct radeon_device *rdev) } } -int evergreen_asic_reset(struct radeon_device *rdev) +int evergreen_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + evergreen_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = evergreen_gpu_check_soft_reset(rdev); if (reset_mask) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index ec0aac8..4a3d7ca 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1959,10 +1959,15 @@ static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) evergreen_print_gpu_status_regs(rdev); } -int cayman_asic_reset(struct radeon_device *rdev) +int cayman_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + evergreen_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = cayman_gpu_check_soft_reset(rdev); if (reset_mask) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 6e478a2..bbdf15f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2555,7 +2555,7 @@ void r100_bm_disable(struct radeon_device *rdev) mdelay(1); } -int r100_asic_reset(struct radeon_device *rdev) +int r100_asic_reset(struct radeon_device *rdev, bool hard) { struct r100_mc_save save; u32 status, tmp; diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 718b12b..7e417d8 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -410,7 +410,7 @@ static void r300_gpu_init(struct radeon_device *rdev) rdev->num_gb_pipes, rdev->num_z_pipes); } -int r300_asic_reset(struct radeon_device *rdev) +int r300_asic_reset(struct radeon_device *rdev, bool hard) { struct r100_mc_save save; u32 status, tmp; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 24fa982..d7896bb 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1871,10 +1871,15 @@ static void r600_gpu_pci_config_reset(struct radeon_device *rdev) } } -int r600_asic_reset(struct radeon_device *rdev) +int r600_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + r600_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = r600_gpu_check_soft_reset(rdev); if (reset_mask) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 91828ec..1ededd1 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1854,7 +1854,7 @@ struct radeon_asic { int (*resume)(struct radeon_device *rdev); int (*suspend)(struct radeon_device *rdev); void (*vga_set_state)(struct radeon_device *rdev, bool state); - int (*asic_reset)(struct radeon_device *rdev); + int (*asic_reset)(struct radeon_device *rdev, bool hard); /* Flush the HDP cache via MMIO */ void (*mmio_hdp_flush)(struct radeon_device *rdev); /* check if 3D engine is idle */ @@ -2720,7 +2720,7 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) #define radeon_cs_parse(rdev, r, p) (rdev)->asic->ring[(r)]->cs_parse((p)) #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) -#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) +#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev), false) #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) #define radeon_gart_get_page_entry(a, f) (rdev)->asic->gart.get_page_entry((a), (f)) #define radeon_gart_set_page(rdev, i, e) (rdev)->asic->gart.set_page((rdev), (i), (e)) diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index e0aa332..7675dfa 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -64,7 +64,7 @@ int r100_suspend(struct radeon_device *rdev); int r100_resume(struct radeon_device *rdev); void r100_vga_set_state(struct radeon_device *rdev, bool state); bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int r100_asic_reset(struct radeon_device *rdev); +int r100_asic_reset(struct radeon_device *rdev, bool hard); u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); void r100_pci_gart_tlb_flush(struct radeon_device *rdev); uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags); @@ -167,7 +167,7 @@ extern int r300_init(struct radeon_device *rdev); extern void r300_fini(struct radeon_device *rdev); extern int r300_suspend(struct radeon_device *rdev); extern int r300_resume(struct radeon_device *rdev); -extern int r300_asic_reset(struct radeon_device *rdev); +extern int r300_asic_reset(struct radeon_device *rdev, bool hard); extern void r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); extern void r300_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence); @@ -225,7 +225,7 @@ extern int rs400_mc_wait_for_idle(struct radeon_device *rdev); /* * rs600. */ -extern int rs600_asic_reset(struct radeon_device *rdev); +extern int rs600_asic_reset(struct radeon_device *rdev, bool hard); extern int rs600_init(struct radeon_device *rdev); extern void rs600_fini(struct radeon_device *rdev); extern int rs600_suspend(struct radeon_device *rdev); @@ -334,7 +334,7 @@ bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev, void r600_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); bool r600_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int r600_asic_reset(struct radeon_device *rdev); +int r600_asic_reset(struct radeon_device *rdev, bool hard); int r600_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, uint32_t offset, uint32_t obj_size); @@ -513,7 +513,7 @@ int evergreen_suspend(struct radeon_device *rdev); int evergreen_resume(struct radeon_device *rdev); bool evergreen_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); bool evergreen_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int evergreen_asic_reset(struct radeon_device *rdev); +int evergreen_asic_reset(struct radeon_device *rdev, bool hard); void evergreen_bandwidth_update(struct radeon_device *rdev); void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); void evergreen_hpd_init(struct radeon_device *rdev); @@ -606,7 +606,7 @@ int cayman_init(struct radeon_device *rdev); void cayman_fini(struct radeon_device *rdev); int cayman_suspend(struct radeon_device *rdev); int cayman_resume(struct radeon_device *rdev); -int cayman_asic_reset(struct radeon_device *rdev); +int cayman_asic_reset(struct radeon_device *rdev, bool hard); void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int cayman_vm_init(struct radeon_device *rdev); void cayman_vm_fini(struct radeon_device *rdev); @@ -712,7 +712,7 @@ int si_suspend(struct radeon_device *rdev); int si_resume(struct radeon_device *rdev); bool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); bool si_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int si_asic_reset(struct radeon_device *rdev); +int si_asic_reset(struct radeon_device *rdev, bool hard); void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int si_irq_set(struct radeon_device *rdev); int si_irq_process(struct radeon_device *rdev); @@ -817,7 +817,7 @@ void cik_fini(struct radeon_device *rdev); int cik_suspend(struct radeon_device *rdev); int cik_resume(struct radeon_device *rdev); bool cik_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int cik_asic_reset(struct radeon_device *rdev); +int cik_asic_reset(struct radeon_device *rdev, bool hard); void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 6244f4e..3c250c4 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -444,7 +444,7 @@ void rs600_hpd_fini(struct radeon_device *rdev) radeon_irq_kms_disable_hpd(rdev, disable); } -int rs600_asic_reset(struct radeon_device *rdev) +int rs600_asic_reset(struct radeon_device *rdev, bool hard) { struct rv515_mc_save save; u32 status, tmp; diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 7ed2a03..f0ad026 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -4081,10 +4081,15 @@ static void si_gpu_pci_config_reset(struct radeon_device *rdev) } } -int si_asic_reset(struct radeon_device *rdev) +int si_asic_reset(struct radeon_device *rdev, bool hard) { u32 reset_mask; + if (hard) { + si_gpu_pci_config_reset(rdev); + return 0; + } + reset_mask = si_gpu_check_soft_reset(rdev); if (reset_mask)