From 410a3418a88cc1273a281d347687f736fc39dd86 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 18 Jan 2013 13:05:39 -0500 Subject: [PATCH] drm/radeon: add a bios scratch asic hung helper Used by all asic families from r600+. Flag for the vbios and later instances of the driver that the GPU is hung. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen.c | 5 +++++ drivers/gpu/drm/radeon/ni.c | 5 +++++ drivers/gpu/drm/radeon/r600.c | 17 +++++++++++++++++ drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/si.c | 5 +++++ 5 files changed, 33 insertions(+) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index a1e12bf2d0f7..dd1d188376bf 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2433,6 +2433,8 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); + r600_set_bios_scratch_engine_hung(rdev, true); + evergreen_mc_stop(rdev, &save); if (evergreen_mc_wait_for_idle(rdev)) { dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); @@ -2448,6 +2450,9 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) udelay(50); evergreen_mc_resume(rdev, &save); + + r600_set_bios_scratch_engine_hung(rdev, false); + return 0; } diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 835992d8d067..af9e86d2fc07 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1422,6 +1422,8 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) if (reset_mask == 0) return 0; + r600_set_bios_scratch_engine_hung(rdev, true); + dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", @@ -1448,6 +1450,9 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) udelay(50); evergreen_mc_resume(rdev, &save); + + r600_set_bios_scratch_engine_hung(rdev, false); + return 0; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index becb03e8b32f..a6208178a6f2 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1254,6 +1254,18 @@ void r600_vram_scratch_fini(struct radeon_device *rdev) radeon_bo_unref(&rdev->vram_scratch.robj); } +void r600_set_bios_scratch_engine_hung(struct radeon_device *rdev, bool hung) +{ + u32 tmp = RREG32(R600_BIOS_3_SCRATCH); + + if (hung) + tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG; + else + tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG; + + WREG32(R600_BIOS_3_SCRATCH, tmp); +} + /* We doesn't check that the GPU really needs a reset we simply do the * reset, it's up to the caller to determine if the GPU needs one. We * might add an helper function to check that. @@ -1389,6 +1401,8 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); + r600_set_bios_scratch_engine_hung(rdev, true); + rv515_mc_stop(rdev, &save); if (r600_mc_wait_for_idle(rdev)) { dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); @@ -1404,6 +1418,9 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) mdelay(1); rv515_mc_resume(rdev, &save); + + r600_set_bios_scratch_engine_hung(rdev, false); + return 0; } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index ec3b739ffd79..6539d6cb4bc7 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1860,6 +1860,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); /* Common functions */ /* AGP */ extern int radeon_gpu_reset(struct radeon_device *rdev); +extern void r600_set_bios_scratch_engine_hung(struct radeon_device *rdev, bool hung); extern void radeon_agp_disable(struct radeon_device *rdev); extern int radeon_modeset_init(struct radeon_device *rdev); extern void radeon_modeset_fini(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index f06072f5e5da..1fc0e5545694 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2231,6 +2231,8 @@ static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); + r600_set_bios_scratch_engine_hung(rdev, true); + evergreen_mc_stop(rdev, &save); if (radeon_mc_wait_for_idle(rdev)) { dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); @@ -2246,6 +2248,9 @@ static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) udelay(50); evergreen_mc_resume(rdev, &save); + + r600_set_bios_scratch_engine_hung(rdev, false); + return 0; } -- 2.39.5