From: Jerome Glisse <jgli...@redhat.com>

This try to reset the dma engine when performing gpu reset. Hopefully
bringing back the gpu dma engine in sane state.

Signed-off-by: Jerome Glisse <jglisse at redhat.com>
---
 drivers/gpu/drm/radeon/evergreen.c  | 30 +++++++++++++++++++++---------
 drivers/gpu/drm/radeon/evergreend.h | 10 +++++++++-
 drivers/gpu/drm/radeon/ni.c         | 30 +++++++++++++++++++++---------
 drivers/gpu/drm/radeon/nid.h        |  2 +-
 drivers/gpu/drm/radeon/r600.c       | 28 ++++++++++++++++++++++------
 5 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c 
b/drivers/gpu/drm/radeon/evergreen.c
index 6dc9ee7..f92f6bb 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2309,19 +2309,19 @@ bool evergreen_gpu_is_lockup(struct radeon_device 
*rdev, struct radeon_ring *rin
 static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
 {
        struct evergreen_mc_save save;
-       u32 grbm_reset = 0;
+       u32 grbm_reset = 0, tmp;

        if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
                return 0;

        dev_info(rdev->dev, "GPU softreset \n");
-       dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS               = 0x%08X\n",
                RREG32(GRBM_STATUS));
-       dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS_SE0           = 0x%08X\n",
                RREG32(GRBM_STATUS_SE0));
-       dev_info(rdev->dev, "  GRBM_STATUS_SE1=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS_SE1           = 0x%08X\n",
                RREG32(GRBM_STATUS_SE1));
-       dev_info(rdev->dev, "  SRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  SRBM_STATUS               = 0x%08X\n",
                RREG32(SRBM_STATUS));
        dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X\n",
                RREG32(CP_STALLED_STAT1));
@@ -2337,9 +2337,21 @@ static int evergreen_gpu_soft_reset(struct radeon_device 
*rdev)
        if (evergreen_mc_wait_for_idle(rdev)) {
                dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
+
        /* Disable CP parsing/prefetching */
        WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);

+       /* Disable DMA */
+       tmp = RREG32(DMA_RB_CNTL);
+       tmp &= ~DMA_RB_ENABLE;
+       WREG32(DMA_RB_CNTL, tmp);
+
+       /* Reset dma */
+       WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
+       RREG32(SRBM_SOFT_RESET);
+       udelay(50);
+       WREG32(SRBM_SOFT_RESET, 0);
+
        /* reset all the gfx blocks */
        grbm_reset = (SOFT_RESET_CP |
                      SOFT_RESET_CB |
@@ -2362,13 +2374,13 @@ static int evergreen_gpu_soft_reset(struct 
radeon_device *rdev)
        (void)RREG32(GRBM_SOFT_RESET);
        /* Wait a little for things to settle down */
        udelay(50);
-       dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS               = 0x%08X\n",
                RREG32(GRBM_STATUS));
-       dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS_SE0           = 0x%08X\n",
                RREG32(GRBM_STATUS_SE0));
-       dev_info(rdev->dev, "  GRBM_STATUS_SE1=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS_SE1           = 0x%08X\n",
                RREG32(GRBM_STATUS_SE1));
-       dev_info(rdev->dev, "  SRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  SRBM_STATUS               = 0x%08X\n",
                RREG32(SRBM_STATUS));
        dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X\n",
                RREG32(CP_STALLED_STAT1));
diff --git a/drivers/gpu/drm/radeon/evergreend.h 
b/drivers/gpu/drm/radeon/evergreend.h
index f82f98a..5786a32 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -742,8 +742,9 @@
 #define                SOFT_RESET_ROM                          (1 << 14)
 #define                SOFT_RESET_SEM                          (1 << 15)
 #define                SOFT_RESET_VMC                          (1 << 17)
+#define                SOFT_RESET_DMA                          (1 << 20)
 #define                SOFT_RESET_TST                          (1 << 21)
-#define                SOFT_RESET_REGBB                        (1 << 22)
+#define                SOFT_RESET_REGBB                        (1 << 22)
 #define                SOFT_RESET_ORB                          (1 << 23)

 /* display watermarks */
@@ -2028,6 +2029,13 @@
 #define        CAYMAN_PACKET3_DEALLOC_STATE                    0x14

 /* DMA regs common on r6xx/r7xx/evergreen/ni */
+#define DMA_RB_CNTL                                       0xd000
+#       define DMA_RB_ENABLE                              (1 << 0)
+#       define DMA_RB_SIZE(x)                             ((x) << 1) /* log2 */
+#       define DMA_RB_SWAP_ENABLE                         (1 << 9) /* 8IN32 */
+#       define DMA_RPTR_WRITEBACK_ENABLE                  (1 << 12)
+#       define DMA_RPTR_WRITEBACK_SWAP_ENABLE             (1 << 13)  /* 8IN32 
*/
+#       define DMA_RPTR_WRITEBACK_TIMER(x)                ((x) << 16) /* log2 
*/
 #define DMA_STATUS_REG                                    0xd034

 #endif
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 6dae387..e67d5f6 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1309,19 +1309,19 @@ void cayman_dma_fini(struct radeon_device *rdev)
 static int cayman_gpu_soft_reset(struct radeon_device *rdev)
 {
        struct evergreen_mc_save save;
-       u32 grbm_reset = 0;
+       u32 grbm_reset = 0, tmp;

        if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
                return 0;

        dev_info(rdev->dev, "GPU softreset \n");
-       dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS               = 0x%08X\n",
                RREG32(GRBM_STATUS));
-       dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS_SE0           = 0x%08X\n",
                RREG32(GRBM_STATUS_SE0));
-       dev_info(rdev->dev, "  GRBM_STATUS_SE1=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS_SE1           = 0x%08X\n",
                RREG32(GRBM_STATUS_SE1));
-       dev_info(rdev->dev, "  SRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  SRBM_STATUS               = 0x%08X\n",
                RREG32(SRBM_STATUS));
        dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X\n",
                RREG32(CP_STALLED_STAT1));
@@ -1346,9 +1346,21 @@ static int cayman_gpu_soft_reset(struct radeon_device 
*rdev)
        if (evergreen_mc_wait_for_idle(rdev)) {
                dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
+
        /* Disable CP parsing/prefetching */
        WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);

+       /* Disable DMA */
+       tmp = RREG32(DMA_RB_CNTL);
+       tmp &= ~DMA_RB_ENABLE;
+       WREG32(DMA_RB_CNTL, tmp);
+
+       /* Reset dma */
+       WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
+       RREG32(SRBM_SOFT_RESET);
+       udelay(50);
+       WREG32(SRBM_SOFT_RESET, 0);
+
        /* reset all the gfx blocks */
        grbm_reset = (SOFT_RESET_CP |
                      SOFT_RESET_CB |
@@ -1373,13 +1385,13 @@ static int cayman_gpu_soft_reset(struct radeon_device 
*rdev)
        /* Wait a little for things to settle down */
        udelay(50);

-       dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS               = 0x%08X\n",
                RREG32(GRBM_STATUS));
-       dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS_SE0           = 0x%08X\n",
                RREG32(GRBM_STATUS_SE0));
-       dev_info(rdev->dev, "  GRBM_STATUS_SE1=0x%08X\n",
+       dev_info(rdev->dev, "  GRBM_STATUS_SE1           = 0x%08X\n",
                RREG32(GRBM_STATUS_SE1));
-       dev_info(rdev->dev, "  SRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  SRBM_STATUS               = 0x%08X\n",
                RREG32(SRBM_STATUS));
        dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X\n",
                RREG32(CP_STALLED_STAT1));
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 22a62c6..48e5022 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -65,7 +65,7 @@
 #define                SOFT_RESET_VMC                          (1 << 17)
 #define                SOFT_RESET_DMA                          (1 << 20)
 #define                SOFT_RESET_TST                          (1 << 21)
-#define                SOFT_RESET_REGBB                        (1 << 22)
+#define                SOFT_RESET_REGBB                        (1 << 22)
 #define                SOFT_RESET_ORB                          (1 << 23)

 #define VM_CONTEXT0_REQUEST_RESPONSE                   0x1470
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 4605551..95daff2 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1283,11 +1283,11 @@ static int r600_gpu_soft_reset(struct radeon_device 
*rdev)
                return 0;

        dev_info(rdev->dev, "GPU softreset \n");
-       dev_info(rdev->dev, "  R_008010_GRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  R_008010_GRBM_STATUS      = 0x%08X\n",
                RREG32(R_008010_GRBM_STATUS));
-       dev_info(rdev->dev, "  R_008014_GRBM_STATUS2=0x%08X\n",
+       dev_info(rdev->dev, "  R_008014_GRBM_STATUS2     = 0x%08X\n",
                RREG32(R_008014_GRBM_STATUS2));
-       dev_info(rdev->dev, "  R_000E50_SRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  R_000E50_SRBM_STATUS      = 0x%08X\n",
                RREG32(R_000E50_SRBM_STATUS));
        dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X\n",
                RREG32(CP_STALLED_STAT1));
@@ -1303,8 +1303,24 @@ static int r600_gpu_soft_reset(struct radeon_device 
*rdev)
        if (r600_mc_wait_for_idle(rdev)) {
                dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
+
        /* Disable CP parsing/prefetching */
        WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
+
+       /* Disable DMA */
+       tmp = RREG32(DMA_RB_CNTL);
+       tmp &= ~DMA_RB_ENABLE;
+       WREG32(DMA_RB_CNTL, tmp);
+
+       /* Reset dma */
+       if (rdev->family >= CHIP_RV770)
+               WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA);
+       else
+               WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
+       RREG32(SRBM_SOFT_RESET);
+       udelay(50);
+       WREG32(SRBM_SOFT_RESET, 0);
+
        /* Check if any of the rendering block is busy and reset it */
        if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
            (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
@@ -1336,11 +1352,11 @@ static int r600_gpu_soft_reset(struct radeon_device 
*rdev)
        WREG32(R_008020_GRBM_SOFT_RESET, 0);
        /* Wait a little for things to settle down */
        mdelay(1);
-       dev_info(rdev->dev, "  R_008010_GRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  R_008010_GRBM_STATUS      = 0x%08X\n",
                RREG32(R_008010_GRBM_STATUS));
-       dev_info(rdev->dev, "  R_008014_GRBM_STATUS2=0x%08X\n",
+       dev_info(rdev->dev, "  R_008014_GRBM_STATUS2     = 0x%08X\n",
                RREG32(R_008014_GRBM_STATUS2));
-       dev_info(rdev->dev, "  R_000E50_SRBM_STATUS=0x%08X\n",
+       dev_info(rdev->dev, "  R_000E50_SRBM_STATUS      = 0x%08X\n",
                RREG32(R_000E50_SRBM_STATUS));
        dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X\n",
                RREG32(CP_STALLED_STAT1));
-- 
1.7.11.7

Reply via email to