| |
| #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 |