diff options
author | Ma Ling <ling.ma@intel.com> | 2009-01-14 14:46:52 +0800 |
---|---|---|
committer | Zhenyu Wang <zhenyu.z.wang@intel.com> | 2009-01-14 14:46:52 +0800 |
commit | db9f5915ce812144ffd9d2aa42e8ba856129c35e (patch) | |
tree | 99dda64137131492e5e893c4a5aedc168f288a59 /src/i830_display.c | |
parent | a4b023c17b9c3bd65fb9466ddb8a953f60244402 (diff) |
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.
Diffstat (limited to 'src/i830_display.c')
-rw-r--r-- | src/i830_display.c | 34 |
1 files 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; } |