提交 64c56e8c 编写于 作者: J Jerome Glisse 提交者: Alex Deucher

drm/radeon: reset dma engine on gpu reset (v2)

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

v2: agd5f: fix dma reset on cayman/TN, add support for SI
Signed-off-by: NJerome Glisse <jglisse@redhat.com>
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
上级 eaaa6983
...@@ -2309,19 +2309,19 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin ...@@ -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) static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
{ {
struct evergreen_mc_save save; struct evergreen_mc_save save;
u32 grbm_reset = 0; u32 grbm_reset = 0, tmp;
if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
return 0; return 0;
dev_info(rdev->dev, "GPU softreset \n"); 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)); 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)); 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)); 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)); RREG32(SRBM_STATUS));
dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
RREG32(CP_STALLED_STAT1)); RREG32(CP_STALLED_STAT1));
...@@ -2337,9 +2337,21 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) ...@@ -2337,9 +2337,21 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
if (evergreen_mc_wait_for_idle(rdev)) { if (evergreen_mc_wait_for_idle(rdev)) {
dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
} }
/* Disable CP parsing/prefetching */ /* Disable CP parsing/prefetching */
WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); 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 */ /* reset all the gfx blocks */
grbm_reset = (SOFT_RESET_CP | grbm_reset = (SOFT_RESET_CP |
SOFT_RESET_CB | SOFT_RESET_CB |
...@@ -2362,13 +2374,13 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) ...@@ -2362,13 +2374,13 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
(void)RREG32(GRBM_SOFT_RESET); (void)RREG32(GRBM_SOFT_RESET);
/* Wait a little for things to settle down */ /* Wait a little for things to settle down */
udelay(50); udelay(50);
dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n",
RREG32(GRBM_STATUS)); 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)); 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)); 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)); RREG32(SRBM_STATUS));
dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
RREG32(CP_STALLED_STAT1)); RREG32(CP_STALLED_STAT1));
......
...@@ -742,6 +742,7 @@ ...@@ -742,6 +742,7 @@
#define SOFT_RESET_ROM (1 << 14) #define SOFT_RESET_ROM (1 << 14)
#define SOFT_RESET_SEM (1 << 15) #define SOFT_RESET_SEM (1 << 15)
#define SOFT_RESET_VMC (1 << 17) #define SOFT_RESET_VMC (1 << 17)
#define SOFT_RESET_DMA (1 << 20)
#define SOFT_RESET_TST (1 << 21) #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 SOFT_RESET_ORB (1 << 23)
...@@ -2028,6 +2029,13 @@ ...@@ -2028,6 +2029,13 @@
#define CAYMAN_PACKET3_DEALLOC_STATE 0x14 #define CAYMAN_PACKET3_DEALLOC_STATE 0x14
/* DMA regs common on r6xx/r7xx/evergreen/ni */ /* 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 #define DMA_STATUS_REG 0xd034
#endif #endif
...@@ -1309,19 +1309,19 @@ void cayman_dma_fini(struct radeon_device *rdev) ...@@ -1309,19 +1309,19 @@ void cayman_dma_fini(struct radeon_device *rdev)
static int cayman_gpu_soft_reset(struct radeon_device *rdev) static int cayman_gpu_soft_reset(struct radeon_device *rdev)
{ {
struct evergreen_mc_save save; struct evergreen_mc_save save;
u32 grbm_reset = 0; u32 grbm_reset = 0, tmp;
if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
return 0; return 0;
dev_info(rdev->dev, "GPU softreset \n"); 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)); 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)); 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)); 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)); RREG32(SRBM_STATUS));
dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
RREG32(CP_STALLED_STAT1)); RREG32(CP_STALLED_STAT1));
...@@ -1346,9 +1346,26 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) ...@@ -1346,9 +1346,26 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev)
if (evergreen_mc_wait_for_idle(rdev)) { if (evergreen_mc_wait_for_idle(rdev)) {
dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
} }
/* Disable CP parsing/prefetching */ /* Disable CP parsing/prefetching */
WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
/* dma0 */
tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
tmp &= ~DMA_RB_ENABLE;
WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
/* dma1 */
tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
tmp &= ~DMA_RB_ENABLE;
WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
/* Reset dma */
WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
RREG32(SRBM_SOFT_RESET);
udelay(50);
WREG32(SRBM_SOFT_RESET, 0);
/* reset all the gfx blocks */ /* reset all the gfx blocks */
grbm_reset = (SOFT_RESET_CP | grbm_reset = (SOFT_RESET_CP |
SOFT_RESET_CB | SOFT_RESET_CB |
...@@ -1373,13 +1390,13 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) ...@@ -1373,13 +1390,13 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev)
/* Wait a little for things to settle down */ /* Wait a little for things to settle down */
udelay(50); udelay(50);
dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n",
RREG32(GRBM_STATUS)); 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)); 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)); 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)); RREG32(SRBM_STATUS));
dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
RREG32(CP_STALLED_STAT1)); RREG32(CP_STALLED_STAT1));
......
...@@ -1283,11 +1283,11 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) ...@@ -1283,11 +1283,11 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev)
return 0; return 0;
dev_info(rdev->dev, "GPU softreset \n"); 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)); 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)); 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)); RREG32(R_000E50_SRBM_STATUS));
dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
RREG32(CP_STALLED_STAT1)); RREG32(CP_STALLED_STAT1));
...@@ -1303,8 +1303,24 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) ...@@ -1303,8 +1303,24 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev)
if (r600_mc_wait_for_idle(rdev)) { if (r600_mc_wait_for_idle(rdev)) {
dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
} }
/* Disable CP parsing/prefetching */ /* Disable CP parsing/prefetching */
WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); 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 */ /* Check if any of the rendering block is busy and reset it */
if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
(RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
...@@ -1336,11 +1352,11 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) ...@@ -1336,11 +1352,11 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev)
WREG32(R_008020_GRBM_SOFT_RESET, 0); WREG32(R_008020_GRBM_SOFT_RESET, 0);
/* Wait a little for things to settle down */ /* Wait a little for things to settle down */
mdelay(1); 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)); 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)); 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)); RREG32(R_000E50_SRBM_STATUS));
dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
RREG32(CP_STALLED_STAT1)); RREG32(CP_STALLED_STAT1));
......
...@@ -2129,7 +2129,7 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) ...@@ -2129,7 +2129,7 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
static int si_gpu_soft_reset(struct radeon_device *rdev) static int si_gpu_soft_reset(struct radeon_device *rdev)
{ {
struct evergreen_mc_save save; struct evergreen_mc_save save;
u32 grbm_reset = 0; u32 grbm_reset = 0, tmp;
if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
return 0; return 0;
...@@ -2159,6 +2159,22 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) ...@@ -2159,6 +2159,22 @@ static int si_gpu_soft_reset(struct radeon_device *rdev)
/* Disable CP parsing/prefetching */ /* Disable CP parsing/prefetching */
WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
/* dma0 */
tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
tmp &= ~DMA_RB_ENABLE;
WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
/* dma1 */
tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
tmp &= ~DMA_RB_ENABLE;
WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
/* Reset dma */
WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
RREG32(SRBM_SOFT_RESET);
udelay(50);
WREG32(SRBM_SOFT_RESET, 0);
/* reset all the gfx blocks */ /* reset all the gfx blocks */
grbm_reset = (SOFT_RESET_CP | grbm_reset = (SOFT_RESET_CP |
SOFT_RESET_CB | SOFT_RESET_CB |
......
...@@ -62,6 +62,22 @@ ...@@ -62,6 +62,22 @@
#define SRBM_STATUS 0xE50 #define SRBM_STATUS 0xE50
#define SRBM_SOFT_RESET 0x0E60
#define SOFT_RESET_BIF (1 << 1)
#define SOFT_RESET_DC (1 << 5)
#define SOFT_RESET_DMA1 (1 << 6)
#define SOFT_RESET_GRBM (1 << 8)
#define SOFT_RESET_HDP (1 << 9)
#define SOFT_RESET_IH (1 << 10)
#define SOFT_RESET_MC (1 << 11)
#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_ORB (1 << 23)
#define CC_SYS_RB_BACKEND_DISABLE 0xe80 #define CC_SYS_RB_BACKEND_DISABLE 0xe80
#define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84 #define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册