Commit 71fe2899 authored by Jérome Glisse's avatar Jérome Glisse Committed by Alex Deucher

drm/radeon: allow to force hard GPU reset.

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: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarJérôme Glisse <jglisse@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fabb5935
...@@ -5261,15 +5261,21 @@ static void cik_gpu_pci_config_reset(struct radeon_device *rdev) ...@@ -5261,15 +5261,21 @@ static void cik_gpu_pci_config_reset(struct radeon_device *rdev)
* cik_asic_reset - soft reset GPU * cik_asic_reset - soft reset GPU
* *
* @rdev: radeon_device pointer * @rdev: radeon_device pointer
* @hard: force hard reset
* *
* Look up which blocks are hung and attempt * Look up which blocks are hung and attempt
* to reset them. * to reset them.
* Returns 0 for success. * 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; u32 reset_mask;
if (hard) {
cik_gpu_pci_config_reset(rdev);
return 0;
}
reset_mask = cik_gpu_check_soft_reset(rdev); reset_mask = cik_gpu_check_soft_reset(rdev);
if (reset_mask) if (reset_mask)
......
...@@ -3984,10 +3984,15 @@ void evergreen_gpu_pci_config_reset(struct radeon_device *rdev) ...@@ -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; u32 reset_mask;
if (hard) {
evergreen_gpu_pci_config_reset(rdev);
return 0;
}
reset_mask = evergreen_gpu_check_soft_reset(rdev); reset_mask = evergreen_gpu_check_soft_reset(rdev);
if (reset_mask) if (reset_mask)
......
...@@ -1959,10 +1959,15 @@ static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) ...@@ -1959,10 +1959,15 @@ static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
evergreen_print_gpu_status_regs(rdev); 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; u32 reset_mask;
if (hard) {
evergreen_gpu_pci_config_reset(rdev);
return 0;
}
reset_mask = cayman_gpu_check_soft_reset(rdev); reset_mask = cayman_gpu_check_soft_reset(rdev);
if (reset_mask) if (reset_mask)
......
...@@ -2555,7 +2555,7 @@ void r100_bm_disable(struct radeon_device *rdev) ...@@ -2555,7 +2555,7 @@ void r100_bm_disable(struct radeon_device *rdev)
mdelay(1); 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; struct r100_mc_save save;
u32 status, tmp; u32 status, tmp;
......
...@@ -410,7 +410,7 @@ static void r300_gpu_init(struct radeon_device *rdev) ...@@ -410,7 +410,7 @@ static void r300_gpu_init(struct radeon_device *rdev)
rdev->num_gb_pipes, rdev->num_z_pipes); 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; struct r100_mc_save save;
u32 status, tmp; u32 status, tmp;
......
...@@ -1871,10 +1871,15 @@ static void r600_gpu_pci_config_reset(struct radeon_device *rdev) ...@@ -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; u32 reset_mask;
if (hard) {
r600_gpu_pci_config_reset(rdev);
return 0;
}
reset_mask = r600_gpu_check_soft_reset(rdev); reset_mask = r600_gpu_check_soft_reset(rdev);
if (reset_mask) if (reset_mask)
......
...@@ -1854,7 +1854,7 @@ struct radeon_asic { ...@@ -1854,7 +1854,7 @@ struct radeon_asic {
int (*resume)(struct radeon_device *rdev); int (*resume)(struct radeon_device *rdev);
int (*suspend)(struct radeon_device *rdev); int (*suspend)(struct radeon_device *rdev);
void (*vga_set_state)(struct radeon_device *rdev, bool state); 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 */ /* Flush the HDP cache via MMIO */
void (*mmio_hdp_flush)(struct radeon_device *rdev); void (*mmio_hdp_flush)(struct radeon_device *rdev);
/* check if 3D engine is idle */ /* check if 3D engine is idle */
...@@ -2720,7 +2720,7 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) ...@@ -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_suspend(rdev) (rdev)->asic->suspend((rdev))
#define radeon_cs_parse(rdev, r, p) (rdev)->asic->ring[(r)]->cs_parse((p)) #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_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_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_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)) #define radeon_gart_set_page(rdev, i, e) (rdev)->asic->gart.set_page((rdev), (i), (e))
......
...@@ -64,7 +64,7 @@ int r100_suspend(struct radeon_device *rdev); ...@@ -64,7 +64,7 @@ int r100_suspend(struct radeon_device *rdev);
int r100_resume(struct radeon_device *rdev); int r100_resume(struct radeon_device *rdev);
void r100_vga_set_state(struct radeon_device *rdev, bool state); void r100_vga_set_state(struct radeon_device *rdev, bool state);
bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); 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); u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
void r100_pci_gart_tlb_flush(struct radeon_device *rdev); void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags); 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); ...@@ -167,7 +167,7 @@ extern int r300_init(struct radeon_device *rdev);
extern void r300_fini(struct radeon_device *rdev); extern void r300_fini(struct radeon_device *rdev);
extern int r300_suspend(struct radeon_device *rdev); extern int r300_suspend(struct radeon_device *rdev);
extern int r300_resume(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_ring_start(struct radeon_device *rdev, struct radeon_ring *ring);
extern void r300_fence_ring_emit(struct radeon_device *rdev, extern void r300_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence); struct radeon_fence *fence);
...@@ -225,7 +225,7 @@ extern int rs400_mc_wait_for_idle(struct radeon_device *rdev); ...@@ -225,7 +225,7 @@ extern int rs400_mc_wait_for_idle(struct radeon_device *rdev);
/* /*
* rs600. * 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 int rs600_init(struct radeon_device *rdev);
extern void rs600_fini(struct radeon_device *rdev); extern void rs600_fini(struct radeon_device *rdev);
extern int rs600_suspend(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, ...@@ -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); 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_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
bool r600_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); 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, int r600_set_surface_reg(struct radeon_device *rdev, int reg,
uint32_t tiling_flags, uint32_t pitch, uint32_t tiling_flags, uint32_t pitch,
uint32_t offset, uint32_t obj_size); uint32_t offset, uint32_t obj_size);
...@@ -513,7 +513,7 @@ int evergreen_suspend(struct radeon_device *rdev); ...@@ -513,7 +513,7 @@ int evergreen_suspend(struct radeon_device *rdev);
int evergreen_resume(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_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp);
bool evergreen_dma_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_bandwidth_update(struct radeon_device *rdev);
void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
void evergreen_hpd_init(struct radeon_device *rdev); void evergreen_hpd_init(struct radeon_device *rdev);
...@@ -606,7 +606,7 @@ int cayman_init(struct radeon_device *rdev); ...@@ -606,7 +606,7 @@ int cayman_init(struct radeon_device *rdev);
void cayman_fini(struct radeon_device *rdev); void cayman_fini(struct radeon_device *rdev);
int cayman_suspend(struct radeon_device *rdev); int cayman_suspend(struct radeon_device *rdev);
int cayman_resume(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); void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
int cayman_vm_init(struct radeon_device *rdev); int cayman_vm_init(struct radeon_device *rdev);
void cayman_vm_fini(struct radeon_device *rdev); void cayman_vm_fini(struct radeon_device *rdev);
...@@ -712,7 +712,7 @@ int si_suspend(struct radeon_device *rdev); ...@@ -712,7 +712,7 @@ int si_suspend(struct radeon_device *rdev);
int si_resume(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_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp);
bool si_dma_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); void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
int si_irq_set(struct radeon_device *rdev); int si_irq_set(struct radeon_device *rdev);
int si_irq_process(struct radeon_device *rdev); int si_irq_process(struct radeon_device *rdev);
...@@ -817,7 +817,7 @@ void cik_fini(struct radeon_device *rdev); ...@@ -817,7 +817,7 @@ void cik_fini(struct radeon_device *rdev);
int cik_suspend(struct radeon_device *rdev); int cik_suspend(struct radeon_device *rdev);
int cik_resume(struct radeon_device *rdev); int cik_resume(struct radeon_device *rdev);
bool cik_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); 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); 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_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
......
...@@ -444,7 +444,7 @@ void rs600_hpd_fini(struct radeon_device *rdev) ...@@ -444,7 +444,7 @@ void rs600_hpd_fini(struct radeon_device *rdev)
radeon_irq_kms_disable_hpd(rdev, disable); 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; struct rv515_mc_save save;
u32 status, tmp; u32 status, tmp;
......
...@@ -4034,10 +4034,15 @@ static void si_gpu_pci_config_reset(struct radeon_device *rdev) ...@@ -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; u32 reset_mask;
if (hard) {
si_gpu_pci_config_reset(rdev);
return 0;
}
reset_mask = si_gpu_check_soft_reset(rdev); reset_mask = si_gpu_check_soft_reset(rdev);
if (reset_mask) if (reset_mask)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment