kolibrios/drivers/old/radeonhd/rhd_lut.c

305 lines
8.2 KiB
C
Raw Normal View History

/*
* 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);
}