xf86-video-intel: Branch 'modesetting' - src/i830_cursor.c src/i830_display.c src/i830_display.h src/i830_driver.c src/i830.h src/i830_randr.c src/i830_xf86Crtc.h

Eric Anholt anholt at kemper.freedesktop.org
Wed Jan 3 20:05:56 EET 2007


 src/i830.h          |    4 -
 src/i830_cursor.c   |    8 ---
 src/i830_display.c  |   60 ++++++++++++++++++++++--
 src/i830_display.h  |    1 
 src/i830_driver.c   |  127 ++++++++++++++++++----------------------------------
 src/i830_randr.c    |   12 ++++
 src/i830_xf86Crtc.h |    5 ++
 7 files changed, 118 insertions(+), 99 deletions(-)

New commits:
diff-tree 394124ceaadb46d976ad5c3bdeb1b77d351c57f6 (from 69f250af60220a875f4a04c6d682bffa352281e4)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Jan 2 16:57:33 2007 -0800

    Add per-CRTC gamma control support for RandR.
    
    This makes the CRTCs now always run in gamma-enabled mode, rather than having
    flaky logic for switching modes.  Also, it should clear up issues with the LUTs
    being uninitialized when outputs are first brought up.

diff --git a/src/i830.h b/src/i830.h
index c2670cd..d5ca5d4 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -194,7 +194,8 @@ extern const char *i830_output_type_name
 
 typedef struct _I830CrtcPrivateRec {
     int			    pipe;
-    Bool		    gammaEnabled;
+    /* Lookup table values to be set when the CRTC is enabled */
+    CARD8 lut_r[256], lut_g[256], lut_b[256];
 } I830CrtcPrivateRec, *I830CrtcPrivatePtr;
 
 #define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
@@ -221,7 +222,6 @@ enum last_3d {
 
 typedef struct _I830PipeRec {
    Bool		  enabled;
-   Bool		  gammaEnabled;
    int		  x;
    int		  y;
    Bool		  cursorInRange;
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index cb1585f..81cb3bd 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -130,9 +130,7 @@ I830SetPipeCursor (xf86CrtcPtr crtc, Boo
 	    temp = INREG(cursor_control);
 	    temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
 	    if (pI830->CursorIsARGB) {
-		temp |= CURSOR_MODE_64_ARGB_AX;
-		if (intel_crtc->gammaEnabled)
-		    temp |= MCURSOR_GAMMA_ENABLE;
+		temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 	    } else
 		temp |= CURSOR_MODE_64_4C_AX;
 	    
@@ -144,9 +142,7 @@ I830SetPipeCursor (xf86CrtcPtr crtc, Boo
 	    temp &= ~(CURSOR_FORMAT_MASK);
 	    temp |= CURSOR_ENABLE;
 	    if (pI830->CursorIsARGB) {
-		temp |= CURSOR_FORMAT_ARGB;
-		if (intel_crtc->gammaEnabled)
-		    temp |= CURSOR_GAMMA_ENABLE;
+		temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
 	    } else
 		temp |= CURSOR_FORMAT_3C;
 	    OUTREG(CURSOR_CONTROL, temp);
diff --git a/src/i830_display.c b/src/i830_display.c
index d124ba0..f47a9db 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -536,6 +536,8 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mod
 	    OUTREG(dspbase_reg, INREG(dspbase_reg));
 	}
 
+	i830_crtc_load_lut(crtc);
+
 	/* Give the overlay scaler a chance to enable if it's on this pipe */
 	i830_crtc_dpms_video(crtc, TRUE);
 	break;
@@ -718,10 +720,10 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	dpll |= PLL_REF_INPUT_DREFCLK;
 
     /* Set up the display plane register */
-    dspcntr = 0;
+    dspcntr = DISPPLANE_GAMMA_ENABLE;
     switch (pScrn->bitsPerPixel) {
     case 8:
-	dspcntr |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE;
+	dspcntr |= DISPPLANE_8BPP;
 	break;
     case 16:
 	if (pScrn->depth == 15)
@@ -736,10 +738,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	FatalError("unknown display bpp\n");
     }
 
-    if (intel_crtc->gammaEnabled) {
- 	dspcntr |= DISPPLANE_GAMMA_ENABLE;
-    }
-
     if (pipe == 0)
 	dspcntr |= DISPPLANE_SEL_PIPE_A;
     else
@@ -840,6 +838,48 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     i830WaitForVblank(pScrn);
 }
 
+
+/** Loads the palette/gamma unit for the CRTC with the prepared values */
+void
+i830_crtc_load_lut(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+    int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B;
+    int i;
+
+    /* The clocks have to be on to load the palette. */
+    if (!crtc->enabled)
+	return;
+
+    for (i = 0; i < 256; i++) {
+	OUTREG(palreg + 4 * i,
+	       (intel_crtc->lut_r[i] << 16) |
+	       (intel_crtc->lut_g[i] << 8) |
+	       intel_crtc->lut_b[i]);
+    }
+}
+
+/** Sets the color ramps on behalf of RandR */
+static void
+i830_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
+		    int size)
+{
+    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+    int i;
+
+    assert(size == 256);
+
+    for (i = 0; i < 256; i++) {
+	intel_crtc->lut_r[i] = red[i] >> 8;
+	intel_crtc->lut_g[i] = green[i] >> 8;
+	intel_crtc->lut_b[i] = blue[i] >> 8;
+    }
+
+    i830_crtc_load_lut(crtc);
+}
+
 /**
  * Sets the given video mode on the given pipe.
  *
@@ -1147,6 +1187,7 @@ static const xf86CrtcFuncsRec i830_crtc_
     .restore = NULL, /* XXX */
     .mode_fixup = i830_crtc_mode_fixup,
     .mode_set = i830_crtc_mode_set,
+    .gamma_set = i830_crtc_gamma_set,
     .destroy = NULL, /* XXX */
 };
 
@@ -1155,6 +1196,7 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pi
 {
     xf86CrtcPtr crtc;
     I830CrtcPrivatePtr intel_crtc;
+    int i;
 
     crtc = xf86CrtcCreate (pScrn, &i830_crtc_funcs);
     if (crtc == NULL)
@@ -1163,6 +1205,12 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pi
     intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
     intel_crtc->pipe = pipe;
 
+    /* Initialize the LUTs for when we turn on the CRTC. */
+    for (i = 0; i < 256; i++) {
+	intel_crtc->lut_r[i] = i;
+	intel_crtc->lut_g[i] = i;
+	intel_crtc->lut_b[i] = i;
+    }
     crtc->driver_private = intel_crtc;
 }
 
diff --git a/src/i830_display.h b/src/i830_display.h
index 5517d27..66ab17e 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -42,3 +42,4 @@ xf86CrtcPtr i830GetLoadDetectPipe(xf86Ou
 void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
 Bool i830PipeInUse(xf86CrtcPtr crtc);
 void i830_crtc_init(ScrnInfoPtr pScrn, int pipe);
+void i830_crtc_load_lut(xf86CrtcPtr crtc);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 694c96f..94cba05 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -579,106 +579,67 @@ I830LoadPalette(ScrnInfoPtr pScrn, int n
 		LOCO * colors, VisualPtr pVisual)
 {
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-   I830Ptr pI830;
    int i,j, index;
-   unsigned char r, g, b;
-   CARD32 val, temp;
-   int palreg;
-   int dspreg, dspbase, dspsurf;
    int p;
+   CARD16 lut_r[256], lut_g[256], lut_b[256];
 
    DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
-   pI830 = I830PTR(pScrn);
 
-   for(p=0; p < xf86_config->num_crtc; p++) 
-   {
+   for(p = 0; p < xf86_config->num_crtc; p++) {
       xf86CrtcPtr	   crtc = xf86_config->crtc[p];
       I830CrtcPrivatePtr   intel_crtc = crtc->driver_private;
 
-      if (p == 0) {
-         palreg = PALETTE_A;
-         dspreg = DSPACNTR;
-         dspbase = DSPABASE;
-	 dspsurf = DSPASURF;
-      } else {
-         palreg = PALETTE_B;
-         dspreg = DSPBCNTR;
-         dspbase = DSPBBASE;
-	 dspsurf = DSPBSURF;
+      /* Initialize to the old lookup table values. */
+      for (i = 0; i < 256; i++) {
+	 lut_r[i] = intel_crtc->lut_r[i] << 8;
+	 lut_g[i] = intel_crtc->lut_g[i] << 8;
+	 lut_b[i] = intel_crtc->lut_b[i] << 8;
       }
 
-      if (crtc->enabled == 0)
-	 continue;  
-
-      intel_crtc->gammaEnabled = 1;
-      
-      /* To ensure gamma is enabled we need to turn off and on the plane */
-      temp = INREG(dspreg);
-      OUTREG(dspreg, temp & ~(1<<31));
-      OUTREG(dspbase, INREG(dspbase));
-      OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE);
-      OUTREG(dspbase, INREG(dspbase));
-      if (IS_I965G(pI830))
-	 OUTREG(dspsurf, INREG(dspsurf));
-
-      /* It seems that an initial read is needed. */
-      temp = INREG(palreg);
-
       switch(pScrn->depth) {
       case 15:
-        for (i = 0; i < numColors; i++) {
-         index = indices[i];
-         r = colors[index].red;
-         g = colors[index].green;
-         b = colors[index].blue;
-	 val = (r << 16) | (g << 8) | b;
-         for (j = 0; j < 8; j++) {
-	    OUTREG(palreg + index * 32 + (j * 4), val);
+	 for (i = 0; i < numColors; i++) {
+	    index = indices[i];
+	    for (j = 0; j < 8; j++) {
+	       lut_r[index * 8 + j] = colors[index].red << 8;
+	       lut_g[index * 8 + j] = colors[index].green << 8;
+	       lut_b[index * 8 + j] = colors[index].blue << 8;
+	    }
          }
-        }
-      break;
+	 break;
       case 16:
-        for (i = 0; i < numColors; i++) {
-         index = indices[i];
-	 r   = colors[index / 2].red;
-	 g   = colors[index].green;
-	 b   = colors[index / 2].blue;
-
-	 val = (r << 16) | (g << 8) | b;
-	 OUTREG(palreg + index * 16, val);
-	 OUTREG(palreg + index * 16 + 4, val);
-	 OUTREG(palreg + index * 16 + 8, val);
-	 OUTREG(palreg + index * 16 + 12, val);
-
-   	 if (index <= 31) {
-            r   = colors[index].red;
-	    g   = colors[(index * 2) + 1].green;
-	    b   = colors[index].blue;
-
-	    val = (r << 16) | (g << 8) | b;
-	    OUTREG(palreg + index * 32, val);
-	    OUTREG(palreg + index * 32 + 4, val);
-	    OUTREG(palreg + index * 32 + 8, val);
-	    OUTREG(palreg + index * 32 + 12, val);
-	 }
-        }
+	 for (i = 0; i < numColors; i++) {
+	    index = indices[i];
+
+	    if (i <= 31) {
+	       for (j = 0; j < 8; j++) {
+		  lut_r[index * 8 + j] = colors[index].red << 8;
+		  lut_b[index * 8 + j] = colors[index].blue << 8;
+	       }
+	    }
+
+	    for (j = 0; j < 4; j++) {
+	       lut_g[index * 4 + j] = colors[index].green << 8;
+	    }
+         }
         break;
       default:
-        for(i = 0; i < numColors; i++) {
-	 index = indices[i];
-	 r = colors[index].red;
-	 g = colors[index].green;
-	 b = colors[index].blue;
-	 val = (r << 16) | (g << 8) | b;
-	 OUTREG(palreg + index * 4, val);
-        }
-        break;
-     }
+	 for (i = 0; i < numColors; i++) {
+	    index = indices[i];
+	    lut_r[index] = colors[index].red << 8;
+	    lut_g[index] = colors[index].green << 8;
+	    lut_b[index] = colors[index].blue << 8;
+	 }
+	 break;
+      }
+
+      /* Make the change through RandR */
+#ifdef RANDR_12_INTERFACE
+      RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
+#else
+      crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
+#endif
    }
-   
-   /* Enable gamma for Cursor if ARGB */
-   if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn)
-      pI830->CursorInfoRec->ShowCursor(pScrn);
 }
 
 int
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 83cf023..533322b 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -663,9 +663,17 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 
 static Bool
 xf86RandR12CrtcSetGamma (ScreenPtr    pScreen,
-		       RRCrtcPtr    crtc)
+			 RRCrtcPtr    randr_crtc)
 {
-    return FALSE;
+    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
+
+    if (crtc->funcs->gamma_set == NULL)
+	return FALSE;
+
+    crtc->funcs->gamma_set(crtc, randr_crtc->gammaRed, randr_crtc->gammaGreen,
+			   randr_crtc->gammaBlue, randr_crtc->gammaSize);
+
+    return TRUE;
 }
 
 /**
diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h
index 2555c55..8fea162 100644
--- a/src/i830_xf86Crtc.h
+++ b/src/i830_xf86Crtc.h
@@ -89,6 +89,11 @@ typedef struct _xf86CrtcFuncs {
 		DisplayModePtr mode,
 		DisplayModePtr adjusted_mode);
 
+    /* Set the color ramps for the CRTC to the given values. */
+    void
+    (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
+		 int size);
+
     /**
      * Clean up driver-specific bits of the crtc
      */



More information about the xorg-commit mailing list