xf86-video-intel: src/i810_reg.h src/i830_display.c src/i830_driver.c

Jesse Barnes jbarnes at kemper.freedesktop.org
Mon May 26 09:41:54 PDT 2008


 src/i810_reg.h     |    2 ++
 src/i830_display.c |    4 ++++
 src/i830_driver.c  |   44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+)

New commits:
commit 2e1425246ccc75216247b0c2fa6fce2635db472b
Author: Jesse Barnes <jbarnes at hobbes.lan>
Date:   Mon May 26 09:40:10 2008 -0700

    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.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index a357d19..d97780f 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 1122721..2d2d072 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 df9d729..0a8ec56 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);
 }
 


More information about the xorg-commit mailing list