📄 init301.c
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ *//* * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740 * (Universal module for Linux kernel framebuffer, XFree86 4.x) * * Assembler-To-C translation * Parts Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net> * * Based on BIOS * 1.10.07, 1.10a for SiS650/LVDS+CH7019 * 1.07.1b, 1.10.6s for SiS650/301(B/LV), 650/301LVx * 2.04.50 (I) and 2.04.5c (II) for SiS630/301(B) * 2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005 * 1.09b for 315/301(B) * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of the copyright holder not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. The copyright holder makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * */#include "init301.h"#if 0#define TWNEWPANEL#endif#if 1 /* TW: Emulate 650/301LVx BIOS 1.10.6s (should be set) */#define SIS650301NEW#endif#ifdef SIS300#include "oem300.h"#endif#ifdef SIS315H#include "oem310.h"#endif#define SiS_I2CDELAY 1000#define SiS_I2CDELAYSHORT 333BOOLEANSiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension){ USHORT ModeIdIndex; USHORT RefreshRateTableIndex; SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex); /* TW: Used for shifting CR33 */ SiS_Pr->SiS_SelectCRT2Rate = 4; SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr); RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension); SiS_SaveCRT2Info(SiS_Pr,ModeNo); if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr); SiS_SetCRT2ModeRegs(SiS_Pr,BaseAddr,ModeNo,ModeIdIndex,HwDeviceExtension); } if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr); SiS_DisplayOn(SiS_Pr); return(FALSE); } SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, HwDeviceExtension); /* LVDS, 650/301LV(LCDA) and 630/301B BIOS set up Panel Link */ if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) { SiS_GetLVDSDesData(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex, HwDeviceExtension); } else { SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; } if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { SiS_SetGroup1(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension,RefreshRateTableIndex); } if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { SiS_SetGroup2(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, RefreshRateTableIndex,HwDeviceExtension); SiS_SetGroup3(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension); SiS_SetGroup4(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, RefreshRateTableIndex,HwDeviceExtension); SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr, ModeNo,ModeIdIndex); /* TW: 630/301B BIOS does all this: */ if(HwDeviceExtension->jChipType < SIS_315H) { if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { if(!((SiS_Pr->SiS_SetFlag & CRT2IsVGA) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) { if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, RefreshRateTableIndex,HwDeviceExtension); } } } SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, RefreshRateTableIndex,HwDeviceExtension); } } } } else { if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) { if (SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, RefreshRateTableIndex,HwDeviceExtension); } } if(SiS_Pr->SiS_IF_DEF_FSTN == 0) { SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, RefreshRateTableIndex,HwDeviceExtension); } if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { /* TW: Inserted from 650/LVDS BIOS */ if (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr); } } if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TW: Set Chrontel registers only if CRT2 is TV */ SiS_SetCHTVReg(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, RefreshRateTableIndex); } } } }#ifdef SIS300 if ( (HwDeviceExtension->jChipType==SIS_540)|| (HwDeviceExtension->jChipType==SIS_630)|| (HwDeviceExtension->jChipType==SIS_730)|| (HwDeviceExtension->jChipType==SIS_300) ) { if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo); } }#endif#ifdef SIS315H if ( (HwDeviceExtension->jChipType==SIS_315H)|| (HwDeviceExtension->jChipType==SIS_315PRO)|| (HwDeviceExtension->jChipType==SIS_550) || (HwDeviceExtension->jChipType==SIS_640) || (HwDeviceExtension->jChipType==SIS_740) || (HwDeviceExtension->jChipType==SIS_650)) { if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {#ifdef SIS650301NEW SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);#else SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);#endif SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex); SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr); } }#endif if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr); SiS_DisplayOn(SiS_Pr); } if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TW: Disable LCD panel when using TV */ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C); } else { /* TW: Disable TV when using LCD */ SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8); } } SiS_DisplayOn(SiS_Pr); if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) { SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr); } return 1;}/* TW: Checked with 650/LVDS (1.10.07) and 630+301B/LVDS BIOS */BOOLEANSiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension){ USHORT temp,temp1,temp2; if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12)) return(1); temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11); SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80); temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00); SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,0x55); temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00); SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,temp1); SiS_SetReg1(SiS_Pr->SiS_P3d4,0x11,temp); if(HwDeviceExtension->jChipType >= SIS_315H) { if(temp2 == 0x55) return(0); else return(1); } else { if(temp2 != 0x55) return(1); else { SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); return(0); } }}/* TW: Set Part1 registers *//* TW: Checked with 650/LVDS (1.10.07), 650/301LV (II) and 630/301B (II) BIOS *//* TW: Pass 2: Checked with 650/301LVx 1.10.6s, 630/301B 2.04.5a */voidSiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT RefreshRateTableIndex){ USHORT temp=0, tempax=0, tempbx=0, tempcx=0, tempbl=0; USHORT pushbx=0, CRT1Index=0;#ifdef SIS315H USHORT pushcx=0;#endif USHORT modeflag, resinfo=0; if(ModeNo<=0x13) { modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; } else { CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; } /* TW: Removed 301B301LV.. check here; LCDA exists with LVDS as well */ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { /* TW: From 650/LVDS BIOS; 301(B+LV) version does not set Sync */ if (SiS_Pr->SiS_IF_DEF_LVDS == 1) { SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo, RefreshRateTableIndex,HwDeviceExtension); } SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension,RefreshRateTableIndex); } else { if( (HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo, RefreshRateTableIndex,HwDeviceExtension); } else { SiS_SetCRT2Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex, RefreshRateTableIndex,HwDeviceExtension); if (HwDeviceExtension->jChipType < SIS_315H ) {#ifdef SIS300 SiS_SetCRT2FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);#endif } else {#ifdef SIS315H SiS_SetCRT2FIFO_310(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);#endif } SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo, RefreshRateTableIndex,HwDeviceExtension); /* 1. Horizontal setup */ if (HwDeviceExtension->jChipType < SIS_315H ) {#ifdef SIS300 /* ------------- 300 series --------------*/ temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp); /* TW: CRT2 Horizontal Total */ temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4; SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* TW: CRT2 Horizontal Total Overflow [7:4] */ temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp); /* TW: CRT2 Horizontal Display Enable End */ pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA@HRS 0x0B,0x0C */ tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2; tempbx = pushbx + tempcx; tempcx <<= 1; tempcx += tempbx; if(SiS_Pr->SiS_IF_DEF_LVDS == 0) { if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){ CRT1Index &= 0x3F; tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4]; tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2); tempbx = (tempbx - 1) << 3; tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5]; tempcx &= 0x1F; temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15]; temp = (temp & 0x04) << (6-2); tempcx = ((tempcx | temp) - 1) << 3; } if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){ if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){ tempbx = 1040; tempcx = 1042; } } } temp = tempbx & 0x00FF; SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp); /* TW: CRT2 Horizontal Retrace Start */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -