summaryrefslogtreecommitdiff
path: root/src/i830_display.c
diff options
context:
space:
mode:
authorMa Ling <ling.ma@intel.com>2009-01-14 14:46:52 +0800
committerZhenyu Wang <zhenyu.z.wang@intel.com>2009-01-14 14:46:52 +0800
commitdb9f5915ce812144ffd9d2aa42e8ba856129c35e (patch)
tree99dda64137131492e5e893c4a5aedc168f288a59 /src/i830_display.c
parenta4b023c17b9c3bd65fb9466ddb8a953f60244402 (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.c34
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;
}