0,0 → 1,304 |
/* |
* Copyright 2007-2008 Luc Verhaegen <lverhaegen@novell.com> |
* Copyright 2007-2008 Matthias Hopf <mhopf@novell.com> |
* Copyright 2007-2008 Egbert Eich <eich@novell.com> |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
* OTHER DEALINGS IN THE SOFTWARE. |
*/ |
|
#ifdef HAVE_CONFIG_H |
#include "config.h" |
#endif |
|
#include "xf86.h" |
|
#include "rhd.h" |
#include "rhd_lut.h" |
#include "rhd_regs.h" |
|
#define RHD_REGOFFSET_LUTA 0x000 |
#define RHD_REGOFFSET_LUTB 0x800 |
|
/* |
* |
*/ |
static void |
LUTxSave(struct rhdLUT *LUT) |
{ |
CARD16 RegOff; |
int i; |
RHDFUNC(LUT); |
|
if (LUT->Id == RHD_LUT_A) |
RegOff = RHD_REGOFFSET_LUTA; |
else |
RegOff = RHD_REGOFFSET_LUTB; |
|
LUT->StoreControl = RHDRegRead(LUT, RegOff + DC_LUTA_CONTROL); |
|
LUT->StoreBlackBlue = RHDRegRead(LUT, RegOff + DC_LUTA_BLACK_OFFSET_BLUE); |
LUT->StoreBlackGreen = RHDRegRead(LUT, RegOff + DC_LUTA_BLACK_OFFSET_GREEN); |
LUT->StoreBlackRed = RHDRegRead(LUT, RegOff + DC_LUTA_BLACK_OFFSET_RED); |
|
LUT->StoreWhiteBlue = RHDRegRead(LUT, RegOff + DC_LUTA_WHITE_OFFSET_BLUE); |
LUT->StoreWhiteGreen = RHDRegRead(LUT, RegOff + DC_LUTA_WHITE_OFFSET_GREEN); |
LUT->StoreWhiteRed = RHDRegRead(LUT, RegOff + DC_LUTA_WHITE_OFFSET_RED); |
|
RHDRegWrite(LUT, DC_LUT_RW_MODE, 0); /* Table */ |
if (LUT->Id == RHD_LUT_A) |
RHDRegWrite(LUT, DC_LUT_READ_PIPE_SELECT, 0); |
else |
RHDRegWrite(LUT, DC_LUT_READ_PIPE_SELECT, 1); |
|
RHDRegWrite(LUT, DC_LUT_RW_INDEX, 0); |
for (i = 0; i < 0x300; i++) |
LUT->StoreEntry[i] = RHDRegRead(LUT, DC_LUT_SEQ_COLOR); |
|
LUT->Stored = TRUE; |
} |
|
/* |
* |
*/ |
static void |
LUTxRestore(struct rhdLUT *LUT) |
{ |
CARD16 RegOff; |
int i; |
RHDFUNC(LUT); |
|
if (!LUT->Stored) { |
xf86DrvMsg(LUT->scrnIndex, X_ERROR, "%s: %s: nothing stored!\n", |
__func__, LUT->Name); |
return; |
} |
|
if (LUT->Id == RHD_LUT_A) |
RegOff = RHD_REGOFFSET_LUTA; |
else |
RegOff = RHD_REGOFFSET_LUTB; |
|
RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_BLUE, LUT->StoreBlackBlue); |
RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_GREEN, LUT->StoreBlackGreen); |
RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_RED, LUT->StoreBlackRed); |
|
RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_BLUE, LUT->StoreWhiteBlue); |
RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_GREEN, LUT->StoreWhiteGreen); |
RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_RED, LUT->StoreWhiteRed); |
|
if (LUT->Id == RHD_LUT_A) |
RHDRegWrite(LUT, DC_LUT_RW_SELECT, 0); |
else |
RHDRegWrite(LUT, DC_LUT_RW_SELECT, 1); |
|
RHDRegWrite(LUT, DC_LUT_RW_MODE, 0); /* Table */ |
RHDRegWrite(LUT, DC_LUT_WRITE_EN_MASK, 0x0000003F); |
RHDRegWrite(LUT, DC_LUT_RW_INDEX, 0); |
for (i = 0; i < 0x300; i++) |
RHDRegWrite(LUT, DC_LUT_SEQ_COLOR, LUT->StoreEntry[i]); |
|
RHDRegWrite(LUT, RegOff + DC_LUTA_CONTROL, LUT->StoreControl); |
} |
|
/* |
* |
*/ |
static void |
LUTxSet(struct rhdLUT *LUT, int numColors, int *indices, LOCO *colors) |
{ |
//ScrnInfoPtr pScrn = xf86Screens[LUT->scrnIndex]; |
CARD16 RegOff; |
int i, index; |
|
LUT->Initialised = TRUE; /* thank you RandR */ |
|
if (LUT->Id == RHD_LUT_A) |
RegOff = RHD_REGOFFSET_LUTA; |
else |
RegOff = RHD_REGOFFSET_LUTB; |
|
RHDRegWrite(LUT, RegOff + DC_LUTA_CONTROL, 0); |
|
RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_BLUE, 0); |
RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_GREEN, 0); |
RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_RED, 0); |
|
RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_BLUE, 0x0000FFFF); |
RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_GREEN, 0x0000FFFF); |
RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_RED, 0x0000FFFF); |
|
if (LUT->Id == RHD_LUT_A) |
RHDRegWrite(LUT, DC_LUT_RW_SELECT, 0); |
else |
RHDRegWrite(LUT, DC_LUT_RW_SELECT, 1); |
|
RHDRegWrite(LUT, DC_LUT_RW_MODE, 0); /* table */ |
RHDRegWrite(LUT, DC_LUT_WRITE_EN_MASK, 0x0000003F); |
|
int depth = 32; |
|
switch (depth) { |
case 8: |
case 24: |
case 32: |
for (i = 0; i < numColors; i++) { |
index = indices[i]; |
RHDRegWrite(LUT, DC_LUT_RW_INDEX, index); |
RHDRegWrite(LUT, DC_LUT_30_COLOR, (colors[index].red << 22) | |
(colors[index].green << 12) | (colors[index].blue << 2)); |
} |
break; |
case 16: |
for (i = 0; i < numColors; i++) { |
int j; |
|
index = indices[i]; |
RHDRegWrite(LUT, DC_LUT_RW_INDEX, 4 * index); |
|
for (j = 0; j < 4; j++) |
RHDRegWrite(LUT, DC_LUT_30_COLOR, (colors[index/2].red << 24) | |
(colors[index].green << 14) | (colors[index/2].blue << 4)); |
} |
break; |
case 15: |
for (i = 0; i < numColors; i++) { |
int j; |
|
index = indices[i]; |
RHDRegWrite(LUT, DC_LUT_RW_INDEX, 8 * index); |
|
for (j = 0; j < 8; j++) |
RHDRegWrite(LUT, DC_LUT_30_COLOR, (colors[index].red << 25) | |
(colors[index].green << 15) | (colors[index].blue << 5)); |
} |
break; |
} |
} |
|
/* |
* |
*/ |
void |
RHDLUTsInit(RHDPtr rhdPtr) |
{ |
struct rhdLUT *LUT; |
|
RHDFUNC(rhdPtr); |
|
LUT = xnfcalloc(sizeof(struct rhdLUT), 1); |
|
LUT->scrnIndex = rhdPtr->scrnIndex; |
LUT->Name = "LUT A"; |
LUT->Id = RHD_LUT_A; |
|
LUT->Save = LUTxSave; |
LUT->Restore = LUTxRestore; |
LUT->Set = LUTxSet; |
|
rhdPtr->LUT[0] = LUT; |
|
LUT = xnfcalloc(sizeof(struct rhdLUT), 1); |
|
LUT->scrnIndex = rhdPtr->scrnIndex; |
LUT->Name = "LUT B"; |
LUT->Id = RHD_LUT_B; |
|
LUT->Save = LUTxSave; |
LUT->Restore = LUTxRestore; |
LUT->Set = LUTxSet; |
|
rhdPtr->LUT[1] = LUT; |
} |
|
/* |
* |
*/ |
struct rhdLUTStore { |
CARD32 Select; |
CARD32 Mode; |
CARD32 Index; |
CARD32 Color; |
CARD32 ReadPipe; |
CARD32 WriteMask; |
}; |
|
/* |
* |
*/ |
void |
RHDLUTsSave(RHDPtr rhdPtr) |
{ |
struct rhdLUTStore *Store = rhdPtr->LUTStore; |
|
RHDFUNC(rhdPtr); |
|
if (!Store) { |
Store = xnfcalloc(sizeof(struct rhdLUTStore), 1); |
rhdPtr->LUTStore = Store; |
} |
|
Store->Select = _RHDRegRead(rhdPtr, DC_LUT_RW_SELECT); |
Store->Mode = _RHDRegRead(rhdPtr, DC_LUT_RW_MODE); |
Store->Index = _RHDRegRead(rhdPtr, DC_LUT_RW_INDEX); |
Store->Color = _RHDRegRead(rhdPtr, DC_LUT_30_COLOR); |
Store->ReadPipe = _RHDRegRead(rhdPtr, DC_LUT_READ_PIPE_SELECT); |
Store->WriteMask = _RHDRegRead(rhdPtr, DC_LUT_WRITE_EN_MASK); |
|
rhdPtr->LUT[0]->Save(rhdPtr->LUT[0]); |
rhdPtr->LUT[1]->Save(rhdPtr->LUT[1]); |
} |
|
/* |
* |
*/ |
void |
RHDLUTsRestore(RHDPtr rhdPtr) |
{ |
struct rhdLUTStore *Store = rhdPtr->LUTStore; |
|
RHDFUNC(rhdPtr); |
|
rhdPtr->LUT[0]->Restore(rhdPtr->LUT[0]); |
rhdPtr->LUT[1]->Restore(rhdPtr->LUT[1]); |
|
if (!Store) { |
xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: nothing stored!\n", __func__); |
return; |
} |
|
_RHDRegWrite(rhdPtr, DC_LUT_RW_SELECT, Store->Select); |
_RHDRegWrite(rhdPtr, DC_LUT_RW_MODE, Store->Mode); |
_RHDRegWrite(rhdPtr, DC_LUT_RW_INDEX, Store->Index); |
_RHDRegWrite(rhdPtr, DC_LUT_30_COLOR, Store->Color); |
_RHDRegWrite(rhdPtr, DC_LUT_READ_PIPE_SELECT, Store->ReadPipe); |
_RHDRegWrite(rhdPtr, DC_LUT_WRITE_EN_MASK, Store->WriteMask); |
} |
|
/* |
* |
*/ |
void |
RHDLUTsDestroy(RHDPtr rhdPtr) |
{ |
RHDFUNC(rhdPtr); |
|
xfree(rhdPtr->LUT[0]); |
xfree(rhdPtr->LUT[1]); |
xfree(rhdPtr->LUTStore); |
} |