From: Alex Deucher Date: Thu, 24 Jan 2013 16:37:19 +0000 (-0500) Subject: drm/radeon: use the reset mask to determine if rings are hung X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=123bc1832c33218dfa677a88c2c54bc1a48a9e72;p=linux-beck.git drm/radeon: use the reset mask to determine if rings are hung fetch the reset mask and check if the relevant ring flags are set to determine whether the ring is hung or not. Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f77e33262274..045955d5f337 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2308,25 +2308,6 @@ int evergreen_mc_init(struct radeon_device *rdev) return 0; } -bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 srbm_status; - u32 grbm_status; - u32 grbm_status_se0, grbm_status_se1; - - srbm_status = RREG32(SRBM_STATUS); - grbm_status = RREG32(GRBM_STATUS); - grbm_status_se0 = RREG32(GRBM_STATUS_SE0); - grbm_status_se1 = RREG32(GRBM_STATUS_SE1); - if (!(grbm_status & GUI_ACTIVE)) { - radeon_ring_lockup_update(ring); - return false; - } - /* force CP activities */ - radeon_ring_force_activity(rdev, ring); - return radeon_ring_test_lockup(rdev, ring); -} - void evergreen_print_gpu_status_regs(struct radeon_device *rdev) { dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", @@ -2578,6 +2559,52 @@ int evergreen_asic_reset(struct radeon_device *rdev) return 0; } +/** + * evergreen_gfx_is_lockup - Check if the GFX engine is locked up + * + * @rdev: radeon_device pointer + * @ring: radeon_ring structure holding ring information + * + * Check if the GFX engine is locked up. + * Returns true if the engine appears to be locked up, false if not. + */ +bool evergreen_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) +{ + u32 reset_mask = evergreen_gpu_check_soft_reset(rdev); + + if (!(reset_mask & (RADEON_RESET_GFX | + RADEON_RESET_COMPUTE | + RADEON_RESET_CP))) { + radeon_ring_lockup_update(ring); + return false; + } + /* force CP activities */ + radeon_ring_force_activity(rdev, ring); + return radeon_ring_test_lockup(rdev, ring); +} + +/** + * evergreen_dma_is_lockup - Check if the DMA engine is locked up + * + * @rdev: radeon_device pointer + * @ring: radeon_ring structure holding ring information + * + * Check if the async DMA engine is locked up. + * Returns true if the engine appears to be locked up, false if not. + */ +bool evergreen_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) +{ + u32 reset_mask = evergreen_gpu_check_soft_reset(rdev); + + if (!(reset_mask & RADEON_RESET_DMA)) { + radeon_ring_lockup_update(ring); + return false; + } + /* force ring activities */ + radeon_ring_force_activity(rdev, ring); + return radeon_ring_test_lockup(rdev, ring); +} + /* Interrupts */ u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 4784c4e5056f..b6e80550ed90 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1533,24 +1533,50 @@ int cayman_asic_reset(struct radeon_device *rdev) return 0; } +/** + * cayman_gfx_is_lockup - Check if the GFX engine is locked up + * + * @rdev: radeon_device pointer + * @ring: radeon_ring structure holding ring information + * + * Check if the GFX engine is locked up. + * Returns true if the engine appears to be locked up, false if not. + */ +bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) +{ + u32 reset_mask = cayman_gpu_check_soft_reset(rdev); + + if (!(reset_mask & (RADEON_RESET_GFX | + RADEON_RESET_COMPUTE | + RADEON_RESET_CP))) { + radeon_ring_lockup_update(ring); + return false; + } + /* force CP activities */ + radeon_ring_force_activity(rdev, ring); + return radeon_ring_test_lockup(rdev, ring); +} + /** * cayman_dma_is_lockup - Check if the DMA engine is locked up * * @rdev: radeon_device pointer * @ring: radeon_ring structure holding ring information * - * Check if the async DMA engine is locked up (cayman-SI). + * Check if the async DMA engine is locked up. * Returns true if the engine appears to be locked up, false if not. */ bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { - u32 dma_status_reg; + u32 reset_mask = cayman_gpu_check_soft_reset(rdev); + u32 mask; if (ring->idx == R600_RING_TYPE_DMA_INDEX) - dma_status_reg = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET); + mask = RADEON_RESET_DMA; else - dma_status_reg = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET); - if (dma_status_reg & DMA_IDLE) { + mask = RADEON_RESET_DMA1; + + if (!(reset_mask & mask)) { radeon_ring_lockup_update(ring); return false; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index abb143c0bdca..3f292765aea8 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1537,16 +1537,22 @@ int r600_asic_reset(struct radeon_device *rdev) return 0; } -bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) +/** + * r600_gfx_is_lockup - Check if the GFX engine is locked up + * + * @rdev: radeon_device pointer + * @ring: radeon_ring structure holding ring information + * + * Check if the GFX engine is locked up. + * Returns true if the engine appears to be locked up, false if not. + */ +bool r600_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { - u32 srbm_status; - u32 grbm_status; - u32 grbm_status2; - - srbm_status = RREG32(R_000E50_SRBM_STATUS); - grbm_status = RREG32(R_008010_GRBM_STATUS); - grbm_status2 = RREG32(R_008014_GRBM_STATUS2); - if (!G_008010_GUI_ACTIVE(grbm_status)) { + u32 reset_mask = r600_gpu_check_soft_reset(rdev); + + if (!(reset_mask & (RADEON_RESET_GFX | + RADEON_RESET_COMPUTE | + RADEON_RESET_CP))) { radeon_ring_lockup_update(ring); return false; } @@ -1561,15 +1567,14 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) * @rdev: radeon_device pointer * @ring: radeon_ring structure holding ring information * - * Check if the async DMA engine is locked up (r6xx-evergreen). + * Check if the async DMA engine is locked up. * Returns true if the engine appears to be locked up, false if not. */ bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { - u32 dma_status_reg; + u32 reset_mask = r600_gpu_check_soft_reset(rdev); - dma_status_reg = RREG32(DMA_STATUS_REG); - if (dma_status_reg & DMA_IDLE) { + if (!(reset_mask & RADEON_RESET_DMA)) { radeon_ring_lockup_update(ring); return false; } diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 0b202c07fe50..82b5ef043b0e 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -946,7 +946,7 @@ static struct radeon_asic r600_asic = { .cs_parse = &r600_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &r600_gpu_is_lockup, + .is_lockup = &r600_gfx_is_lockup, }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &r600_dma_ring_ib_execute, @@ -1030,7 +1030,7 @@ static struct radeon_asic rs780_asic = { .cs_parse = &r600_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &r600_gpu_is_lockup, + .is_lockup = &r600_gfx_is_lockup, }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &r600_dma_ring_ib_execute, @@ -1114,7 +1114,7 @@ static struct radeon_asic rv770_asic = { .cs_parse = &r600_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &r600_gpu_is_lockup, + .is_lockup = &r600_gfx_is_lockup, }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &r600_dma_ring_ib_execute, @@ -1198,7 +1198,7 @@ static struct radeon_asic evergreen_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &evergreen_gfx_is_lockup, }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &evergreen_dma_ring_ib_execute, @@ -1207,7 +1207,7 @@ static struct radeon_asic evergreen_asic = { .cs_parse = &evergreen_dma_cs_parse, .ring_test = &r600_dma_ring_test, .ib_test = &r600_dma_ib_test, - .is_lockup = &r600_dma_is_lockup, + .is_lockup = &evergreen_dma_is_lockup, } }, .irq = { @@ -1282,7 +1282,7 @@ static struct radeon_asic sumo_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &evergreen_gfx_is_lockup, }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &evergreen_dma_ring_ib_execute, @@ -1291,7 +1291,7 @@ static struct radeon_asic sumo_asic = { .cs_parse = &evergreen_dma_cs_parse, .ring_test = &r600_dma_ring_test, .ib_test = &r600_dma_ib_test, - .is_lockup = &r600_dma_is_lockup, + .is_lockup = &evergreen_dma_is_lockup, } }, .irq = { @@ -1366,7 +1366,7 @@ static struct radeon_asic btc_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &evergreen_gfx_is_lockup, }, [R600_RING_TYPE_DMA_INDEX] = { .ib_execute = &evergreen_dma_ring_ib_execute, @@ -1375,7 +1375,7 @@ static struct radeon_asic btc_asic = { .cs_parse = &evergreen_dma_cs_parse, .ring_test = &r600_dma_ring_test, .ib_test = &r600_dma_ib_test, - .is_lockup = &r600_dma_is_lockup, + .is_lockup = &evergreen_dma_is_lockup, } }, .irq = { @@ -1457,7 +1457,7 @@ static struct radeon_asic cayman_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &cayman_gfx_is_lockup, .vm_flush = &cayman_vm_flush, }, [CAYMAN_RING_TYPE_CP1_INDEX] = { @@ -1468,7 +1468,7 @@ static struct radeon_asic cayman_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &cayman_gfx_is_lockup, .vm_flush = &cayman_vm_flush, }, [CAYMAN_RING_TYPE_CP2_INDEX] = { @@ -1479,7 +1479,7 @@ static struct radeon_asic cayman_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &cayman_gfx_is_lockup, .vm_flush = &cayman_vm_flush, }, [R600_RING_TYPE_DMA_INDEX] = { @@ -1584,7 +1584,7 @@ static struct radeon_asic trinity_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &cayman_gfx_is_lockup, .vm_flush = &cayman_vm_flush, }, [CAYMAN_RING_TYPE_CP1_INDEX] = { @@ -1595,7 +1595,7 @@ static struct radeon_asic trinity_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &cayman_gfx_is_lockup, .vm_flush = &cayman_vm_flush, }, [CAYMAN_RING_TYPE_CP2_INDEX] = { @@ -1606,7 +1606,7 @@ static struct radeon_asic trinity_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, + .is_lockup = &cayman_gfx_is_lockup, .vm_flush = &cayman_vm_flush, }, [R600_RING_TYPE_DMA_INDEX] = { @@ -1711,7 +1711,7 @@ static struct radeon_asic si_asic = { .cs_parse = NULL, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &si_gpu_is_lockup, + .is_lockup = &si_gfx_is_lockup, .vm_flush = &si_vm_flush, }, [CAYMAN_RING_TYPE_CP1_INDEX] = { @@ -1722,7 +1722,7 @@ static struct radeon_asic si_asic = { .cs_parse = NULL, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &si_gpu_is_lockup, + .is_lockup = &si_gfx_is_lockup, .vm_flush = &si_vm_flush, }, [CAYMAN_RING_TYPE_CP2_INDEX] = { @@ -1733,7 +1733,7 @@ static struct radeon_asic si_asic = { .cs_parse = NULL, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &si_gpu_is_lockup, + .is_lockup = &si_gfx_is_lockup, .vm_flush = &si_vm_flush, }, [R600_RING_TYPE_DMA_INDEX] = { @@ -1744,7 +1744,7 @@ static struct radeon_asic si_asic = { .cs_parse = NULL, .ring_test = &r600_dma_ring_test, .ib_test = &r600_dma_ib_test, - .is_lockup = &cayman_dma_is_lockup, + .is_lockup = &si_dma_is_lockup, .vm_flush = &si_dma_vm_flush, }, [CAYMAN_RING_TYPE_DMA1_INDEX] = { @@ -1755,7 +1755,7 @@ static struct radeon_asic si_asic = { .cs_parse = NULL, .ring_test = &r600_dma_ring_test, .ib_test = &r600_dma_ib_test, - .is_lockup = &cayman_dma_is_lockup, + .is_lockup = &si_dma_is_lockup, .vm_flush = &si_dma_vm_flush, } }, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 15d70e613076..e429e2574cae 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -319,7 +319,7 @@ void r600_dma_semaphore_ring_emit(struct radeon_device *rdev, bool emit_wait); 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_gpu_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_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, @@ -422,7 +422,8 @@ int evergreen_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); int evergreen_suspend(struct radeon_device *rdev); int evergreen_resume(struct radeon_device *rdev); -bool evergreen_gpu_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); int evergreen_asic_reset(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); @@ -480,6 +481,7 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); void cayman_dma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); +bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); @@ -496,7 +498,8 @@ int si_init(struct radeon_device *rdev); void si_fini(struct radeon_device *rdev); int si_suspend(struct radeon_device *rdev); int si_resume(struct radeon_device *rdev); -bool si_gpu_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); int si_asic_reset(struct radeon_device *rdev); void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int si_irq_set(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 89b564ec3d34..cd83bc5bd235 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2108,26 +2108,6 @@ static int si_cp_resume(struct radeon_device *rdev) return 0; } -bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 srbm_status; - u32 grbm_status, grbm_status2; - u32 grbm_status_se0, grbm_status_se1; - - srbm_status = RREG32(SRBM_STATUS); - grbm_status = RREG32(GRBM_STATUS); - grbm_status2 = RREG32(GRBM_STATUS2); - grbm_status_se0 = RREG32(GRBM_STATUS_SE0); - grbm_status_se1 = RREG32(GRBM_STATUS_SE1); - if (!(grbm_status & GUI_ACTIVE)) { - radeon_ring_lockup_update(ring); - return false; - } - /* force CP activities */ - radeon_ring_force_activity(rdev, ring); - return radeon_ring_test_lockup(rdev, ring); -} - static u32 si_gpu_check_soft_reset(struct radeon_device *rdev) { u32 reset_mask = 0; @@ -2347,6 +2327,58 @@ int si_asic_reset(struct radeon_device *rdev) return 0; } +/** + * si_gfx_is_lockup - Check if the GFX engine is locked up + * + * @rdev: radeon_device pointer + * @ring: radeon_ring structure holding ring information + * + * Check if the GFX engine is locked up. + * Returns true if the engine appears to be locked up, false if not. + */ +bool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) +{ + u32 reset_mask = si_gpu_check_soft_reset(rdev); + + if (!(reset_mask & (RADEON_RESET_GFX | + RADEON_RESET_COMPUTE | + RADEON_RESET_CP))) { + radeon_ring_lockup_update(ring); + return false; + } + /* force CP activities */ + radeon_ring_force_activity(rdev, ring); + return radeon_ring_test_lockup(rdev, ring); +} + +/** + * si_dma_is_lockup - Check if the DMA engine is locked up + * + * @rdev: radeon_device pointer + * @ring: radeon_ring structure holding ring information + * + * Check if the async DMA engine is locked up. + * Returns true if the engine appears to be locked up, false if not. + */ +bool si_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) +{ + u32 reset_mask = si_gpu_check_soft_reset(rdev); + u32 mask; + + if (ring->idx == R600_RING_TYPE_DMA_INDEX) + mask = RADEON_RESET_DMA; + else + mask = RADEON_RESET_DMA1; + + if (!(reset_mask & mask)) { + radeon_ring_lockup_update(ring); + return false; + } + /* force ring activities */ + radeon_ring_force_activity(rdev, ring); + return radeon_ring_test_lockup(rdev, ring); +} + /* MC */ static void si_mc_program(struct radeon_device *rdev) {