summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/i830.h4
-rw-r--r--src/i830_cursor.c8
-rw-r--r--src/i830_display.c60
-rw-r--r--src/i830_display.h1
-rw-r--r--src/i830_driver.c127
-rw-r--r--src/i830_randr.c12
-rw-r--r--src/i830_xf86Crtc.h5
7 files changed, 118 insertions, 99 deletions
diff --git a/src/i830.h b/src/i830.h
index c2670cda..d5ca5d4b 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -194,7 +194,8 @@ extern const char *i830_output_type_names[];
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 cb1585fb..81cb3bd8 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -130,9 +130,7 @@ I830SetPipeCursor (xf86CrtcPtr crtc, Bool force)
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, Bool force)
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 d124ba0a..f47a9dbf 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -536,6 +536,8 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
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, DisplayModePtr mode,
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, DisplayModePtr mode,
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, DisplayModePtr mode,
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_funcs = {
.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 pipe)
{
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 pipe)
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 5517d27c..66ab17e8 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -42,3 +42,4 @@ xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
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 694c96f3..94cba05d 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -579,106 +579,67 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
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 83cf0238..533322b2 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 2555c55d..8fea162e 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
*/