drm/radeon/dce8: workaround for atom BlankCrtc table
authorAlex Deucher <alexander.deucher@amd.com>
Wed, 29 Jan 2014 04:49:37 +0000 (23:49 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Feb 2014 21:50:22 +0000 (13:50 -0800)
commit 78fe9e545ce6d510b979dc2d8e14096a279fc519 upstream.

Some DCE8 boards have a funky BlankCrtc table that results
in a timeout when trying to blank the display.  The
timeout is harmless (all operations needed from the table
are complete), but wastes time and is confusing to users so
work around it.

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=73420

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/radeon/atombios_crtc.c

index c6a9c5d..0ee2cf5 100644 (file)
@@ -209,6 +209,16 @@ static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state)
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+static const u32 vga_control_regs[6] =
+{
+       AVIVO_D1VGA_CONTROL,
+       AVIVO_D2VGA_CONTROL,
+       EVERGREEN_D3VGA_CONTROL,
+       EVERGREEN_D4VGA_CONTROL,
+       EVERGREEN_D5VGA_CONTROL,
+       EVERGREEN_D6VGA_CONTROL,
+};
+
 static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -216,13 +226,23 @@ static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
        struct radeon_device *rdev = dev->dev_private;
        int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC);
        BLANK_CRTC_PS_ALLOCATION args;
+       u32 vga_control = 0;
 
        memset(&args, 0, sizeof(args));
 
+       if (ASIC_IS_DCE8(rdev)) {
+               vga_control = RREG32(vga_control_regs[radeon_crtc->crtc_id]);
+               WREG32(vga_control_regs[radeon_crtc->crtc_id], vga_control | 1);
+       }
+
        args.ucCRTC = radeon_crtc->crtc_id;
        args.ucBlanking = state;
 
        atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+       if (ASIC_IS_DCE8(rdev)) {
+               WREG32(vga_control_regs[radeon_crtc->crtc_id], vga_control);
+       }
 }
 
 static void atombios_powergate_crtc(struct drm_crtc *crtc, int state)