Commit 25b2ec5b authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: balance asic_reset functions

First, we were calling mc_stop() at the top of the function
which turns off all MC (memory controller) clients,
then checking if the GPU is idle.  If it was idle we
returned without re-enabling the MC clients which would
lead to a blank screen, etc.  This patch checks if the
GPU is idle before calling mc_stop().

Second, if the reset failed, we were returning without
re-enabling the MC clients.  This patch re-enables
the MC clients before returning regardless of whether
the reset was successful or not.
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Cc: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent fd909c37
...@@ -2086,12 +2086,13 @@ int r100_asic_reset(struct radeon_device *rdev) ...@@ -2086,12 +2086,13 @@ int r100_asic_reset(struct radeon_device *rdev)
{ {
struct r100_mc_save save; struct r100_mc_save save;
u32 status, tmp; u32 status, tmp;
int ret = 0;
r100_mc_stop(rdev, &save);
status = RREG32(R_000E40_RBBM_STATUS); status = RREG32(R_000E40_RBBM_STATUS);
if (!G_000E40_GUI_ACTIVE(status)) { if (!G_000E40_GUI_ACTIVE(status)) {
return 0; return 0;
} }
r100_mc_stop(rdev, &save);
status = RREG32(R_000E40_RBBM_STATUS); status = RREG32(R_000E40_RBBM_STATUS);
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
/* stop CP */ /* stop CP */
...@@ -2131,11 +2132,11 @@ int r100_asic_reset(struct radeon_device *rdev) ...@@ -2131,11 +2132,11 @@ int r100_asic_reset(struct radeon_device *rdev)
G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) {
dev_err(rdev->dev, "failed to reset GPU\n"); dev_err(rdev->dev, "failed to reset GPU\n");
rdev->gpu_lockup = true; rdev->gpu_lockup = true;
return -1; ret = -1;
} } else
r100_mc_resume(rdev, &save);
dev_info(rdev->dev, "GPU reset succeed\n"); dev_info(rdev->dev, "GPU reset succeed\n");
return 0; r100_mc_resume(rdev, &save);
return ret;
} }
void r100_set_common_regs(struct radeon_device *rdev) void r100_set_common_regs(struct radeon_device *rdev)
......
...@@ -405,12 +405,13 @@ int r300_asic_reset(struct radeon_device *rdev) ...@@ -405,12 +405,13 @@ int r300_asic_reset(struct radeon_device *rdev)
{ {
struct r100_mc_save save; struct r100_mc_save save;
u32 status, tmp; u32 status, tmp;
int ret = 0;
r100_mc_stop(rdev, &save);
status = RREG32(R_000E40_RBBM_STATUS); status = RREG32(R_000E40_RBBM_STATUS);
if (!G_000E40_GUI_ACTIVE(status)) { if (!G_000E40_GUI_ACTIVE(status)) {
return 0; return 0;
} }
r100_mc_stop(rdev, &save);
status = RREG32(R_000E40_RBBM_STATUS); status = RREG32(R_000E40_RBBM_STATUS);
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
/* stop CP */ /* stop CP */
...@@ -451,11 +452,11 @@ int r300_asic_reset(struct radeon_device *rdev) ...@@ -451,11 +452,11 @@ int r300_asic_reset(struct radeon_device *rdev)
if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
dev_err(rdev->dev, "failed to reset GPU\n"); dev_err(rdev->dev, "failed to reset GPU\n");
rdev->gpu_lockup = true; rdev->gpu_lockup = true;
return -1; ret = -1;
} } else
r100_mc_resume(rdev, &save);
dev_info(rdev->dev, "GPU reset succeed\n"); dev_info(rdev->dev, "GPU reset succeed\n");
return 0; r100_mc_resume(rdev, &save);
return ret;
} }
/* /*
......
...@@ -339,16 +339,16 @@ void rs600_bm_disable(struct radeon_device *rdev) ...@@ -339,16 +339,16 @@ void rs600_bm_disable(struct radeon_device *rdev)
int rs600_asic_reset(struct radeon_device *rdev) int rs600_asic_reset(struct radeon_device *rdev)
{ {
u32 status, tmp;
struct rv515_mc_save save; struct rv515_mc_save save;
u32 status, tmp;
int ret = 0;
/* Stops all mc clients */
rv515_mc_stop(rdev, &save);
status = RREG32(R_000E40_RBBM_STATUS); status = RREG32(R_000E40_RBBM_STATUS);
if (!G_000E40_GUI_ACTIVE(status)) { if (!G_000E40_GUI_ACTIVE(status)) {
return 0; return 0;
} }
/* Stops all mc clients */
rv515_mc_stop(rdev, &save);
status = RREG32(R_000E40_RBBM_STATUS); status = RREG32(R_000E40_RBBM_STATUS);
dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
/* stop CP */ /* stop CP */
...@@ -392,11 +392,11 @@ int rs600_asic_reset(struct radeon_device *rdev) ...@@ -392,11 +392,11 @@ int rs600_asic_reset(struct radeon_device *rdev)
if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) {
dev_err(rdev->dev, "failed to reset GPU\n"); dev_err(rdev->dev, "failed to reset GPU\n");
rdev->gpu_lockup = true; rdev->gpu_lockup = true;
return -1; ret = -1;
} } else
rv515_mc_resume(rdev, &save);
dev_info(rdev->dev, "GPU reset succeed\n"); dev_info(rdev->dev, "GPU reset succeed\n");
return 0; rv515_mc_resume(rdev, &save);
return ret;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment