From 71fe289970430fca85c7c8da5a829e65764e081b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9rome=20Glisse?= Date: Fri, 18 Mar 2016 16:58:38 +0100 Subject: [PATCH] drm/radeon: allow to force hard GPU reset. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. Reviewed-by: Christian König Signed-off-by: Jérôme Glisse Cc: Alex Deucher Cc: Christian König Signed-off-by: Alex Deucher --- 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 dd1a7b206a48..ba192a35c607 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -5261,15 +5261,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 cc0cf9addf65..e483b0752866 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 ec0aac8d455f..4a3d7cab83f7 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 6e478a248628..bbdf15fc9153 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 718b12b03b57..7e417d8dc733 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 24fa982522ee..d7896bb553a9 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 91828ecf39cf..1ededd1a86f5 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 e0aa33262eac..7675dfaaa005 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 6244f4e44e9a..3c250c445bdb 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 9ef41188b814..7afe825ee561 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -4034,10 +4034,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) -- 2.30.2