diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 6dc9ee78f4a8abe8d312429b4e3492a9c37bb968..f92f6bb18872c6c48bc3f2d8b3dc189a381ba5db 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 f82f98a11a7610091ede6a0a8f5f2cdca8ece8ab..5786a32e7bdae26ac1de91f51b53202c5bdc0069 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 6dae3878e39716592b08b32b5731d4298d6784ac..8a9a75d1cb00f810277dcec248925b8134c5b1e6 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,26 @@ 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); + /* 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 */ grbm_reset = (SOFT_RESET_CP | SOFT_RESET_CB | @@ -1373,13 +1390,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 22a62c673fec3887447f3a48a09cb0671a8386d4..48e5022ee921d33081f86de17d8ab6b0520ea037 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 252067bba2d91bbdeb162dd168520f415b59db4c..721b5afd792a569f4d16e174d06cb030b6314e36 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)); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 74d38452c5c18235903d0c9bf3acf085be9e8174..4bf17334927a722e8e38b10f5cbfc927dec8dc79 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -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) { struct evergreen_mc_save save; - u32 grbm_reset = 0; + u32 grbm_reset = 0, tmp; if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) return 0; @@ -2159,6 +2159,22 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) /* Disable CP parsing/prefetching */ 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 */ grbm_reset = (SOFT_RESET_CP | SOFT_RESET_CB | diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 98909b264ac2f2508604b0974443d1bb777308a7..c056aae814f090693a4eb445d83d3ca2be30efd7 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -62,6 +62,22 @@ #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 GC_USER_SYS_RB_BACKEND_DISABLE 0xe84