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

Eric Anholt anholt at kemper.freedesktop.org
Fri Jul 18 08:35:58 PDT 2008


 src/i830_display.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/i830_driver.c  |   58 ----------------------------------------
 2 files changed, 75 insertions(+), 58 deletions(-)

New commits:
commit b8ca1c747a679c931267363639fc0bc690cae2d6
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 17 14:41:51 2008 -0700

    Choose a split for DSPARB based on the configured modes for both planes.
    
    Previously, we were attempting to give both planes equal space in the FIFO
    to be fair.  However, larger modes require more fifo space, so split it based
    on the relative HDisplay of the modes.  This should resolve some fifo underrun
    issues with differently-sized displays, or single large ones.
    
    Bug #16169.

diff --git a/src/i830_display.c b/src/i830_display.c
index 3967b69..69bf7f7 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1093,6 +1093,79 @@ i830_panel_fitter_pipe(I830Ptr pI830)
 }
 
 /**
+ * Sets up the DSPARB register to split the display fifo appropriately between
+ * the display planes.
+ *
+ * Adjusting this register requires that the planes be off.
+ */
+static void
+i830_update_dsparb(ScrnInfoPtr pScrn)
+{
+   xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+   I830Ptr pI830 = I830PTR(pScrn);
+   uint32_t dspacntr, dspbcntr;
+   int total_hdisplay = 0, planea_hdisplay = 0, planeb_hdisplay = 0;
+   int fifo_entries = 0, planea_entries = 0, planeb_entries = 0, i;
+
+   dspacntr = INREG(DSPACNTR);
+   dspbcntr = INREG(DSPBCNTR);
+
+   /* Disable planes since DSPARB can only be updated when they're
+    * off.
+    */
+   OUTREG(DSPACNTR, dspacntr & ~DISPLAY_PLANE_ENABLE);
+   OUTREG(DSPBCNTR, dspbcntr & ~DISPLAY_PLANE_ENABLE);
+   i830WaitForVblank(pScrn);
+
+   /*
+    * FIFO entries will be split based on programmed modes
+    */
+   if (IS_I965GM(pI830) || IS_GM45(pI830))
+       fifo_entries = 127;
+   else if (IS_I9XX(pI830))
+       fifo_entries = 95;
+   else if (IS_MOBILE(pI830)) {
+       fifo_entries = 255;
+   } else {
+	/* The 845/865 only have a AEND field.  Though the field size would
+	* allow 128 entries, the 865 rendered the cursor wrong then.
+	* The BIOS set it up for 96.
+	*/
+	fifo_entries = 95;
+   }
+
+   for (i = 0; i < xf86_config->num_crtc; i++) {
+      xf86CrtcPtr crtc = xf86_config->crtc[i];
+      I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+      if (crtc->enabled) {
+	  total_hdisplay += crtc->mode.HDisplay;
+	  if (intel_crtc->plane == 0)
+	      planea_hdisplay = crtc->mode.HDisplay;
+	  else
+	      planeb_hdisplay = crtc->mode.HDisplay;
+      }
+   }
+
+   planea_entries = fifo_entries * planea_hdisplay / total_hdisplay;
+   planeb_entries = fifo_entries * planeb_hdisplay / total_hdisplay;
+
+   if (IS_I9XX(pI830))
+       OUTREG(DSPARB,
+	      ((planea_entries + planeb_entries) << DSPARB_CSTART_SHIFT) |
+	      (planea_entries << DSPARB_BSTART_SHIFT));
+   else if (IS_MOBILE(pI830))
+       OUTREG(DSPARB,
+	      ((planea_entries + planeb_entries) << DSPARB_BEND_SHIFT) |
+	      (planea_entries << DSPARB_AEND_SHIFT));
+   else
+       OUTREG(DSPARB, planea_entries << DSPARB_AEND_SHIFT);
+
+   OUTREG(DSPACNTR, dspacntr);
+   OUTREG(DSPBCNTR, dspbcntr);
+   i830WaitForVblank(pScrn);
+}
+
+/**
  * Sets up registers for the given mode/adjusted_mode pair.
  *
  * The clocks, CRTCs and outputs attached to this CRTC must be off.
@@ -1437,6 +1510,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
     
     i830WaitForVblank(pScrn);
 
+    i830_update_dsparb(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 e29dd10..84aedba 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1954,59 +1954,6 @@ i830_refresh_ring(ScrnInfoPtr pScrn)
    i830MarkSync(pScrn);
 }
 
-/**
- * Sets up the DSPARB register to split the display fifo appropriately between
- * the display planes.
- *
- * Adjusting this register requires that the planes be off, thus as a side
- * effect they are disabled by this function.
- */
-static void
-i830_set_dsparb(ScrnInfoPtr pScrn)
-{
-   xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-   I830Ptr pI830 = I830PTR(pScrn);
-   int i;
-
-   /* Disable outputs & pipes since DSPARB 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);
-
-   /* Fixup FIFO defaults:
-    * we don't use plane C at all so we can allocate all but one of the 96
-    * FIFO RAM entries equally between planes A and B.
-    */
-   if (IS_I9XX(pI830)) {
-       if (IS_I965GM(pI830) || IS_GM45(pI830))
-	   OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) |
-		  (64 << DSPARB_BSTART_SHIFT));
-       else
-	   OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) |
-		  (48 << DSPARB_BSTART_SHIFT));
-   } else {
-       if (IS_MOBILE(pI830)) {
-	   /* The 830 has 288 entries, and the 855 has 256. */
-	   OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT);
-       } else {
-	   /* The 845/865 only have a AEND field.  Though the field size would
-	    * allow 128 entries, the 865 rendered the cursor wrong then.
-	    * The BIOS set it up for 96.
-	    */
-	   OUTREG(DSPARB, 95 << DSPARB_AEND_SHIFT);
-       }
-   }
-}
-
 enum pipe {
     PIPE_A = 0,
     PIPE_B,
@@ -3416,11 +3363,6 @@ I830EnterVT(int scrnIndex, int flags)
    if (!pI830->SWCursor)
       I830InitHWCursor(pScrn);
 
-   /* Set the DSPARB register.  This disables the outputs, which is about to
-    * happen (likely) in xf86SetDesiredModes anyway.
-    */
-   i830_set_dsparb(pScrn);
-
    /* Tell the BIOS that we're in control of mode setting now. */
    i830_init_bios_control(pScrn);
 


More information about the xorg-commit mailing list