Commit 4c712e6c authored by Dave Airlie's avatar Dave Airlie

drm/radeon/kms: check/restore sanity before doing anything else with GPU.

On systems using kexec, the new kernel is booted straight from the old kernel, without any warning to the graphics driver. So the GPU is basically left as-is in a running state, however the CPU side is completly reset.

Without stating the saneness of anyone using kexec on live systems, we should at least try not to crash the GPU. This patch resets 3 registers to 0 that could cause bad things to happen to the running system.

This allows kexec to work on a Power6/RN50 system.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent e376573f
...@@ -3809,6 +3809,31 @@ void r100_fini(struct radeon_device *rdev) ...@@ -3809,6 +3809,31 @@ void r100_fini(struct radeon_device *rdev)
rdev->bios = NULL; rdev->bios = NULL;
} }
/*
* Due to how kexec works, it can leave the hw fully initialised when it
* boots the new kernel. However doing our init sequence with the CP and
* WB stuff setup causes GPU hangs on the RN50 at least. So at startup
* do some quick sanity checks and restore sane values to avoid this
* problem.
*/
void r100_restore_sanity(struct radeon_device *rdev)
{
u32 tmp;
tmp = RREG32(RADEON_CP_CSQ_CNTL);
if (tmp) {
WREG32(RADEON_CP_CSQ_CNTL, 0);
}
tmp = RREG32(RADEON_CP_RB_CNTL);
if (tmp) {
WREG32(RADEON_CP_RB_CNTL, 0);
}
tmp = RREG32(RADEON_SCRATCH_UMSK);
if (tmp) {
WREG32(RADEON_SCRATCH_UMSK, 0);
}
}
int r100_init(struct radeon_device *rdev) int r100_init(struct radeon_device *rdev)
{ {
int r; int r;
...@@ -3821,6 +3846,8 @@ int r100_init(struct radeon_device *rdev) ...@@ -3821,6 +3846,8 @@ int r100_init(struct radeon_device *rdev)
radeon_scratch_init(rdev); radeon_scratch_init(rdev);
/* Initialize surface registers */ /* Initialize surface registers */
radeon_surface_init(rdev); radeon_surface_init(rdev);
/* sanity check some register to avoid hangs like after kexec */
r100_restore_sanity(rdev);
/* TODO: disable VGA need to use VGA request */ /* TODO: disable VGA need to use VGA request */
/* BIOS*/ /* BIOS*/
if (!radeon_get_bios(rdev)) { if (!radeon_get_bios(rdev)) {
......
...@@ -1377,6 +1377,8 @@ int r300_init(struct radeon_device *rdev) ...@@ -1377,6 +1377,8 @@ int r300_init(struct radeon_device *rdev)
/* Initialize surface registers */ /* Initialize surface registers */
radeon_surface_init(rdev); radeon_surface_init(rdev);
/* TODO: disable VGA need to use VGA request */ /* TODO: disable VGA need to use VGA request */
/* restore some register to sane defaults */
r100_restore_sanity(rdev);
/* BIOS*/ /* BIOS*/
if (!radeon_get_bios(rdev)) { if (!radeon_get_bios(rdev)) {
if (ASIC_IS_AVIVO(rdev)) if (ASIC_IS_AVIVO(rdev))
......
...@@ -343,6 +343,8 @@ int r420_init(struct radeon_device *rdev) ...@@ -343,6 +343,8 @@ int r420_init(struct radeon_device *rdev)
/* Initialize surface registers */ /* Initialize surface registers */
radeon_surface_init(rdev); radeon_surface_init(rdev);
/* TODO: disable VGA need to use VGA request */ /* TODO: disable VGA need to use VGA request */
/* restore some register to sane defaults */
r100_restore_sanity(rdev);
/* BIOS*/ /* BIOS*/
if (!radeon_get_bios(rdev)) { if (!radeon_get_bios(rdev)) {
if (ASIC_IS_AVIVO(rdev)) if (ASIC_IS_AVIVO(rdev))
......
...@@ -230,6 +230,8 @@ int r520_init(struct radeon_device *rdev) ...@@ -230,6 +230,8 @@ int r520_init(struct radeon_device *rdev)
radeon_scratch_init(rdev); radeon_scratch_init(rdev);
/* Initialize surface registers */ /* Initialize surface registers */
radeon_surface_init(rdev); radeon_surface_init(rdev);
/* restore some register to sane defaults */
r100_restore_sanity(rdev);
/* TODO: disable VGA need to use VGA request */ /* TODO: disable VGA need to use VGA request */
/* BIOS*/ /* BIOS*/
if (!radeon_get_bios(rdev)) { if (!radeon_get_bios(rdev)) {
......
...@@ -113,6 +113,7 @@ void r100_wb_fini(struct radeon_device *rdev); ...@@ -113,6 +113,7 @@ void r100_wb_fini(struct radeon_device *rdev);
int r100_wb_init(struct radeon_device *rdev); int r100_wb_init(struct radeon_device *rdev);
int r100_cp_reset(struct radeon_device *rdev); int r100_cp_reset(struct radeon_device *rdev);
void r100_vga_render_disable(struct radeon_device *rdev); void r100_vga_render_disable(struct radeon_device *rdev);
void r100_restore_sanity(struct radeon_device *rdev);
int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt, struct radeon_cs_packet *pkt,
struct radeon_bo *robj); struct radeon_bo *robj);
......
...@@ -480,6 +480,8 @@ int rs400_init(struct radeon_device *rdev) ...@@ -480,6 +480,8 @@ int rs400_init(struct radeon_device *rdev)
/* Initialize surface registers */ /* Initialize surface registers */
radeon_surface_init(rdev); radeon_surface_init(rdev);
/* TODO: disable VGA need to use VGA request */ /* TODO: disable VGA need to use VGA request */
/* restore some register to sane defaults */
r100_restore_sanity(rdev);
/* BIOS*/ /* BIOS*/
if (!radeon_get_bios(rdev)) { if (!radeon_get_bios(rdev)) {
if (ASIC_IS_AVIVO(rdev)) if (ASIC_IS_AVIVO(rdev))
......
...@@ -879,6 +879,8 @@ int rs600_init(struct radeon_device *rdev) ...@@ -879,6 +879,8 @@ int rs600_init(struct radeon_device *rdev)
radeon_scratch_init(rdev); radeon_scratch_init(rdev);
/* Initialize surface registers */ /* Initialize surface registers */
radeon_surface_init(rdev); radeon_surface_init(rdev);
/* restore some register to sane defaults */
r100_restore_sanity(rdev);
/* BIOS */ /* BIOS */
if (!radeon_get_bios(rdev)) { if (!radeon_get_bios(rdev)) {
if (ASIC_IS_AVIVO(rdev)) if (ASIC_IS_AVIVO(rdev))
......
...@@ -707,6 +707,8 @@ int rs690_init(struct radeon_device *rdev) ...@@ -707,6 +707,8 @@ int rs690_init(struct radeon_device *rdev)
radeon_scratch_init(rdev); radeon_scratch_init(rdev);
/* Initialize surface registers */ /* Initialize surface registers */
radeon_surface_init(rdev); radeon_surface_init(rdev);
/* restore some register to sane defaults */
r100_restore_sanity(rdev);
/* TODO: disable VGA need to use VGA request */ /* TODO: disable VGA need to use VGA request */
/* BIOS*/ /* BIOS*/
if (!radeon_get_bios(rdev)) { if (!radeon_get_bios(rdev)) {
......
...@@ -468,6 +468,8 @@ int rv515_init(struct radeon_device *rdev) ...@@ -468,6 +468,8 @@ int rv515_init(struct radeon_device *rdev)
/* Initialize surface registers */ /* Initialize surface registers */
radeon_surface_init(rdev); radeon_surface_init(rdev);
/* TODO: disable VGA need to use VGA request */ /* TODO: disable VGA need to use VGA request */
/* restore some register to sane defaults */
r100_restore_sanity(rdev);
/* BIOS*/ /* BIOS*/
if (!radeon_get_bios(rdev)) { if (!radeon_get_bios(rdev)) {
if (ASIC_IS_AVIVO(rdev)) if (ASIC_IS_AVIVO(rdev))
......
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