From db9f5915ce812144ffd9d2aa42e8ba856129c35e Mon Sep 17 00:00:00 2001 From: Ma Ling Date: Wed, 14 Jan 2009 14:46:52 +0800 Subject: [PATCH] Disable VGA plane reliably This fixes #17235, VGA random hang on recent G45/43 board. From spec, SR01 bit 5 should be set before VGA plane disable through control register, otherwise we might get random crash and lockups. --- src/i830_display.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index 4fba1fb2..7a8e96da 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -786,6 +786,37 @@ static void i830_modeset_ctl(xf86CrtcPtr crtc, int dpms_state) } #endif /* DRM_IOCTL_MODESET_CTL && (XF86DRI || DRI2) */ +static void +i830_disable_vga_plane (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + I830Ptr pI830 = I830PTR(pScrn); + uint32_t vgacntrl = INREG(VGACNTRL); + uint8_t sr01; + + if (vgacntrl & VGA_DISP_DISABLE) + return; + + /* + Set bit 5 of SR01; + Wait 30us; + */ + OUTREG8(SRX, 1); + sr01 = INREG8(SRX + 1); + OUTREG8(SRX + 1, sr01 | (1 << 5)); + usleep(30); + + vgacntrl |= VGA_DISP_DISABLE; + + /* disable center mode */ + if (IS_I9XX(pI830)) + vgacntrl &= ~(3 << 24); + + OUTREG(VGACNTRL, vgacntrl); + i830WaitForVblank(pScrn); + +} + /** * Sets the power management mode of the pipe and plane. * @@ -910,8 +941,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) } /* Disable the VGA plane that we never use. */ - OUTREG(VGACNTRL, VGA_DISP_DISABLE); - i830WaitForVblank(pScrn); + i830_disable_vga_plane (crtc); break; }