drm/radeon: allow to force hard GPU reset.
authorJérome Glisse <jglisse@redhat.com>
Fri, 18 Mar 2016 15:58:38 +0000 (16:58 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 2 May 2016 17:08:54 +0000 (13:08 -0400)
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 <christian.koenig@amd.com>
Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/si.c

index dd1a7b206a486e4323921d5bcff740cac42161b7..ba192a35c60771cbcd9461b6d127379ca17295b2 100644 (file)
@@ -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)
index cc0cf9addf656dfb2a010c9999ec272520ca0516..e483b0752866a6541d6809bf74bf17771e6c1379 100644 (file)
@@ -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)
index ec0aac8d455fba4da910519ac251a7d7bf589e11..4a3d7cab83f7a554aea1a21b309815bc83f1900c 100644 (file)
@@ -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)
index 6e478a248628bf62904befd7cfcfea5075081d08..bbdf15fc915356e9aee9a9afd6b10b7292d98571 100644 (file)
@@ -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;
index 718b12b03b570de5687af46d97ef123dc130c961..7e417d8dc733157c1c3c397246619334c1cc3cc9 100644 (file)
@@ -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;
index 24fa982522ee891f3d970203a5686d2531122da5..d7896bb553a9c0eb123b9f507a56dc7d9da9804c 100644 (file)
@@ -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)
index 91828ecf39cf4a5bc35c14383c283b1bf68d44cb..1ededd1a86f53b89c9e0b52f018172c09d746181 100644 (file)
@@ -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))
index e0aa33262eac62126e73984292e2658b310305ba..7675dfaaa005e9b7ebcd13ce5a136a0cbd69a1da 100644 (file)
@@ -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);
index 6244f4e44e9a541d15d5a76ac36beff8822c3145..3c250c445bdb66376c63e9ef53065091b7c02f86 100644 (file)
@@ -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;
index 9ef41188b814a356d2a41f982032f27dbc482e3b..7afe825ee561aa4b32265e1703651384d687309d 100644 (file)
@@ -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)