#include "ati.h"
#include "atiadapter.h"
#include "atichip.h"
#include "atimono.h"
#include "atistruct.h"
#include "ativga.h"
#include "ativgaio.h"
#ifndef DPMS_SERVER
# define DPMS_SERVER
#endif
#include "extensions/dpms.h"
#ifndef AVOID_CPIO
void
ATIVGAPreInit
(
ATIPtr pATI,
ATIHWPtr pATIHW
)
{
int Index;
pATIHW->seq[0] = 0x03U;
if (pATI->depth == 1)
pATIHW->seq[2] = 0x01U << BIT_PLANE;
else
pATIHW->seq[2] = 0x0FU;
if (pATI->depth <= 4)
pATIHW->seq[4] = 0x06U;
else if (pATI->Adapter == ATI_ADAPTER_VGA)
pATIHW->seq[4] = 0x0EU;
else
pATIHW->seq[4] = 0x0AU;
if ((pATI->depth >= 8) &&
((pATI->Chip >= ATI_CHIP_264CT) ||
(pATI->CPIO_VGAWonder &&
(pATI->Chip <= ATI_CHIP_18800_1) &&
(pATI->VideoRAM == 256))))
pATIHW->crt[19] = pATI->displayWidth >> 3;
else
pATIHW->crt[19] = pATI->displayWidth >> 4;
if ((pATI->depth >= 8) && (pATI->Adapter == ATI_ADAPTER_VGA))
pATIHW->crt[23] = 0xC3U;
else
pATIHW->crt[23] = 0xE3U;
pATIHW->crt[24] = 0xFFU;
if (pATI->depth == 1)
{
Bool FlipPixels = xf86GetFlipPixels();
for (Index = 0; Index < 16; Index++)
if (((Index & (0x01U << BIT_PLANE)) != 0) != FlipPixels)
pATIHW->attr[Index] = MONO_WHITE;
else
pATIHW->attr[Index] = MONO_BLACK;
pATIHW->attr[16] = 0x01U;
pATIHW->attr[17] = MONO_OVERSCAN;
}
else
{
for (Index = 0; Index < 16; Index++)
pATIHW->attr[Index] = Index;
if (pATI->depth <= 4)
pATIHW->attr[16] = 0x81U;
else if (pATI->Adapter == ATI_ADAPTER_VGA)
pATIHW->attr[16] = 0x41U;
else
pATIHW->attr[16] = 0x01U;
pATIHW->attr[17] = 0xFFU;
}
pATIHW->attr[18] = 0x0FU;
if (pATI->depth == 1)
pATIHW->gra[4] = BIT_PLANE;
else if (pATI->depth <= 4)
pATIHW->gra[5] = 0x02U;
else if (pATI->Chip >= ATI_CHIP_264CT)
pATIHW->gra[5] = 0x40U;
if (pATI->UseSmallApertures && (pATI->Chip >= ATI_CHIP_264CT) &&
((pATI->Chip >= ATI_CHIP_264VT) || !pATI->LinearBase))
pATIHW->gra[6] = 0x01U;
else
pATIHW->gra[6] = 0x05U;
pATIHW->gra[7] = 0x0FU;
pATIHW->gra[8] = 0xFFU;
}
void
ATIVGASave
(
ATIPtr pATI,
ATIHWPtr pATIHW
)
{
int Index;
pATIHW->genmo = inb(R_GENMO);
ATISetVGAIOBase(pATI, pATIHW->genmo);
for (Index = 0; Index < NumberOf(pATIHW->seq); Index++)
pATIHW->seq[Index] = GetReg(SEQX, Index);
for (Index = 0; Index < NumberOf(pATIHW->crt); Index++)
pATIHW->crt[Index] = GetReg(CRTX(pATI->CPIO_VGABase), Index);
for (Index = 0; Index < NumberOf(pATIHW->attr); Index++)
{
(void)inb(GENS1(pATI->CPIO_VGABase));
pATIHW->attr[Index] = GetReg(ATTRX, Index);
}
for (Index = 0; Index < NumberOf(pATIHW->gra); Index++)
pATIHW->gra[Index] = GetReg(GRAX, Index);
}
void
ATIVGACalculate
(
ATIPtr pATI,
ATIHWPtr pATIHW,
DisplayModePtr pMode
)
{
int Index, VDisplay;
if (!pMode->CrtcHAdjusted)
{
pMode->CrtcHAdjusted = TRUE;
pMode->CrtcHDisplay = (pMode->HDisplay >> 3) - 1;
pMode->CrtcHBlankStart = (pMode->HDisplay >> 3);
if ((pATI->Chip == ATI_CHIP_18800_1) ||
(pATI->Chip >= ATI_CHIP_264CT))
pMode->CrtcHBlankStart--;
pMode->CrtcHSyncStart = pMode->HSyncStart >> 3;
pMode->CrtcHSyncEnd = pMode->HSyncEnd >> 3;
pMode->CrtcHBlankEnd = (pMode->HTotal >> 3) - 1;
pMode->CrtcHTotal = (pMode->HTotal >> 3) - 5;
pMode->CrtcHSkew = pMode->HSkew;
Index = pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart - 0x1F;
if (Index > 0)
{
pMode->CrtcHSyncStart += Index / 2;
pMode->CrtcHSyncEnd = pMode->CrtcHSyncStart + 0x1F;
}
Index = pMode->CrtcHBlankEnd - pMode->CrtcHBlankStart - 0x3F;
if (Index > 0)
{
if ((pMode->CrtcHBlankEnd - Index) > pMode->CrtcHSyncEnd)
{
pMode->CrtcHBlankStart += Index / 2;
if (pMode->CrtcHBlankStart >= pMode->CrtcHSyncStart)
pMode->CrtcHBlankStart = pMode->CrtcHSyncStart - 1;
pMode->CrtcHBlankEnd = pMode->CrtcHBlankStart + 0x3F;
}
else
{
Index -= 0x40;
if (Index > 0)
{
pMode->CrtcHBlankStart += Index / 2;
if (pMode->CrtcHBlankStart >= pMode->CrtcHSyncStart)
pMode->CrtcHBlankStart = pMode->CrtcHSyncStart - 1;
pMode->CrtcHBlankEnd = pMode->CrtcHBlankStart + 0x7F;
}
}
}
}
pMode->CrtcVDisplay = pMode->VDisplay;
pMode->CrtcVBlankStart = pMode->VDisplay;
pMode->CrtcVSyncStart = pMode->VSyncStart;
pMode->CrtcVSyncEnd = pMode->VSyncEnd;
pMode->CrtcVBlankEnd = pMode->VTotal;
pMode->CrtcVTotal = pMode->VTotal;
if (pMode->Flags & V_DBLSCAN)
{
pMode->CrtcVDisplay <<= 1;
pMode->CrtcVBlankStart <<= 1;
pMode->CrtcVSyncStart <<= 1;
pMode->CrtcVSyncEnd <<= 1;
pMode->CrtcVBlankEnd <<= 1;
pMode->CrtcVTotal <<= 1;
}
if (pMode->VScan > 1)
{
pMode->CrtcVDisplay *= pMode->VScan;
pMode->CrtcVBlankStart *= pMode->VScan;
pMode->CrtcVSyncStart *= pMode->VScan;
pMode->CrtcVSyncEnd *= pMode->VScan;
pMode->CrtcVBlankEnd *= pMode->VScan;
pMode->CrtcVTotal *= pMode->VScan;
}
pATIHW->genmo = 0x23U;
if ((pMode->Flags & (V_PHSYNC | V_NHSYNC)) &&
(pMode->Flags & (V_PVSYNC | V_NVSYNC)))
{
if (pMode->Flags & V_NHSYNC)
pATIHW->genmo |= 0x40U;
if (pMode->Flags & V_NVSYNC)
pATIHW->genmo |= 0x80U;
}
else
{
pMode->Flags &= ~(V_PHSYNC | V_NHSYNC | V_PVSYNC | V_NVSYNC);
if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
VDisplay = pATI->LCDVertical;
else
VDisplay = pMode->CrtcVDisplay;
if (VDisplay < 400)
{
pMode->Flags |= V_PHSYNC | V_NVSYNC;
pATIHW->genmo |= 0x80U;
}
else if (VDisplay < 480)
{
pMode->Flags |= V_NHSYNC | V_PVSYNC;
pATIHW->genmo |= 0x40U;
}
else if (VDisplay < 768)
{
pMode->Flags |= V_NHSYNC | V_NVSYNC;
pATIHW->genmo |= 0xC0U;
}
else
{
pMode->Flags |= V_PHSYNC | V_PVSYNC;
}
}
if ((pMode->Flags & V_INTERLACE) && (pATI->Chip < ATI_CHIP_264CT))
{
pMode->CrtcVDisplay >>= 1;
pMode->CrtcVBlankStart >>= 1;
pMode->CrtcVSyncStart >>= 1;
pMode->CrtcVSyncEnd >>= 1;
pMode->CrtcVBlankEnd >>= 1;
pMode->CrtcVTotal >>= 1;
}
if (pMode->CrtcVTotal > 1024)
{
pATIHW->crt[23] |= 0x04U;
pMode->CrtcVDisplay >>= 1;
pMode->CrtcVBlankStart >>= 1;
pMode->CrtcVSyncStart >>= 1;
pMode->CrtcVSyncEnd >>= 1;
pMode->CrtcVBlankEnd >>= 1;
pMode->CrtcVTotal >>= 1;
}
else
{
pATIHW->crt[23] &= ~0x04U;
}
pMode->CrtcVDisplay--;
if (pATI->Chip == ATI_CHIP_18800)
pMode->CrtcVBlankStart++;
else
pMode->CrtcVBlankStart--;
pMode->CrtcVBlankEnd--;
if (pATI->Chip < ATI_CHIP_264CT)
pMode->CrtcVBlankEnd--;
pMode->CrtcVTotal -= 2;
pMode->CrtcVAdjusted = TRUE;
Index = pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart - 0x0F;
if (Index > 0)
{
pMode->CrtcVSyncStart += Index / 2;
pMode->CrtcVSyncEnd = pMode->CrtcVSyncStart + 0x0F;
}
Index = pMode->CrtcVBlankEnd - pMode->CrtcVBlankStart - 0x00FF;
if (Index > 0)
{
if ((pMode->CrtcVBlankEnd - Index) > pMode->CrtcVSyncEnd)
{
pMode->CrtcVBlankStart += Index / 2;
if (pMode->CrtcVBlankStart >= pMode->CrtcVSyncStart)
pMode->CrtcVBlankStart = pMode->CrtcVSyncStart - 1;
pMode->CrtcVBlankEnd = pMode->CrtcVBlankStart + 0x00FF;
}
else
{
Index -= 0x0100;
if (Index > 0)
{
pMode->CrtcVBlankStart += Index / 2;
if (pMode->CrtcVBlankStart >= pMode->CrtcVSyncStart)
pMode->CrtcVBlankStart = pMode->CrtcVSyncStart - 1;
pMode->CrtcVBlankEnd = pMode->CrtcVBlankStart + 0x01FF;
}
}
}
if (pMode->Flags & V_CLKDIV2)
pATIHW->seq[1] = 0x09U;
else
pATIHW->seq[1] = 0x01U;
pATIHW->crt[0] = pMode->CrtcHTotal;
pATIHW->crt[1] = pMode->CrtcHDisplay;
pATIHW->crt[2] = pMode->CrtcHBlankStart;
pATIHW->crt[3] = (pMode->CrtcHBlankEnd & 0x1FU) | 0x80U;
Index = ((pMode->CrtcHSkew << 2) + 0x10U) & ~0x1FU;
if (Index < 0x0080)
pATIHW->crt[3] |= Index;
pATIHW->crt[4] = pMode->CrtcHSyncStart;
pATIHW->crt[5] = ((pMode->CrtcHBlankEnd & 0x20U) << 2) |
((pMode->CrtcHSyncEnd & 0x1FU) );
pATIHW->crt[6] = pMode->CrtcVTotal & 0xFFU;
pATIHW->crt[7] = ((pMode->CrtcVTotal & 0x0100U) >> 8) |
((pMode->CrtcVDisplay & 0x0100U) >> 7) |
((pMode->CrtcVSyncStart & 0x0100U) >> 6) |
((pMode->CrtcVBlankStart & 0x0100U) >> 5) |
0x10U |
((pMode->CrtcVTotal & 0x0200U) >> 4) |
((pMode->CrtcVDisplay & 0x0200U) >> 3) |
((pMode->CrtcVSyncStart & 0x0200U) >> 2);
pATIHW->crt[9] = ((pMode->CrtcVBlankStart & 0x0200U) >> 4) | 0x40U;
if ((Index = pMode->VScan) <= 0)
Index = 1;
if (pMode->Flags & V_DBLSCAN)
Index <<= 1;
Index--;
pATIHW->crt[9] |= (Index & 0x1FU) | ((Index & 0x20U) << 2);
pATIHW->crt[16] = pMode->CrtcVSyncStart & 0xFFU;
pATIHW->crt[17] = (pMode->CrtcVSyncEnd & 0x0FU) | 0x20U;
pATIHW->crt[18] = pMode->CrtcVDisplay & 0xFFU;
pATIHW->crt[21] = pMode->CrtcVBlankStart & 0xFFU;
pATIHW->crt[22] = pMode->CrtcVBlankEnd & 0xFFU;
}
void
ATIVGASet
(
ATIPtr pATI,
ATIHWPtr pATIHW
)
{
int Index;
ATISetVGAIOBase(pATI, pATIHW->genmo);
outb(GENMO, pATIHW->genmo);
for (Index = NumberOf(pATIHW->seq); --Index >= 0; )
PutReg(SEQX, Index, pATIHW->seq[Index]);
for (Index = 0; Index < NumberOf(pATIHW->crt); Index++)
PutReg(CRTX(pATI->CPIO_VGABase), Index, pATIHW->crt[Index]);
for (Index = 0; Index < NumberOf(pATIHW->attr); Index++)
{
(void)inb(GENS1(pATI->CPIO_VGABase));
outb(ATTRX, Index);
outb(ATTRX, pATIHW->attr[Index]);
}
for (Index = 0; Index < NumberOf(pATIHW->gra); Index++)
PutReg(GRAX, Index, pATIHW->gra[Index]);
}
void
ATIVGASaveScreen
(
ATIPtr pATI,
int Mode
)
{
(void)inb(GENS1(pATI->CPIO_VGABase));
switch (Mode)
{
case SCREEN_SAVER_OFF:
case SCREEN_SAVER_FORCER:
outb(ATTRX, 0x20U);
break;
case SCREEN_SAVER_ON:
case SCREEN_SAVER_CYCLE:
outb(ATTRX, 0x00U);
break;
default:
break;
}
}
void
ATIVGASetDPMSMode
(
ATIPtr pATI,
int DPMSMode
)
{
CARD8 seq1, crt17;
switch (DPMSMode)
{
case DPMSModeOn:
seq1 = 0x00U;
crt17 = 0x80U;
break;
case DPMSModeStandby:
seq1 = 0x20U;
crt17 = 0x80U;
break;
case DPMSModeSuspend:
seq1 = 0x20U;
crt17 = 0x80U;
break;
case DPMSModeOff:
seq1 = 0x20U;
crt17 = 0x00U;
break;
default:
return;
}
PutReg(SEQX, 0x00U, 0x01U);
seq1 |= GetReg(SEQX, 0x01U) & ~0x20U;
PutReg(SEQX, 0x01U, seq1);
crt17 |= GetReg(CRTX(pATI->CPIO_VGABase), 0x17U) & ~0x80U;
usleep(10000);
PutReg(CRTX(pATI->CPIO_VGABase), 0x17U, crt17);
PutReg(SEQX, 0x01U, 0x03U);
}
#endif