summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@hobbes.lan>2008-05-26 09:40:10 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-05-26 09:40:10 -0700
commit2e1425246ccc75216247b0c2fa6fce2635db472b (patch)
tree691a69e52311f44359ce313b6a2760afe831ff99 /src
parent89bb53cc7a853d88fc34a0ca65ae2b6227a8dd24 (diff)
Handle display FIFOs better
Add some debug code to catch FIFO underruns, which are normally bugs (unless they occur during mode setting) and remove any plane C FIFO allocations, since we don't use that plane at all. We may eventually need to be a little smarter about this on platforms that use plane C for the popup.
Diffstat (limited to 'src')
-rw-r--r--src/i810_reg.h2
-rw-r--r--src/i830_display.c4
-rw-r--r--src/i830_driver.c44
3 files changed, 50 insertions, 0 deletions
diff --git a/src/i810_reg.h b/src/i810_reg.h
index a357d190..d97780f0 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2103,6 +2103,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPARB 0x70030
+#define DSPARB_CSTART_SHIFT 7
+#define DSPARB_BSTART_SHIFT 0
#define DSPFW1 0x70034
#define DSPFW2 0x70038
#define DSPFW3 0x7003c
diff --git a/src/i830_display.c b/src/i830_display.c
index 1122721a..2d2d072a 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1077,6 +1077,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
+ int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT;
int i;
int refclk;
intel_clock_t clock;
@@ -1376,6 +1377,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
#endif
i830WaitForVblank(pScrn);
+
+ /* Clear any FIFO underrun status that may have occurred normally */
+ OUTREG(pipestat_reg, INREG(pipestat_reg) | FIFO_UNDERRUN);
}
diff --git a/src/i830_driver.c b/src/i830_driver.c
index df9d7299..0a8ec564 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1934,12 +1934,36 @@ static void
SetHWOperatingState(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
DPRINTF(PFX, "SetHWOperatingState\n");
+ /*
+ * Disable outputs & pipes since some of these regs can only be updated
+ * when they're off.
+ */
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ output->funcs->dpms(output, DPMSModeOff);
+ }
+ i830WaitForVblank(pScrn);
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+ crtc->funcs->dpms(crtc, DPMSModeOff);
+ }
+ i830WaitForVblank(pScrn);
+
i830_start_ring(pScrn);
if (!pI830->SWCursor)
I830InitHWCursor(pScrn);
+
+ /*
+ * Fixup FIFO defaults:
+ * we don't use plane C at all so we can allocate the 96 FIFO RAM
+ * entries equally between planes A and B.
+ */
+ OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) | (48 << DSPARB_BSTART_SHIFT));
}
enum pipe {
@@ -2313,6 +2337,10 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL);
}
+ /* Clear any FIFO underrun status that may have occurred normally */
+ OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN);
+ OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN);
+
vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
vgaHWLock(hwp);
@@ -2462,6 +2490,22 @@ I830BlockHandler(int i,
if (pScrn->vtSema && !pI830->noAccel && !pI830->directRenderingEnabled)
I830EmitFlush(pScrn);
+ /*
+ * Check for FIFO underruns at block time (which amounts to just
+ * periodically). If this happens, it means our DSPARB or some other
+ * memory arbitration setting is wrong for the current configuration
+ * (except for mode setting, where it may occur naturally).
+ * Check & ack the condition.
+ */
+ if (INREG(PIPEASTAT) & FIFO_UNDERRUN) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe A!\n");
+ OUTREG(PIPEASTAT, INREG(PIPEASTAT) | FIFO_UNDERRUN);
+ }
+ if (INREG(PIPEBSTAT) & FIFO_UNDERRUN) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "underrun on pipe B!\n");
+ OUTREG(PIPEBSTAT, INREG(PIPEBSTAT) | FIFO_UNDERRUN);
+ }
+
I830VideoBlockHandler(i, blockData, pTimeout, pReadmask);
}