blob: 81c0cc41bb42969ede42b29f38481c96fc299982 [file] [log] [blame]
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/types.h>
#include "XGIfb.h"
#include "vb_def.h"
#include "vgatypes.h"
#include "vb_struct.h"
#include "vb_init.h"
#include "vb_util.h"
#include "vb_table.h"
#include "vb_setmode.h"
#define IndexMask 0xff
static const unsigned short XGINew_MDA_DAC[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F};
static const unsigned short XGINew_CGA_DAC[] = {
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F};
static const unsigned short XGINew_EGA_DAC[] = {
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17,
0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37,
0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F};
static const unsigned short XGINew_VGA_DAC[] = {
0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
0x0B, 0x0C, 0x0D, 0x0F, 0x10};
void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
{
pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable;
pVBInfo->StandTable = (struct XGI_StandTableStruct *) XGI330_StandTable;
pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable;
pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex;
pVBInfo->XGINEWUB_CRT1Table
= (struct XGI_CRT1TableStruct *) XGI_CRT1Table;
/* add for new UNIVGABIOS */
/* XGINew_UBLCDDataTable =
* (struct XGI_LCDDataTablStruct *) XGI_LCDDataTable; */
/* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable; */
pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData;
pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData;
pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData;
pVBInfo->VBVCLKData = (struct XGI_VBVCLKDataStruct *) XGI_VBVCLKData;
pVBInfo->ScreenOffset = XGI330_ScreenOffset;
pVBInfo->StResInfo = (struct XGI_StResInfoStruct *) XGI330_StResInfo;
pVBInfo->ModeResInfo
= (struct XGI_ModeResInfoStruct *) XGI330_ModeResInfo;
pVBInfo->pOutputSelect = &XGI330_OutputSelect;
pVBInfo->pSoftSetting = &XGI330_SoftSetting;
pVBInfo->pSR07 = &XGI330_SR07;
pVBInfo->LCDResInfo = 0;
pVBInfo->LCDTypeInfo = 0;
pVBInfo->LCDInfo = 0;
pVBInfo->VBInfo = 0;
pVBInfo->TVInfo = 0;
pVBInfo->SR15 = XGI340_SR13;
pVBInfo->CR40 = XGI340_cr41;
pVBInfo->SR25 = XGI330_sr25;
pVBInfo->pSR31 = &XGI330_sr31;
pVBInfo->pSR32 = &XGI330_sr32;
pVBInfo->CR6B = XGI340_CR6B;
pVBInfo->CR6E = XGI340_CR6E;
pVBInfo->CR6F = XGI340_CR6F;
pVBInfo->CR89 = XGI340_CR89;
pVBInfo->AGPReg = XGI340_AGPReg;
pVBInfo->SR16 = XGI340_SR16;
pVBInfo->pCRCF = &XG40_CRCF;
pVBInfo->pXGINew_DRAMTypeDefinition = &XG40_DRAMTypeDefinition;
pVBInfo->CR49 = XGI330_CR49;
pVBInfo->pSR1F = &XGI330_SR1F;
pVBInfo->pSR21 = &XGI330_SR21;
pVBInfo->pSR22 = &XGI330_SR22;
pVBInfo->pSR23 = &XGI330_SR23;
pVBInfo->pSR24 = &XGI330_SR24;
pVBInfo->pSR33 = &XGI330_SR33;
pVBInfo->pCRT2Data_1_2 = &XGI330_CRT2Data_1_2;
pVBInfo->pCRT2Data_4_D = &XGI330_CRT2Data_4_D;
pVBInfo->pCRT2Data_4_E = &XGI330_CRT2Data_4_E;
pVBInfo->pCRT2Data_4_10 = &XGI330_CRT2Data_4_10;
pVBInfo->pRGBSenseData = &XGI330_RGBSenseData;
pVBInfo->pVideoSenseData = &XGI330_VideoSenseData;
pVBInfo->pYCSenseData = &XGI330_YCSenseData;
pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2;
pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2;
pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2;
pVBInfo->NTSCTiming = XGI330_NTSCTiming;
pVBInfo->PALTiming = XGI330_PALTiming;
pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming;
pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing;
pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing;
pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming;
pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming;
pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming;
pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming;
pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data;
pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu;
pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text;
pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3;
pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3;
pVBInfo->TimingH = (struct XGI_TimingHStruct *) XGI_TimingH;
pVBInfo->TimingV = (struct XGI_TimingVStruct *) XGI_TimingV;
pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table;
/* 310 customization related */
if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV))
pVBInfo->LCDCapList = XGI_LCDDLCapList;
else
pVBInfo->LCDCapList = XGI_LCDCapList;
if ((ChipType == XG21) || (ChipType == XG27))
pVBInfo->XG21_LVDSCapList = XGI21_LCDCapList;
pVBInfo->XGI_TVDelayList = XGI301TVDelayList;
pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2;
pVBInfo->pXGINew_I2CDefinition = &XG40_I2CDefinition;
if (ChipType >= XG20)
pVBInfo->pXGINew_CR97 = &XG20_CR97;
if (ChipType == XG27) {
pVBInfo->MCLKData
= (struct XGI_MCLKDataStruct *) XGI27New_MCLKData;
pVBInfo->CR40 = XGI27_cr41;
pVBInfo->pXGINew_CR97 = &XG27_CR97;
pVBInfo->pSR36 = &XG27_SR36;
pVBInfo->pCR8F = &XG27_CR8F;
pVBInfo->pCRD0 = XG27_CRD0;
pVBInfo->pCRDE = XG27_CRDE;
pVBInfo->pSR40 = &XG27_SR40;
pVBInfo->pSR41 = &XG27_SR41;
}
if (ChipType >= XG20) {
pVBInfo->pDVOSetting = &XG21_DVOSetting;
pVBInfo->pCR2E = &XG21_CR2E;
pVBInfo->pCR2F = &XG21_CR2F;
pVBInfo->pCR46 = &XG21_CR46;
pVBInfo->pCR47 = &XG21_CR47;
}
}
static unsigned char XGI_GetModePtr(unsigned short ModeNo,
unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo)
{
unsigned char index;
if (ModeNo <= 0x13)
index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex;
else {
if (pVBInfo->ModeType <= 0x02)
index = 0x1B; /* 02 -> ModeEGA */
else
index = 0x0F;
}
return index; /* Get pVBInfo->StandTable index */
}
static void XGI_SetSeqRegs(unsigned short ModeNo,
unsigned short StandTableIndex,
unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo)
{
unsigned char tempah, SRdata;
unsigned short i, modeflag;
if (ModeNo <= 0x13)
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
else
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
tempah = pVBInfo->StandTable[StandTableIndex].SR[0];
i = SetCRT2ToLCDA;
if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
tempah |= 0x01;
} else {
if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
if (pVBInfo->VBInfo & SetInSlaveMode)
tempah |= 0x01;
}
}
tempah |= 0x20; /* screen off */
xgifb_reg_set(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */
for (i = 02; i <= 04; i++) {
/* Get SR2,3,4 from file */
SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1];
xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
}
}
static void XGI_SetMiscRegs(unsigned short StandTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned char Miscdata;
/* Get Misc from file */
Miscdata = pVBInfo->StandTable[StandTableIndex].MISC;
/*
if (pVBInfo->VBType & (VB_XGI301B |
VB_XGI302B |
VB_XGI301LV |
VB_XGI302LV |
VB_XGI301C)) {
if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
Miscdata |= 0x0C;
}
}
*/
outb(Miscdata, pVBInfo->P3c2); /* Set Misc(3c2) */
}
static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
unsigned short StandTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned char CRTCdata;
unsigned short i;
CRTCdata = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
CRTCdata &= 0x7f;
xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
for (i = 0; i <= 0x18; i++) {
/* Get CRTC from file */
CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i];
xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
}
/*
if ((HwDeviceExtension->jChipType == XGI_630) &&
(HwDeviceExtension->jChipRevision == 0x30)) {
if (pVBInfo->VBInfo & SetInSlaveMode) {
if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
xgifb_reg_set(pVBInfo->P3d4, 0x18, 0xFE);
}
}
}
*/
}
static void XGI_SetATTRegs(unsigned short ModeNo,
unsigned short StandTableIndex,
unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo)
{
unsigned char ARdata;
unsigned short i, modeflag;
if (ModeNo <= 0x13)
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
else
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
for (i = 0; i <= 0x13; i++) {
ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
if (modeflag & Charx8Dot) { /* ifndef Dot9 */
if (i == 0x13) {
if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
ARdata = 0;
} else {
if (pVBInfo->VBInfo & (SetCRT2ToTV
| SetCRT2ToLCD)) {
if (pVBInfo->VBInfo &
SetInSlaveMode)
ARdata = 0;
}
}
}
}
inb(pVBInfo->P3da); /* reset 3da */
outb(i, pVBInfo->P3c0); /* set index */
outb(ARdata, pVBInfo->P3c0); /* set data */
}
inb(pVBInfo->P3da); /* reset 3da */
outb(0x14, pVBInfo->P3c0); /* set index */
outb(0x00, pVBInfo->P3c0); /* set data */
inb(pVBInfo->P3da); /* Enable Attribute */
outb(0x20, pVBInfo->P3c0);
}
static void XGI_SetGRCRegs(unsigned short StandTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned char GRdata;
unsigned short i;
for (i = 0; i <= 0x08; i++) {
/* Get GR from file */
GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i];
xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
}
if (pVBInfo->ModeType > ModeVGA) {
GRdata = (unsigned char) xgifb_reg_get(pVBInfo->P3ce, 0x05);
GRdata &= 0xBF; /* 256 color disable */
xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata);
}
}
static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
{
unsigned short i;
for (i = 0x0A; i <= 0x0E; i++)
xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
}
static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
{
xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B);
xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C);
xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B);
xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C);
xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30);
return 0;
}
static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex, unsigned short *i,
struct vb_device_info *pVBInfo)
{
unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
if (ModeNo <= 0x13)
/* si+St_ModeFlag */
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
else
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
tempax = 0;
if (pVBInfo->IF_DEF_LVDS == 0) {
if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
tempax |= SupportRAMDAC2;
if (pVBInfo->VBType & VB_XGI301C)
tempax |= SupportCRT2in301C;
}
/* 301b */
if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
tempax |= SupportLCD;
if (pVBInfo->LCDResInfo != Panel1280x1024) {
if (pVBInfo->LCDResInfo != Panel1280x960) {
if (pVBInfo->LCDInfo &
LCDNonExpanding) {
if (resinfo >= 9) {
tempax = 0;
return 0;
}
}
}
}
}
if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
if ((pVBInfo->VBType & VB_XGI301LV) &&
(pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
tempax |= SupportYPbPr;
if (pVBInfo->VBInfo & SetInSlaveMode) {
if (resinfo == 4)
return 0;
if (resinfo == 3)
return 0;
if (resinfo > 7)
return 0;
}
} else {
tempax |= SupportHiVisionTV;
if (pVBInfo->VBInfo & SetInSlaveMode) {
if (resinfo == 4)
return 0;
if (resinfo == 3) {
if (pVBInfo->SetFlag
& TVSimuMode)
return 0;
}
if (resinfo > 7)
return 0;
}
}
} else {
if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO |
SetCRT2ToSVIDEO |
SetCRT2ToSCART |
SetCRT2ToYPbPr |
SetCRT2ToHiVisionTV)) {
tempax |= SupportTV;
if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
| VB_XGI301LV | VB_XGI302LV
| VB_XGI301C)) {
tempax |= SupportTV1024;
}
if (!(pVBInfo->VBInfo & SetPALTV)) {
if (modeflag & NoSupportSimuTV) {
if (pVBInfo->VBInfo &
SetInSlaveMode) {
if (!(pVBInfo->VBInfo &
SetNotSimuMode)) {
return 0;
}
}
}
}
}
}
} else { /* for LVDS */
if (pVBInfo->VBInfo & SetCRT2ToLCD) {
tempax |= SupportLCD;
if (resinfo > 0x08)
return 0; /* 1024x768 */
if (pVBInfo->LCDResInfo < Panel1024x768) {
if (resinfo > 0x07)
return 0; /* 800x600 */
if (resinfo == 0x04)
return 0; /* 512x384 */
}
}
}
for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
tempbx; (*i)--) {
infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
Ext_InfoFlag;
if (infoflag & tempax)
return 1;
if ((*i) == 0)
break;
}
for ((*i) = 0;; (*i)++) {
infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
Ext_InfoFlag;
if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
!= tempbx) {
return 0;
}
if (infoflag & tempax)
return 1;
}
return 1;
}
static void XGI_SetSync(unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short sync, temp;
/* di+0x00 */
sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
sync &= 0xC0;
temp = 0x2F;
temp |= sync;
outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */
}
static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
struct xgi_hw_device_info *HwDeviceExtension)
{
unsigned char data, data1, pushax;
unsigned short i, j;
/* xgifb_reg_set(pVBInfo->P3d4, 0x51, 0); */
/* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */
/* xgifb_reg_and_or(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
/* unlock cr0-7 */
data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
data &= 0x7F;
xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
data = pVBInfo->TimingH[0].data[0];
xgifb_reg_set(pVBInfo->P3d4, 0, data);
for (i = 0x01; i <= 0x04; i++) {
data = pVBInfo->TimingH[0].data[i];
xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data);
}
for (i = 0x05; i <= 0x06; i++) {
data = pVBInfo->TimingH[0].data[i];
xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data);
}
j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e);
j &= 0x1F;
data = pVBInfo->TimingH[0].data[7];
data &= 0xE0;
data |= j;
xgifb_reg_set(pVBInfo->P3c4, 0x0e, data);
if (HwDeviceExtension->jChipType >= XG20) {
data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x04);
data = data - 1;
xgifb_reg_set(pVBInfo->P3d4, 0x04, data);
data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x05);
data1 = data;
data1 &= 0xE0;
data &= 0x1F;
if (data == 0) {
pushax = data;
data = (unsigned char) xgifb_reg_get(pVBInfo->P3c4,
0x0c);
data &= 0xFB;
xgifb_reg_set(pVBInfo->P3c4, 0x0c, data);
data = pushax;
}
data = data - 1;
data |= data1;
xgifb_reg_set(pVBInfo->P3d4, 0x05, data);
data = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e);
data = data >> 5;
data = data + 3;
if (data > 7)
data = data - 7;
data = data << 5;
xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data);
}
}
static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
unsigned short ModeNo,
struct vb_device_info *pVBInfo)
{
unsigned char data;
unsigned short i, j;
/* xgifb_reg_set(pVBInfo->P3d4, 0x51, 0); */
/* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */
/* xgifb_reg_and_or(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
for (i = 0x00; i <= 0x01; i++) {
data = pVBInfo->TimingV[0].data[i];
xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data);
}
for (i = 0x02; i <= 0x03; i++) {
data = pVBInfo->TimingV[0].data[i];
xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
}
for (i = 0x04; i <= 0x05; i++) {
data = pVBInfo->TimingV[0].data[i];
xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
}
j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0a);
j &= 0xC0;
data = pVBInfo->TimingV[0].data[6];
data &= 0x3F;
data |= j;
xgifb_reg_set(pVBInfo->P3c4, 0x0a, data);
data = pVBInfo->TimingV[0].data[6];
data &= 0x80;
data = data >> 2;
if (ModeNo <= 0x13)
i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
else
i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
i &= DoubleScanMode;
if (i)
data |= 0x80;
j = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x09);
j &= 0x5F;
data |= j;
xgifb_reg_set(pVBInfo->P3d4, 0x09, data);
}
static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo,
struct xgi_hw_device_info *HwDeviceExtension)
{
unsigned char index, data;
unsigned short i;
/* Get index */
index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
index = index & IndexMask;
data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
data &= 0x7F;
xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
for (i = 0; i < 8; i++)
pVBInfo->TimingH[0].data[i]
= pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
for (i = 0; i < 7; i++)
pVBInfo->TimingV[0].data[i]
= pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
if (pVBInfo->ModeType > 0x03)
xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F);
}
/* --------------------------------------------------------------------- */
/* Function : XGI_SetXG21CRTC */
/* Input : Stand or enhance CRTC table */
/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
/* Description : Set LCD timing */
/* --------------------------------------------------------------------- */
static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
unsigned short Temp1, Temp2, Temp3;
if (ModeNo <= 0x13) {
StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
/* CR04 HRS */
Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4];
/* SR2E [7:0]->HRS */
xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
/* Tempbx: CR05 HRE */
Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5];
Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
Tempcx = Tempax;
Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
Tempdx <<= 2; /* Tempdx << 2 */
/* SR2F [7:2]->HRE */
xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx);
xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
/* Tempax: CR16 VRS */
Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16];
Tempbx = Tempax; /* Tempbx=Tempax */
Tempax &= 0x01; /* Tempax: VRS[0] */
xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */
/* Tempax: CR7 VRS */
Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7];
Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */
Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */
Tempcx <<= 5; /* Tempcx[7]: VRS[8] */
Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */
/* SR34[7:0]: VRS[8:1] */
xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempdx);
/* Temp1[8]: VRS[8] unsigned char -> unsigned short */
Temp1 = Tempcx << 1;
Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
Tempax &= 0x80; /* Tempax[7]: CR7[7] */
Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
/* CR16 VRE */
Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17];
Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */
Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */
Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */
if (Tempax < Temp3) /* VRE[3:0]<VRS[3:0] */
Temp2 |= 0x10; /* Temp2: VRE + 0x10 */
Temp2 &= 0xFF; /* Temp2[7:0]: VRE[7:0] */
Tempax = (unsigned char) Temp2; /* Tempax[7:0]: VRE[7:0] */
Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
Temp1 >>= 9; /* [10:9]->[1:0] */
Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */
Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */
Tempax &= 0x7F;
/* SR3F D[7:2]->VRE D[1:0]->VRS */
xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
} else {
index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
/* Tempax: CR4 HRS */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
Tempcx = Tempax; /* Tempcx: HRS */
/* SR2E[7:0]->HRS */
xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
if (Tempax < Tempcx) /* HRE < HRS */
Temp2 |= 0x40; /* Temp2 + 0x40 */
Temp2 &= 0xFF;
Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
/* SR2F D[7:2]->HRE, D[1:0]->HRS */
xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
/* CR10 VRS */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
Tempbx = Tempax; /* Tempbx: VRS */
Tempax &= 0x01; /* Tempax[0]: VRS[0] */
xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
/* CR7[2][7] VRE */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
Temp1 <<= 1; /* Temp1[8]: VRS[8] */
Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
Tempax &= 0x80;
Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
/* Tempax: SRA */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
Tempax &= 0x08; /* Tempax[3]: VRS[3] */
Temp2 = Tempax;
Temp2 <<= 7; /* Temp2[10]: VRS[10] */
Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
/* Tempax: CR11 VRE */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
/* Tempbx: SRA */
Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
if (Tempax < Temp3) /* VRE < VRS */
Temp2 |= 0x20; /* VRE + 0x20 */
Temp2 &= 0xFF;
Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
Tempbx = (unsigned char) Temp1;
Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
Tempax &= 0x7F;
/* SR3F D[7:2]->VRE D[1:0]->VRS */
xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
}
}
static void XGI_SetXG27CRTC(unsigned short ModeNo,
unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
if (ModeNo <= 0x13) {
StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
/* CR04 HRS */
Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4];
/* SR2E [7:0]->HRS */
xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
/* Tempbx: CR05 HRE */
Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5];
Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
Tempcx = Tempax;
Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
Tempdx <<= 2; /* Tempdx << 2 */
/* SR2F [7:2]->HRE */
xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx);
xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
/* Tempax: CR10 VRS */
Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16];
xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */
Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */
/* Tempax[7][2]: CR7[7][2] VRS[9][8] */
Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7];
Tempbx = Tempax; /* Tempbx=CR07 */
Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */
Tempax >>= 2;
/* SR35 D[0]->VRS D[8] */
xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */
Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */
/* CR11 VRE */
Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17];
Tempax &= 0x0F; /* Tempax: VRE[3:0] */
Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */
Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */
Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */
if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */
Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */
/* Tempax[7:0]: VRE[7:0] */
Tempax = (unsigned char) Tempbx & 0xFF;
Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */
/* SR3F D[7:2]->VRE D[5:0] */
xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
/* SR35 D[2:1]->VRS[10:9] */
xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x06, Tempcx);
} else {
index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
/* Tempax: CR4 HRS */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
Tempbx = Tempax; /* Tempbx: HRS[7:0] */
/* SR2E[7:0]->HRS */
xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
/* SR0B */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5];
Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */
Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
Tempcx = Tempax; /* Tempcx: HRE[4:0] */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */
Tempax &= 0x04; /* Tempax[2]: HRE[5] */
Tempax <<= 3; /* Tempax[5]: HRE[5] */
Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
/* Tempax: CR4 HRS */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
Tempax &= 0x3F; /* Tempax: HRS[5:0] */
if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
/* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
/* CR10 VRS */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
/* SR34[7:0]->VRS[7:0] */
xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
/* CR7[7][2] VRS[9][8] */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
Tempax >>= 2; /* Tempax[0]: VRS[8] */
/* SR35[0]: VRS[8] */
xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
/* Tempax: SR0A */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
Tempax &= 0x08; /* SR0A[3] VRS[10] */
Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
/* Tempax: CR11 VRE */
Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
/* Tempbx: SR0A */
Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
if (Tempbx <= Tempcx) /* VRE <= VRS */
Tempbx |= 0x20; /* VRE + 0x20 */
/* Tempax: Tempax[7:0]; VRE[5:0]00 */
Tempax = (Tempbx << 2) & 0xFF;
/* SR3F[7:2]:VRE[5:0] */
xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
Tempax = Tempcx >> 8;
/* SR35[2:0]:VRS[10:8] */
xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax);
}
}
static void xgifb_set_lcd(int chip_id,
struct vb_device_info *pVBInfo,
unsigned short RefreshRateTableIndex,
unsigned short ModeNo)
{
unsigned short Data, Temp, b3CC;
unsigned short XGI_P3cc;
XGI_P3cc = pVBInfo->P3cc;
xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00);
xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00);
xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00);
xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00);
if (chip_id == XG27) {
Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
if ((Temp & 0x03) == 0) { /* dual 12 */
xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13);
xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13);
}
}
if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) {
xgifb_reg_set(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E);
xgifb_reg_set(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F);
xgifb_reg_set(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46);
xgifb_reg_set(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47);
}
if (chip_id == XG27) {
XGI_SetXG27FPBits(pVBInfo);
} else {
Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
if (Temp & 0x01) {
/* 18 bits FP */
xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40);
xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40);
}
}
xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
if (ModeNo <= 0x13) {
b3CC = (unsigned char) inb(XGI_P3cc);
if (b3CC & 0x40)
/* Hsync polarity */
xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
if (b3CC & 0x80)
/* Vsync polarity */
xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
} else {
Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
if (Data & 0x4000)
/* Hsync polarity */
xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
if (Data & 0x8000)
/* Vsync polarity */
xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
}
}
/* --------------------------------------------------------------------- */
/* Function : XGI_UpdateXG21CRTC */
/* Input : */
/* Output : CRT1 CRTC */
/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
/* --------------------------------------------------------------------- */
static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
struct vb_device_info *pVBInfo,
unsigned short RefreshRateTableIndex)
{
int i, index = -1;
xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
if (ModeNo <= 0x13) {
for (i = 0; i < 12; i++) {
if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID)
index = i;
}
} else {
if (ModeNo == 0x2E &&
(pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
RES640x480x60))
index = 12;
else if (ModeNo == 0x2E &&
(pVBInfo->RefIndex[RefreshRateTableIndex].
Ext_CRT1CRTC == RES640x480x72))
index = 13;
else if (ModeNo == 0x2F)
index = 14;
else if (ModeNo == 0x50)
index = 15;
else if (ModeNo == 0x59)
index = 16;
}
if (index != -1) {
xgifb_reg_set(pVBInfo->P3d4, 0x02,
pVBInfo->UpdateCRT1[index].CR02);
xgifb_reg_set(pVBInfo->P3d4, 0x03,
pVBInfo->UpdateCRT1[index].CR03);
xgifb_reg_set(pVBInfo->P3d4, 0x15,
pVBInfo->UpdateCRT1[index].CR15);
xgifb_reg_set(pVBInfo->P3d4, 0x16,
pVBInfo->UpdateCRT1[index].CR16);
}
}
static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
unsigned char data;
resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
if (ModeNo <= 0x13) {
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
tempax = pVBInfo->StResInfo[resindex].HTotal;
tempbx = pVBInfo->StResInfo[resindex].VTotal;
} else {
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
tempax = pVBInfo->ModeResInfo[resindex].HTotal;
tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
}
if (modeflag & HalfDCLK)
tempax = tempax >> 1;
if (ModeNo > 0x13) {
if (modeflag & HalfDCLK)
tempax = tempax << 1;
temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
if (temp & InterlaceMode)
tempbx = tempbx >> 1;
if (modeflag & DoubleScanMode)
tempbx = tempbx << 1;
}
tempcx = 8;
/* if (!(modeflag & Charx8Dot)) */
/* tempcx = 9; */
tempax /= tempcx;
tempax -= 1;
tempbx -= 1;
tempcx = tempax;
temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
data &= 0x7F;
xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c,
(unsigned short) ((tempcx & 0x0ff00) >> 10));
xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
tempax = 0;
tempbx = tempbx >> 8;
if (tempbx & 0x01)
tempax |= 0x02;
if (tempbx & 0x02)
tempax |= 0x40;
xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax);
data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x07);
data &= 0xFF;
tempax = 0;
if (tempbx & 0x04)
tempax |= 0x02;
xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
xgifb_reg_set(pVBInfo->P3d4, 0x11, temp);
}
unsigned short XGI_GetResInfo(unsigned short ModeNo,
unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
{
unsigned short resindex;
if (ModeNo <= 0x13)
/* si+St_ResInfo */
resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
else
/* si+Ext_ResInfo */
resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
return resindex;
}
static void XGI_SetCRT1Offset(unsigned short ModeNo,
unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct xgi_hw_device_info *HwDeviceExtension,
struct vb_device_info *pVBInfo)
{
unsigned short temp, ah, al, temp2, i, DisplayUnit;
/* GetOffset */
temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
temp = temp >> 8;
temp = pVBInfo->ScreenOffset[temp];
temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
temp2 &= InterlaceMode;
if (temp2)
temp = temp << 1;
temp2 = pVBInfo->ModeType - ModeEGA;
switch (temp2) {
case 0:
temp2 = 1;
break;
case 1:
temp2 = 2;
break;
case 2:
temp2 = 4;
break;
case 3:
temp2 = 4;
break;
case 4:
temp2 = 6;
break;
case 5:
temp2 = 8;
break;
default:
break;
}
if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
temp = temp * temp2 + temp2 / 2;
else
temp *= temp2;
/* SetOffset */
DisplayUnit = temp;
temp2 = temp;
temp = temp >> 8; /* ah */
temp &= 0x0F;
i = xgifb_reg_get(pVBInfo->P3c4, 0x0E);
i &= 0xF0;
i |= temp;
xgifb_reg_set(pVBInfo->P3c4, 0x0E, i);
temp = (unsigned char) temp2;
temp &= 0xFF; /* al */
xgifb_reg_set(pVBInfo->P3d4, 0x13, temp);
/* SetDisplayUnit */
temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
temp2 &= InterlaceMode;
if (temp2)
DisplayUnit >>= 1;
DisplayUnit = DisplayUnit << 5;
ah = (DisplayUnit & 0xff00) >> 8;
al = DisplayUnit & 0x00ff;
if (al == 0)
ah += 1;
else
ah += 2;
if (HwDeviceExtension->jChipType >= XG20)
if ((ModeNo == 0x4A) | (ModeNo == 0x49))
ah -= 1;
xgifb_reg_set(pVBInfo->P3c4, 0x10, ah);
}
static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct xgi_hw_device_info *HwDeviceExtension,
struct vb_device_info *pVBInfo)
{
unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2,
VCLK65 + 2,
VCLK65 + 2,
VCLK65 + 2 };
unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5,
VCLK108_2 + 5,
VCLK108_2 + 5,
VCLK108_2 + 5 };
unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2,
VCLK65 + 2,
VCLK65 + 2,
VCLK65 + 2 };
unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2,
VCLK65 + 2,
VCLK65 + 2,
VCLK65 + 2 };
unsigned short CRT2Index, VCLKIndex;
unsigned short modeflag, resinfo;
if (ModeNo <= 0x13) {
/* si+St_ResInfo */
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
} else {
/* si+Ext_ResInfo */
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].
Ext_CRT2CRTC;
}
if (pVBInfo->IF_DEF_LVDS == 0) {
CRT2Index = CRT2Index >> 6; /* for LCD */
if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/
if (pVBInfo->LCDResInfo != Panel1024x768)
VCLKIndex = LCDXlat2VCLK[CRT2Index];
else
VCLKIndex = LCDXlat1VCLK[CRT2Index];
} else { /* for TV */
if (pVBInfo->VBInfo & SetCRT2ToTV) {
if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
if (pVBInfo->SetFlag & RPLLDIV2XO) {
VCLKIndex = HiTVVCLKDIV2;
VCLKIndex += 25;
} else {
VCLKIndex = HiTVVCLK;
VCLKIndex += 25;
}
if (pVBInfo->SetFlag & TVSimuMode) {
if (modeflag & Charx8Dot) {
VCLKIndex =
HiTVSimuVCLK;
VCLKIndex += 25;
} else {
VCLKIndex =
HiTVTextVCLK;
VCLKIndex += 25;
}
}
/* 301lv */
if (pVBInfo->VBType & VB_XGI301LV) {
if (!(pVBInfo->VBExtInfo ==
VB_YPbPr1080i)) {
VCLKIndex =
YPbPr750pVCLK;
if (!(pVBInfo->VBExtInfo
==
VB_YPbPr750p)) {
VCLKIndex =
YPbPr525pVCLK;
if (!(pVBInfo->VBExtInfo
== VB_YPbPr525p)) {
VCLKIndex
= YPbPr525iVCLK_2;
if (!(pVBInfo->SetFlag
& RPLLDIV2XO))
VCLKIndex
= YPbPr525iVCLK;
}
}
}
}
} else {
if (pVBInfo->VBInfo & SetCRT2ToTV) {
if (pVBInfo->SetFlag &
RPLLDIV2XO) {
VCLKIndex = TVVCLKDIV2;
VCLKIndex += 25;
} else {
VCLKIndex = TVVCLK;
VCLKIndex += 25;
}
}
}
} else { /* for CRT2 */
/* Port 3cch */
VCLKIndex = (unsigned char) inb(
(pVBInfo->P3ca + 0x02));
VCLKIndex = ((VCLKIndex >> 2) & 0x03);
if (ModeNo > 0x13) {
/* di+Ext_CRTVCLK */
VCLKIndex =
pVBInfo->RefIndex[
RefreshRateTableIndex].
Ext_CRTVCLK;
VCLKIndex &= IndexMask;
}
}
}
} else { /* LVDS */
if (ModeNo <= 0x13)
VCLKIndex = CRT2Index;
else
VCLKIndex = CRT2Index;
VCLKIndex = VCLKIndex >> 6;
if ((pVBInfo->LCDResInfo == Panel800x600) ||
(pVBInfo->LCDResInfo == Panel320x480))
VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
else if ((pVBInfo->LCDResInfo == Panel1024x768) ||
(pVBInfo->LCDResInfo == Panel1024x768x75))
VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
else
VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
}
/* VCLKIndex = VCLKIndex&IndexMask; */
return VCLKIndex;
}
static void XGI_SetCRT1VCLK(unsigned short ModeNo,
unsigned short ModeIdIndex,
struct xgi_hw_device_info *HwDeviceExtension,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned char index, data;
unsigned short vclkindex;
if (pVBInfo->IF_DEF_LVDS == 1) {
index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
xgifb_reg_set(pVBInfo->P3c4, 0x2B,
pVBInfo->VCLKData[index].SR2B);
xgifb_reg_set(pVBInfo->P3c4, 0x2C,
pVBInfo->VCLKData[index].SR2C);
xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
} else if ((pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
| VB_XGI302LV | VB_XGI301C)) && (pVBInfo->VBInfo
& SetCRT2ToLCDA)) {
vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex,
RefreshRateTableIndex, HwDeviceExtension,
pVBInfo);
data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
data = pVBInfo->VBVCLKData[vclkindex].Part4_A;
xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
data = pVBInfo->VBVCLKData[vclkindex].Part4_B;
xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
} else {
index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
xgifb_reg_set(pVBInfo->P3c4, 0x2B,
pVBInfo->VCLKData[index].SR2B);
xgifb_reg_set(pVBInfo->P3c4, 0x2C,
pVBInfo->VCLKData[index].SR2C);
xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
}
if (HwDeviceExtension->jChipType >= XG20) {
if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag &
HalfDCLK) {
data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
data = xgifb_reg_get(pVBInfo->P3c4, 0x2C);
index = data;
index &= 0xE0;
data &= 0x1F;
data = data << 1;
data += 1;
data |= index;
xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
}
}
}
static void XGI_SetCRT1FIFO(unsigned short ModeNo,
struct xgi_hw_device_info *HwDeviceExtension,
struct vb_device_info *pVBInfo)
{
unsigned short data;
data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
data &= 0xfe;
xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
if (ModeNo > 0x13) {
xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34);
data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
data &= 0xC0;
xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30);
data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
data |= 0x01;
xgifb_reg_set(pVBInfo->P3c4, 0x3D, data);
} else {
if (HwDeviceExtension->jChipType == XG27) {
xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x0E);
data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
data &= 0xC0;
xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x20);
} else {
xgifb_reg_set(pVBInfo->P3c4, 0x08, 0xAE);
data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
data &= 0xF0;
xgifb_reg_set(pVBInfo->P3c4, 0x09, data);
}
}
if (HwDeviceExtension->jChipType == XG21)
XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
}
static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
unsigned short ModeNo, unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short data, data2 = 0;
short VCLK;
unsigned char index;
if (ModeNo <= 0x13)
VCLK = 0;
else {
index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
index &= IndexMask;
VCLK = pVBInfo->VCLKData[index].CLOCK;
}
data = xgifb_reg_get(pVBInfo->P3c4, 0x32);
data &= 0xf3;
if (VCLK >= 200)
data |= 0x0c; /* VCLK > 200 */
if (HwDeviceExtension->jChipType >= XG20)
data &= ~0x04; /* 2 pixel mode */
xgifb_reg_set(pVBInfo->P3c4, 0x32, data);
if (HwDeviceExtension->jChipType < XG20) {
data = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
data &= 0xE7;
if (VCLK < 200)
data |= 0x10;
xgifb_reg_set(pVBInfo->P3c4, 0x1F, data);
}
/* Jong for Adavantech LCD ripple issue
if ((VCLK >= 0) && (VCLK < 135))
data2 = 0x03;
else if ((VCLK >= 135) && (VCLK < 160))
data2 = 0x02;
else if ((VCLK >= 160) && (VCLK < 260))
data2 = 0x01;
else if (VCLK > 260)
data2 = 0x00;
*/
data2 = 0x00;
xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2);
if (HwDeviceExtension->jChipType >= XG27)
xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
}
static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
xres;
if (ModeNo > 0x13) {
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].
Ext_InfoFlag;
} else
/* si+St_ModeFlag */
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
if (ModeNo > 0x13)
data = infoflag;
else
data = 0;
data2 = 0;
if (ModeNo > 0x13) {
if (pVBInfo->ModeType > 0x02) {
data2 |= 0x02;
data3 = pVBInfo->ModeType - ModeVGA;
data3 = data3 << 2;
data2 |= data3;
}
}
data &= InterlaceMode;
if (data)
data2 |= 0x20;
xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
/* xgifb_reg_set(pVBInfo->P3c4,0x06,data2); */
resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
if (ModeNo <= 0x13)
xres = pVBInfo->StResInfo[resindex].HTotal;
else
xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
data = 0x0000;
if (infoflag & InterlaceMode) {
if (xres == 1024)
data = 0x0035;
else if (xres == 1280)
data = 0x0048;
}
data2 = data & 0x00FF;
xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data2);
data2 = (data & 0xFF00) >> 8;
xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, data2);
if (modeflag & HalfDCLK)
xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
data2 = 0;
if (modeflag & LineCompareOff)
data2 |= 0x08;
if (ModeNo > 0x13) {
if (pVBInfo->ModeType == ModeEGA)
data2 |= 0x40;
}
xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2);
data = 0x60;
if (pVBInfo->ModeType != ModeText) {
data = data ^ 0x60;
if (pVBInfo->ModeType != ModeEGA)
data = data ^ 0xA0;
}
xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data);
XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
pVBInfo);
/* if (modeflag&HalfDCLK) //030305 fix lowresolution bug */
/* if (XGINew_IF_DEF_NEW_LOWRES) */
/* XGI_VesaLowResolution(ModeNo, ModeIdIndex);
* //030305 fix lowresolution bug */
data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
if (HwDeviceExtension->jChipType == XG27) {
if (data & 0x40)
data = 0x2c;
else
data = 0x6c;
xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10);
} else if (HwDeviceExtension->jChipType >= XG20) {
if (data & 0x40)
data = 0x33;
else
data = 0x73;
xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02);
} else {
if (data & 0x40)
data = 0x2c;
else
data = 0x6c;
xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
}
}
static void XGI_WriteDAC(unsigned short dl,
unsigned short ah,
unsigned short al,
unsigned short dh,
struct vb_device_info *pVBInfo)
{
unsigned short temp, bh, bl;
bh = ah;
bl = al;
if (dl != 0) {
temp = bh;
bh = dh;
dh = temp;
if (dl == 1) {
temp = bl;
bl = dh;
dh = temp;
} else {
temp = bl;
bl = bh;
bh = temp;
}
}
outb((unsigned short) dh, pVBInfo->P3c9);
outb((unsigned short) bh, pVBInfo->P3c9);
outb((unsigned short) bl, pVBInfo->P3c9);
}
static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo)
{
unsigned short data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al,
ah, dh;
const unsigned short *table = NULL;
if (ModeNo <= 0x13)
data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
else
data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
data &= DACInfoFlag;
time = 64;
if (data == 0x00)
table = XGINew_MDA_DAC;
else if (data == 0x08)
table = XGINew_CGA_DAC;
else if (data == 0x10)
table = XGINew_EGA_DAC;
else if (data == 0x18) {
time = 256;
table = XGINew_VGA_DAC;
}
if (time == 256)
j = 16;
else
j = time;
outb(0xFF, pVBInfo->P3c6);
outb(0x00, pVBInfo->P3c8);
for (i = 0; i < j; i++) {
data = table[i];
for (k = 0; k < 3; k++) {
data2 = 0;
if (data & 0x01)
data2 = 0x2A;
if (data & 0x02)
data2 += 0x15;
outb(data2, pVBInfo->P3c9);
data = data >> 2;
}
}
if (time == 256) {
for (i = 16; i < 32; i++) {
data = table[i];
for (k = 0; k < 3; k++)
outb(data, pVBInfo->P3c9);
}
si = 32;
for (m = 0; m < 9; m++) {
di = si;
bx = si + 0x04;
dl = 0;
for (n = 0; n < 3; n++) {
for (o = 0; o < 5; o++) {
dh = table[si];
ah = table[di];
al = table[bx];
si++;
XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
}
si -= 2;
for (o = 0; o < 3; o++) {
dh = table[bx];
ah = table[di];
al = table[si];
si--;
XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
}
dl++;
}
si += 5;
}
}
}
static void XGI_GetLVDSResInfo(unsigned short ModeNo,
unsigned short ModeIdIndex,
struct vb_device_info *pVBInfo)
{
unsigned short resindex, xres, yres, modeflag;
if (ModeNo <= 0x13)
/* si+St_ResInfo */
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
else
/* si+Ext_ResInfo */
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
/* if (ModeNo > 0x13) */
/* modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; */
/* else */
/* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; */
if (ModeNo <= 0x13)
/* si+St_ResInfo */
resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
else
/* si+Ext_ResInfo */
resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
/* resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); */
if (ModeNo <= 0x13) {
xres = pVBInfo->StResInfo[resindex].HTotal;
yres = pVBInfo->StResInfo[resindex].VTotal;
} else {
xres = pVBInfo->ModeResInfo[resindex].HTotal;
yres = pVBInfo->ModeResInfo[resindex].VTotal;
}
if (ModeNo > 0x13) {
if (modeflag & HalfDCLK)
xres = xres << 1;
if (modeflag & DoubleScanMode)
yres = yres << 1;
}
/* if (modeflag & Charx8Dot) */
/* { */
if (xres == 720)
xres = 640;
/* } */
pVBInfo->VGAHDE = xres;
pVBInfo->HDE = xres;
pVBInfo->VGAVDE = yres;
pVBInfo->VDE = yres;
}
static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table;
struct XGI330_LCDDataTablStruct *tempdi = NULL;
tempbx = BX;
if (ModeNo <= 0x13) {
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
} else {
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
}
tempal = tempal & 0x0f;
if (tempbx <= 1) { /* ExpLink */
if (ModeNo <= 0x13) {
/* find no Ext_CRT2CRTC2 */
tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
} else {
tempal = pVBInfo->RefIndex[RefreshRateTableIndex].
Ext_CRT2CRTC;
}
if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
if (ModeNo <= 0x13)
tempal = pVBInfo->SModeIDTable[ModeIdIndex].
St_CRT2CRTC2;
else
tempal = pVBInfo->RefIndex[
RefreshRateTableIndex].
Ext_CRT2CRTC2;
}
if (tempbx & 0x01)
tempal = (tempal >> 4);
tempal = (tempal & 0x0f);
}
tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
if ((tempbx == 5) || (tempbx) == 7)
tempcx = LCDDesDataLen2;
else if ((tempbx == 3) || (tempbx == 8))
tempcx = LVDSDesDataLen2;
}
/* mov di, word ptr cs:LCDDataList[bx] */
/* tempdi = pVideoMemory[LCDDataList + tempbx * 2] |
(pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */
switch (tempbx) {
case 0:
case 1:
tempdi = xgifb_epllcd_crt1;
break;
case 2:
tempdi = XGI_EPLLCDDataPtr;
break;
case 3:
tempdi = XGI_EPLLCDDesDataPtr;
break;
case 4:
tempdi = XGI_LCDDataTable;
break;
case 5:
tempdi = XGI_LCDDesDataTable;
break;
case 6:
tempdi = XGI_EPLCHLCDRegPtr;
break;
case 7:
case 8:
case 9:
tempdi = NULL;
break;
default:
break;
}
if (tempdi == NULL) /* OEMUtil */
return NULL;
table = tempbx;
i = 0;
while (tempdi[i].PANELID != 0xff) {
tempdx = pVBInfo->LCDResInfo;
if (tempbx & 0x0080) { /* OEMUtil */
tempbx &= (~0x0080);
tempdx = pVBInfo->LCDTypeInfo;
}
if (pVBInfo->LCDInfo & EnableScalingLCD)
tempdx &= (~PanelResInfo);
if (tempdi[i].PANELID == tempdx) {
tempbx = tempdi[i].MASK;
tempdx = pVBInfo->LCDInfo;
if (ModeNo <= 0x13) /* alan 09/10/2003 */
tempdx |= SetLCDStdMode;
if (modeflag & HalfDCLK)
tempdx |= SetLCDLowResolution;
tempbx &= tempdx;
if (tempbx == tempdi[i].CAP)
break;
}
i++;
}
if (table == 0) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_LVDSCRT11024x768_1_H[tempal];
break;
case 1:
return &XGI_LVDSCRT11024x768_2_H[tempal];
break;
case 2:
return &XGI_LVDSCRT11280x1024_1_H[tempal];
break;
case 3:
return &XGI_LVDSCRT11280x1024_2_H[tempal];
break;
case 4:
return &XGI_LVDSCRT11400x1050_1_H[tempal];
break;
case 5:
return &XGI_LVDSCRT11400x1050_2_H[tempal];
break;
case 6:
return &XGI_LVDSCRT11600x1200_1_H[tempal];
break;
case 7:
return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
break;
case 8:
return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
break;
case 9:
return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
break;
case 10:
return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
break;
default:
break;
}
} else if (table == 1) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_LVDSCRT11024x768_1_V[tempal];
break;
case 1:
return &XGI_LVDSCRT11024x768_2_V[tempal];
break;
case 2:
return &XGI_LVDSCRT11280x1024_1_V[tempal];
break;
case 3:
return &XGI_LVDSCRT11280x1024_2_V[tempal];
break;
case 4:
return &XGI_LVDSCRT11400x1050_1_V[tempal];
break;
case 5:
return &XGI_LVDSCRT11400x1050_2_V[tempal];
break;
case 6:
return &XGI_LVDSCRT11600x1200_1_V[tempal];
break;
case 7:
return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
break;
case 8:
return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
break;
case 9:
return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
break;
case 10:
return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
break;
default:
break;
}
} else if (table == 2) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_LVDS1024x768Data_1[tempal];
break;
case 1:
return &XGI_LVDS1024x768Data_2[tempal];
break;
case 2:
return &XGI_LVDS1280x1024Data_1[tempal];
break;
case 3:
return &XGI_LVDS1280x1024Data_2[tempal];
break;
case 4:
return &XGI_LVDS1400x1050Data_1[tempal];
break;
case 5:
return &XGI_LVDS1400x1050Data_2[tempal];
break;
case 6:
return &XGI_LVDS1600x1200Data_1[tempal];
break;
case 7:
return &XGI_LVDSNoScalingData[tempal];
break;
case 8:
return &XGI_LVDS1024x768Data_1x75[tempal];
break;
case 9:
return &XGI_LVDS1024x768Data_2x75[tempal];
break;
case 10:
return &XGI_LVDS1280x1024Data_1x75[tempal];
break;
case 11:
return &XGI_LVDS1280x1024Data_2x75[tempal];
break;
case 12:
return &XGI_LVDSNoScalingDatax75[tempal];
break;
default:
break;
}
} else if (table == 3) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_LVDS1024x768Des_1[tempal];
break;
case 1:
return &XGI_LVDS1024x768Des_3[tempal];
break;
case 2:
return &XGI_LVDS1024x768Des_2[tempal];
break;
case 3:
return &XGI_LVDS1280x1024Des_1[tempal];
break;
case 4:
return &XGI_LVDS1280x1024Des_2[tempal];
break;
case 5:
return &XGI_LVDS1400x1050Des_1[tempal];
break;
case 6:
return &XGI_LVDS1400x1050Des_2[tempal];
break;
case 7:
return &XGI_LVDS1600x1200Des_1[tempal];
break;
case 8:
return &XGI_LVDSNoScalingDesData[tempal];
break;
case 9:
return &XGI_LVDS1024x768Des_1x75[tempal];
break;
case 10:
return &XGI_LVDS1024x768Des_3x75[tempal];
break;
case 11:
return &XGI_LVDS1024x768Des_2x75[tempal];
break;
case 12:
return &XGI_LVDS1280x1024Des_1x75[tempal];
break;
case 13:
return &XGI_LVDS1280x1024Des_2x75[tempal];
break;
case 14:
return &XGI_LVDSNoScalingDesDatax75[tempal];
break;
default:
break;
}
} else if (table == 4) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_ExtLCD1024x768Data[tempal];
break;
case 1:
return &XGI_StLCD1024x768Data[tempal];
break;
case 2:
return &XGI_CetLCD1024x768Data[tempal];
break;
case 3:
return &XGI_ExtLCD1280x1024Data[tempal];
break;
case 4:
return &XGI_StLCD1280x1024Data[tempal];
break;
case 5:
return &XGI_CetLCD1280x1024Data[tempal];
break;
case 6:
case 7:
return &xgifb_lcd_1400x1050[tempal];
break;
case 8:
return &XGI_CetLCD1400x1050Data[tempal];
break;
case 9:
return &XGI_ExtLCD1600x1200Data[tempal];
break;
case 10:
return &XGI_StLCD1600x1200Data[tempal];
break;
case 11:
return &XGI_NoScalingData[tempal];
break;
case 12:
return &XGI_ExtLCD1024x768x75Data[tempal];
break;
case 13:
return &XGI_ExtLCD1024x768x75Data[tempal];
break;
case 14:
return &XGI_CetLCD1024x768x75Data[tempal];
break;
case 15:
case 16:
return &xgifb_lcd_1280x1024x75[tempal];
break;
case 17:
return &XGI_CetLCD1280x1024x75Data[tempal];
break;
case 18:
return &XGI_NoScalingDatax75[tempal];
break;
default:
break;
}
} else if (table == 5) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_ExtLCDDes1024x768Data[tempal];
break;
case 1:
return &XGI_StLCDDes1024x768Data[tempal];
break;
case 2:
return &XGI_CetLCDDes1024x768Data[tempal];
break;
case 3:
if ((pVBInfo->VBType & VB_XGI301LV) ||
(pVBInfo->VBType & VB_XGI302LV))
return &XGI_ExtLCDDLDes1280x1024Data[tempal];
else
return &XGI_ExtLCDDes1280x1024Data[tempal];
break;
case 4:
if ((pVBInfo->VBType & VB_XGI301LV) ||
(pVBInfo->VBType & VB_XGI302LV))
return &XGI_StLCDDLDes1280x1024Data[tempal];
else
return &XGI_StLCDDes1280x1024Data[tempal];
break;
case 5:
if ((pVBInfo->VBType & VB_XGI301LV) ||
(pVBInfo->VBType & VB_XGI302LV))
return &XGI_CetLCDDLDes1280x1024Data[tempal];
else
return &XGI_CetLCDDes1280x1024Data[tempal];
break;
case 6:
case 7:
if ((pVBInfo->VBType & VB_XGI301LV) ||
(pVBInfo->VBType & VB_XGI302LV))
return &xgifb_lcddldes_1400x1050[tempal];
else
return &xgifb_lcddes_1400x1050[tempal];
break;
case 8:
return &XGI_CetLCDDes1400x1050Data[tempal];
break;
case 9:
return &XGI_CetLCDDes1400x1050Data2[tempal];
break;
case 10:
if ((pVBInfo->VBType & VB_XGI301LV) ||
(pVBInfo->VBType & VB_XGI302LV))
return &XGI_ExtLCDDLDes1600x1200Data[tempal];
else
return &XGI_ExtLCDDes1600x1200Data[tempal];
break;
case 11:
if ((pVBInfo->VBType & VB_XGI301LV) ||
(pVBInfo->VBType & VB_XGI302LV))
return &XGI_StLCDDLDes1600x1200Data[tempal];
else
return &XGI_StLCDDes1600x1200Data[tempal];
break;
case 12:
return &XGI_NoScalingDesData[tempal];
break;
case 13:
case 14:
return &xgifb_lcddes_1024x768x75[tempal];
break;
case 15:
return &XGI_CetLCDDes1024x768x75Data[tempal];
break;
case 16:
case 17:
if ((pVBInfo->VBType & VB_XGI301LV) ||
(pVBInfo->VBType & VB_XGI302LV))
return &xgifb_lcddldes_1280x1024x75[tempal];
else
return &xgifb_lcddes_1280x1024x75[tempal];
break;
case 18:
if ((pVBInfo->VBType & VB_XGI301LV) ||
(pVBInfo->VBType & VB_XGI302LV))
return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
else
return &XGI_CetLCDDes1280x1024x75Data[tempal];
break;
case 19:
return &XGI_NoScalingDesDatax75[tempal];
break;
default:
break;
}
} else if (table == 6) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_CH7017LV1024x768[tempal];
break;
case 1:
return &XGI_CH7017LV1400x1050[tempal];
break;
default:
break;
}
}
return NULL;
}
static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo,
unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short i, tempdx, tempbx, tempal, modeflag, table;
struct XGI330_TVDataTablStruct *tempdi = NULL;
tempbx = BX;
if (ModeNo <= 0x13) {
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
} else {
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
}
tempal = tempal & 0x3f;
table = tempbx;
switch (tempbx) {
case 0:
tempdi = NULL; /*EPLCHTVCRT1Ptr_H;*/
break;
case 1:
tempdi = NULL; /*EPLCHTVCRT1Ptr_V;*/
break;
case 2:
case 6:
tempdi = xgifb_chrontel_tv;
break;
case 3:
tempdi = NULL;
break;
case 4:
tempdi = XGI_TVDataTable;
break;
case 5:
tempdi = NULL;
break;
default:
break;
}
if (tempdi == NULL) /* OEMUtil */
return NULL;
tempdx = pVBInfo->TVInfo;
if (pVBInfo->VBInfo & SetInSlaveMode)
tempdx = tempdx | SetTVLockMode;
if (modeflag & HalfDCLK)
tempdx = tempdx | SetTVLowResolution;
i = 0;
while (tempdi[i].MASK != 0xffff) {
if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
break;
i++;
}
/* 07/05/22 */
if (table == 0x00) {
} else if (table == 0x01) {
} else if (table == 0x04) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_ExtPALData[tempal];
break;
case 1:
return &XGI_ExtNTSCData[tempal];
break;
case 2:
return &XGI_StPALData[tempal];
break;
case 3:
return &XGI_StNTSCData[tempal];
break;
case 4:
return &XGI_ExtHiTVData[tempal];
break;
case 5:
return &XGI_St2HiTVData[tempal];
break;
case 6:
return &XGI_ExtYPbPr525iData[tempal];
break;
case 7:
return &XGI_ExtYPbPr525pData[tempal];
break;
case 8:
return &XGI_ExtYPbPr750pData[tempal];
break;
case 9:
return &XGI_StYPbPr525iData[tempal];
break;
case 10:
return &XGI_StYPbPr525pData[tempal];
break;
case 11:
return &XGI_StYPbPr750pData[tempal];
break;
case 12: /* avoid system hang */
return &XGI_ExtNTSCData[tempal];
break;
case 13:
return &XGI_St1HiTVData[tempal];
break;
default:
break;
}
} else if (table == 0x02) {
switch (tempdi[i].DATAPTR) {
case 0:
return &XGI_CHTVUNTSCData[tempal];
break;
case 1:
return &XGI_CHTVONTSCData[tempal];
break;
case 2:
return &XGI_CHTVUPALData[tempal];
break;
case 3:
return &XGI_CHTVOPALData[tempal];
break;
default:
break;
}
} else if (table == 0x06) {
}
return NULL;
}
static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short tempbx;
struct XGI330_LVDSDataStruct *LCDPtr = NULL;
tempbx = 2;
if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx,
ModeNo, ModeIdIndex, RefreshRateTableIndex,
pVBInfo);
pVBInfo->VGAHT = LCDPtr->VGAHT;
pVBInfo->VGAVT = LCDPtr->VGAVT;
pVBInfo->HT = LCDPtr->LCDHT;
pVBInfo->VT = LCDPtr->LCDVT;
}
if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
| EnableScalingLCD))) {
if ((pVBInfo->LCDResInfo == Panel1024x768) ||
(pVBInfo->LCDResInfo == Panel1024x768x75)) {
pVBInfo->HDE = 1024;
pVBInfo->VDE = 768;
} else if ((pVBInfo->LCDResInfo == Panel1280x1024) ||
(pVBInfo->LCDResInfo == Panel1280x1024x75)) {
pVBInfo->HDE = 1280;
pVBInfo->VDE = 1024;
} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
pVBInfo->HDE = 1400;
pVBInfo->VDE = 1050;
} else {
pVBInfo->HDE = 1600;
pVBInfo->VDE = 1200;
}
}
}
}
static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct xgi_hw_device_info *HwDeviceExtension,
struct vb_device_info *pVBInfo)
{
unsigned char index;
unsigned short tempbx, i;
struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
if (ModeNo <= 0x13)
index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
else
index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
index = index & IndexMask;
tempbx = 0;
if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
LCDPtr = (struct XGI_LVDSCRT1HDataStruct *)
XGI_GetLcdPtr(tempbx, ModeNo,
ModeIdIndex,
RefreshRateTableIndex,
pVBInfo);
for (i = 0; i < 8; i++)
pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
}
XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
tempbx = 1;
if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
LCDPtr1 = (struct XGI_LVDSCRT1VDataStruct *)
XGI_GetLcdPtr(
tempbx,
ModeNo,
ModeIdIndex,
RefreshRateTableIndex,
pVBInfo);
for (i = 0; i < 7; i++)
pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
}
XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
}
static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
{
unsigned char tempal, tempah, tempbl, i;
tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36);
tempal = tempah & 0x0F;
tempah = tempah & 0xF0;
i = 0;
tempbl = pVBInfo->LCDCapList[i].LCD_ID;
while (tempbl != 0xFF) {
if (tempbl & 0x80) { /* OEMUtil */
tempal = tempah;
tempbl = tempbl & ~(0x80);
}
if (tempal == tempbl)
break;
i++;
tempbl = pVBInfo->LCDCapList[i].LCD_ID;
}
return i;
}
static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
{
unsigned short tempah, tempal, tempbl, i;
tempal = pVBInfo->LCDResInfo;
tempah = pVBInfo->LCDTypeInfo;
i = 0;
tempbl = pVBInfo->LCDCapList[i].LCD_ID;
while (tempbl != 0xFF) {
if ((tempbl & 0x80) && (tempbl != 0x80)) {
tempal = tempah;
tempbl &= ~0x80;
}
if (tempal == tempbl)
break;
i++;
tempbl = pVBInfo->LCDCapList[i].LCD_ID;
}
if (tempbl == 0xFF) {
pVBInfo->LCDResInfo = Panel1024x768;
pVBInfo->LCDTypeInfo = 0;
i = 0;
}
return i;
}
static void XGI_GetLCDSync(unsigned short *HSyncWidth,
unsigned short *VSyncWidth,
struct vb_device_info *pVBInfo)
{
unsigned short Index;
Index = XGI_GetLCDCapPtr(pVBInfo);
*HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
*VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
return;
}
static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,
struct vb_device_info *pVBInfo)
{
unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
unsigned long temp, temp1, temp2, temp3, push3;
struct XGI330_LCDDataDesStruct *LCDPtr = NULL;
struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
if (ModeNo > 0x13)
modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
else
modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
tempbx = 3;
if (pVBInfo->LCDInfo & EnableScalingLCD)
LCDPtr1 =
(struct XGI330_LCDDataDesStruct2 *)
XGI_GetLcdPtr(
tempbx,
ModeNo,
ModeIdIndex,
RefreshRateTableIndex,
pVBInfo);
else
LCDPtr =
(struct XGI330_LCDDataDesStruct *)
XGI_GetLcdPtr(
tempbx,
ModeNo,
ModeIdIndex,
RefreshRateTableIndex,
pVBInfo);
XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
push1 = tempbx;
push2 = tempax;
/* GetLCDResInfo */
if ((pVBInfo->LCDResInfo == Panel1024x768) ||
(pVBInfo->LCDResInfo == Panel1024x768x75)) {
tempax = 1024;
tempbx = 768;
} else if ((pVBInfo->LCDResInfo == Panel1280x1024) ||
(pVBInfo->LCDResInfo == Panel1280x1024x75)) {
tempax = 1280;
tempbx = 1024;
} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
tempax = 1400;
tempbx = 1050;
} else {
tempax = 1600;
tempbx = 1200;
}
if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
pVBInfo->HDE = tempax;
pVBInfo->VDE = tempbx;
pVBInfo->VGAHDE = tempax;
pVBInfo->VGAVDE = tempbx;
}
tempax = pVBInfo->HT;
if (pVBInfo->LCDInfo & EnableScalingLCD)
tempbx = LCDPtr1->LCDHDES;
else
tempbx = LCDPtr->LCDHDES;
tempcx = pVBInfo->HDE;
tempbx = tempbx & 0x0fff;
tempcx += tempbx;
if (tempcx >= tempax)
tempcx -= tempax;
xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
tempcx = tempcx >> 3;
tempbx = tempbx >> 3;
xgifb_reg_set(pVBInfo->Part1Port, 0x16,
(unsigned short) (tempbx & 0xff));
xgifb_reg_set(pVBInfo->Part1Port, 0x17,
(unsigned short) (tempcx & 0xff));
tempax = pVBInfo->HT;
if (pVBInfo->LCDInfo & EnableScalingLCD)
tempbx = LCDPtr1->LCDHRS;
else
tempbx = LCDPtr->LCDHRS;
tempcx = push2;
if (pVBInfo->LCDInfo & EnableScalingLCD)
tempcx = LCDPtr1->LCDHSync;
tempcx += tempbx;
if (tempcx >= tempax)
tempcx -= tempax;
tempax = tempbx & 0x07;
tempax = tempax >> 5;
tempcx = tempcx >> 3;
tempbx = tempbx >> 3;
tempcx &= 0x1f;
tempax |= tempcx;
xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax);
xgifb_reg_set(pVBInfo->Part1Port, 0x14,
(unsigned short) (tempbx & 0xff));
tempax = pVBInfo->VT;
if (pVBInfo->LCDInfo & EnableScalingLCD)
tempbx = LCDPtr1->LCDVDES;
else
tempbx = LCDPtr->LCDVDES;
tempcx = pVBInfo->VDE;
tempbx = tempbx & 0x0fff;
tempcx += tempbx;
if (tempcx >= tempax)
tempcx -= tempax;
xgifb_reg_set(pVBInfo->Part1Port, 0x1b,
(unsigned short) (tempbx & 0xff));
xgifb_reg_set(pVBInfo->Part1Port, 0x1c,
(unsigned short) (tempcx & 0xff));
tempbx = (tempbx >> 8) & 0x07;
tempcx = (tempcx >> 8) & 0x07;
xgifb_reg_set(pVBInfo->Part1Port, 0x1d,
(unsigned short) ((tempcx << 3)
| tempbx));
tempax = pVBInfo->VT;
if (pVBInfo->LCDInfo & EnableScalingLCD)
tempbx = LCDPtr1->LCDVRS;
else
tempbx = LCDPtr->LCDVRS;
/* tempbx = tempbx >> 4; */
tempcx = push1;
if (pVBInfo->LCDInfo & EnableScalingLCD)
tempcx = LCDPtr1->LCDVSync;
tempcx += tempbx;
if (tempcx >= tempax)
tempcx -= tempax;
xgifb_reg_set(pVBInfo->Part1Port, 0x18,
(unsigned short) (tempbx & 0xff));
xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f,
(unsigned short) (tempcx