diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/i830.h | 4 | ||||
-rw-r--r-- | src/i830_cursor.c | 8 | ||||
-rw-r--r-- | src/i830_display.c | 60 | ||||
-rw-r--r-- | src/i830_display.h | 1 | ||||
-rw-r--r-- | src/i830_driver.c | 127 | ||||
-rw-r--r-- | src/i830_randr.c | 12 | ||||
-rw-r--r-- | src/i830_xf86Crtc.h | 5 |
7 files changed, 118 insertions, 99 deletions
@@ -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 */ |