diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2011-01-11 13:36:55 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-01-16 21:21:57 -0500 |
commit | 25b2ec5b643c9ea784e5a51e5e9602cd536965f2 (patch) | |
tree | a6a7f9f7423f2957819d362cadad37a53da5ee0f /drivers/gpu | |
parent | fd909c3718da3fb8c5c0530f93ae21d85dc31471 (diff) |
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: Alex Deucher <alexdeucher@gmail.com>
Cc: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r300.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rs600.c | 16 |
3 files changed, 20 insertions, 18 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index f637595b14e1..46da5142b131 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -2086,12 +2086,13 @@ int r100_asic_reset(struct radeon_device *rdev) | |||
2086 | { | 2086 | { |
2087 | struct r100_mc_save save; | 2087 | struct r100_mc_save save; |
2088 | u32 status, tmp; | 2088 | u32 status, tmp; |
2089 | int ret = 0; | ||
2089 | 2090 | ||
2090 | r100_mc_stop(rdev, &save); | ||
2091 | status = RREG32(R_000E40_RBBM_STATUS); | 2091 | status = RREG32(R_000E40_RBBM_STATUS); |
2092 | if (!G_000E40_GUI_ACTIVE(status)) { | 2092 | if (!G_000E40_GUI_ACTIVE(status)) { |
2093 | return 0; | 2093 | return 0; |
2094 | } | 2094 | } |
2095 | r100_mc_stop(rdev, &save); | ||
2095 | status = RREG32(R_000E40_RBBM_STATUS); | 2096 | status = RREG32(R_000E40_RBBM_STATUS); |
2096 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | 2097 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); |
2097 | /* stop CP */ | 2098 | /* stop CP */ |
@@ -2131,11 +2132,11 @@ int r100_asic_reset(struct radeon_device *rdev) | |||
2131 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { | 2132 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { |
2132 | dev_err(rdev->dev, "failed to reset GPU\n"); | 2133 | dev_err(rdev->dev, "failed to reset GPU\n"); |
2133 | rdev->gpu_lockup = true; | 2134 | rdev->gpu_lockup = true; |
2134 | return -1; | 2135 | ret = -1; |
2135 | } | 2136 | } else |
2137 | dev_info(rdev->dev, "GPU reset succeed\n"); | ||
2136 | r100_mc_resume(rdev, &save); | 2138 | r100_mc_resume(rdev, &save); |
2137 | dev_info(rdev->dev, "GPU reset succeed\n"); | 2139 | return ret; |
2138 | return 0; | ||
2139 | } | 2140 | } |
2140 | 2141 | ||
2141 | void r100_set_common_regs(struct radeon_device *rdev) | 2142 | void r100_set_common_regs(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index fae5e709f270..cf862ca580bf 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -405,12 +405,13 @@ int r300_asic_reset(struct radeon_device *rdev) | |||
405 | { | 405 | { |
406 | struct r100_mc_save save; | 406 | struct r100_mc_save save; |
407 | u32 status, tmp; | 407 | u32 status, tmp; |
408 | int ret = 0; | ||
408 | 409 | ||
409 | r100_mc_stop(rdev, &save); | ||
410 | status = RREG32(R_000E40_RBBM_STATUS); | 410 | status = RREG32(R_000E40_RBBM_STATUS); |
411 | if (!G_000E40_GUI_ACTIVE(status)) { | 411 | if (!G_000E40_GUI_ACTIVE(status)) { |
412 | return 0; | 412 | return 0; |
413 | } | 413 | } |
414 | r100_mc_stop(rdev, &save); | ||
414 | status = RREG32(R_000E40_RBBM_STATUS); | 415 | status = RREG32(R_000E40_RBBM_STATUS); |
415 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | 416 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); |
416 | /* stop CP */ | 417 | /* stop CP */ |
@@ -451,11 +452,11 @@ int r300_asic_reset(struct radeon_device *rdev) | |||
451 | if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { | 452 | if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { |
452 | dev_err(rdev->dev, "failed to reset GPU\n"); | 453 | dev_err(rdev->dev, "failed to reset GPU\n"); |
453 | rdev->gpu_lockup = true; | 454 | rdev->gpu_lockup = true; |
454 | return -1; | 455 | ret = -1; |
455 | } | 456 | } else |
457 | dev_info(rdev->dev, "GPU reset succeed\n"); | ||
456 | r100_mc_resume(rdev, &save); | 458 | r100_mc_resume(rdev, &save); |
457 | dev_info(rdev->dev, "GPU reset succeed\n"); | 459 | return ret; |
458 | return 0; | ||
459 | } | 460 | } |
460 | 461 | ||
461 | /* | 462 | /* |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index b4192acaab5f..5afe294ed51f 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -339,16 +339,16 @@ void rs600_bm_disable(struct radeon_device *rdev) | |||
339 | 339 | ||
340 | int rs600_asic_reset(struct radeon_device *rdev) | 340 | int rs600_asic_reset(struct radeon_device *rdev) |
341 | { | 341 | { |
342 | u32 status, tmp; | ||
343 | |||
344 | struct rv515_mc_save save; | 342 | struct rv515_mc_save save; |
343 | u32 status, tmp; | ||
344 | int ret = 0; | ||
345 | 345 | ||
346 | /* Stops all mc clients */ | ||
347 | rv515_mc_stop(rdev, &save); | ||
348 | status = RREG32(R_000E40_RBBM_STATUS); | 346 | status = RREG32(R_000E40_RBBM_STATUS); |
349 | if (!G_000E40_GUI_ACTIVE(status)) { | 347 | if (!G_000E40_GUI_ACTIVE(status)) { |
350 | return 0; | 348 | return 0; |
351 | } | 349 | } |
350 | /* Stops all mc clients */ | ||
351 | rv515_mc_stop(rdev, &save); | ||
352 | status = RREG32(R_000E40_RBBM_STATUS); | 352 | status = RREG32(R_000E40_RBBM_STATUS); |
353 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); | 353 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); |
354 | /* stop CP */ | 354 | /* stop CP */ |
@@ -392,11 +392,11 @@ int rs600_asic_reset(struct radeon_device *rdev) | |||
392 | if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { | 392 | if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { |
393 | dev_err(rdev->dev, "failed to reset GPU\n"); | 393 | dev_err(rdev->dev, "failed to reset GPU\n"); |
394 | rdev->gpu_lockup = true; | 394 | rdev->gpu_lockup = true; |
395 | return -1; | 395 | ret = -1; |
396 | } | 396 | } else |
397 | dev_info(rdev->dev, "GPU reset succeed\n"); | ||
397 | rv515_mc_resume(rdev, &save); | 398 | rv515_mc_resume(rdev, &save); |
398 | dev_info(rdev->dev, "GPU reset succeed\n"); | 399 | return ret; |
399 | return 0; | ||
400 | } | 400 | } |
401 | 401 | ||
402 | /* | 402 | /* |