diff options
author | Jesse Barnes <jbarnes@hobbes.lan> | 2008-05-26 09:40:10 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-05-26 09:40:10 -0700 |
commit | 2e1425246ccc75216247b0c2fa6fce2635db472b (patch) | |
tree | 691a69e52311f44359ce313b6a2760afe831ff99 /src | |
parent | 89bb53cc7a853d88fc34a0ca65ae2b6227a8dd24 (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.h | 2 | ||||
-rw-r--r-- | src/i830_display.c | 4 | ||||
-rw-r--r-- | src/i830_driver.c | 44 |
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); } |