init.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:159k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1.   SiS_Pr->SiS_SelectCRT2Rate = 0;
  2.   SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
  3. #ifdef LINUX_XF86
  4.   xf86DrvMsg(0, X_PROBED, "(init: VBType=0x%04x, VBInfo=0x%04x)n",
  5.                     SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
  6. #endif
  7.   if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
  8.      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  9.         SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
  10.      }
  11.   }
  12.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  13. SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
  14.   }
  15.   RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
  16.   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
  17. SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
  18.   }
  19.   if (RefreshRateTableIndex != 0xFFFF) {
  20.      SiS_SetSync(SiS_Pr,ROMAddr,RefreshRateTableIndex);
  21.      SiS_SetCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
  22.      SiS_SetCRT1Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
  23.      SiS_SetCRT1VCLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex);
  24.   }
  25. #ifdef SIS300
  26.   if(HwDeviceExtension->jChipType == SIS_300){
  27.       SiS_SetCRT1FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
  28.   }
  29.   if((HwDeviceExtension->jChipType == SIS_630)||
  30.      (HwDeviceExtension->jChipType == SIS_730)||
  31.      (HwDeviceExtension->jChipType == SIS_540)) {
  32.       SiS_SetCRT1FIFO_630(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
  33.   }
  34. #endif
  35. #ifdef SIS315H
  36.   if(HwDeviceExtension->jChipType >= SIS_315H) {
  37.       SiS_SetCRT1FIFO_310(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
  38.   }
  39. #endif
  40.   SiS_SetCRT1ModeRegs(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex);
  41.   SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
  42. #ifndef LINUX_XF86
  43.   if(SiS_Pr->SiS_flag_clearbuffer) {
  44.         SiS_ClearBuffer(SiS_Pr,HwDeviceExtension,ModeNo);
  45.   }
  46. #endif
  47.   if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {
  48.         SiS_LongWait(SiS_Pr);
  49.         SiS_DisplayOn(SiS_Pr);
  50.   }
  51. }
  52. #ifdef LINUX_XF86
  53. void
  54. SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
  55. {
  56.    SISPtr pSiS = SISPTR(pScrn);
  57.    /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
  58.    if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
  59.        ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
  60.          ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
  61.            ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
  62.     SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
  63.    }
  64.    if (pSiS->VBFlags & DISPTYPE_DISP2) {
  65.     SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
  66.    }
  67. }
  68. void
  69. SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
  70. {
  71.     SISPtr pSiS = SISPTR(pScrn);
  72.     ULong  HDisplay,temp;
  73.     HDisplay = pSiS->scrnPitch / 8;
  74.     SiS_SetReg1(SiS_Pr->SiS_P3d4, 0x13, (HDisplay & 0xFF));
  75.     temp = (SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
  76.     SiS_SetReg1(SiS_Pr->SiS_P3c4, 0x0E, temp);
  77. }
  78. void
  79. SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
  80. {
  81.     SISPtr pSiS = SISPTR(pScrn);
  82.     ULong  HDisplay,temp;
  83.     HDisplay = pSiS->scrnPitch / 8;
  84.     /* Unlock CRT2 */
  85.     if (pSiS->VGAEngine == SIS_315_VGA)
  86.         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2F, 0xFF, 0x01);
  87.     else
  88.         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x24, 0xFF, 0x01);
  89.     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07, (HDisplay & 0xFF));
  90.     temp = (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF);
  91.     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09, temp);
  92. }
  93. #endif
  94. /* TW: Checked against 650/301 and 630/301B BIOS */
  95. /* TW: Re-written for 650/301LVx 1.10.6s BIOS */
  96. void
  97. SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
  98. {
  99.   USHORT flag=0, rev=0, nolcd=0;
  100.   SiS_Pr->SiS_VBType = 0;
  101.   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
  102.   flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
  103.   /* TW: Illegal values not welcome... */
  104.   if(flag > 10) return;
  105.   rev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
  106.   if (flag >= 2) {
  107.         SiS_Pr->SiS_VBType = VB_SIS302B;
  108.   } else if (flag == 1) {
  109.         SiS_Pr->SiS_VBType = VB_SIS301;
  110.         if(rev >= 0xB0) {
  111.              SiS_Pr->SiS_VBType = VB_SIS301B;
  112. if(HwDeviceExtension->jChipType >= SIS_315H) {
  113.          nolcd = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x23);
  114.                     if(!(nolcd & 0x02))
  115.                         SiS_Pr->SiS_VBType |= VB_NoLCD;
  116. }
  117.         }
  118.   }
  119.   if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) {
  120.         if(rev >= 0xD0) {
  121.         SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS302B);
  122.            SiS_Pr->SiS_VBType |= VB_SIS30xLV;
  123. SiS_Pr->SiS_VBType &= ~(VB_NoLCD);
  124. if(rev >= 0xE0) {
  125.     SiS_Pr->SiS_VBType &= ~(VB_SIS30xLV);
  126.     SiS_Pr->SiS_VBType |= VB_SIS30xNEW;
  127. }
  128.         }
  129.   }
  130. }
  131. /* TW: Checked against 650/301LVx 1.10.6s */
  132. BOOLEAN
  133. SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex)
  134. {
  135.    UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
  136.    if(*ModeNo <= 0x13) {
  137.       if((*ModeNo) <= 5) (*ModeNo) |= 1;
  138.       for (*ModeIdIndex=0;;(*ModeIdIndex)++) {
  139.          if (SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
  140.          if (SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)   return FALSE;
  141.       }
  142.       if(*ModeNo == 0x07) {
  143.           if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
  144.           /* else 350 lines */
  145.       }
  146.       if(*ModeNo <= 3) {
  147.          if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
  148.          if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
  149.          /* else 350 lines  */
  150.       }
  151.       /* else 200 lines  */
  152.    } else {
  153.       for (*ModeIdIndex=0;;(*ModeIdIndex)++) {
  154.          if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
  155.          if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)   return FALSE;
  156.       }
  157.    }
  158.    return TRUE;
  159. }
  160. /* For SiS 300 oem util: Search VBModeID */
  161. BOOLEAN
  162. SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
  163. {
  164.    USHORT ModeIdIndex;
  165.    UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
  166.    if(*ModeNo <= 5) *ModeNo |= 1;
  167.    for(ModeIdIndex=0; ; ModeIdIndex++) {
  168.        if (SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
  169.        if (SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)   return FALSE;
  170.    }
  171.    if(*ModeNo != 0x07) {
  172.         if(*ModeNo > 0x03) return ((BOOLEAN)ModeIdIndex);
  173. if(VGAINFO & 0x80) return ((BOOLEAN)ModeIdIndex);
  174. ModeIdIndex++;
  175.    }
  176.    if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
  177.                                /* else 350 lines */
  178.    return ((BOOLEAN)ModeIdIndex);
  179. }
  180. /* TW: Checked against 630/301B, 315 1.09 and 650/301LVx 1.10.6s BIOS */
  181. /* TW: Modified */
  182. BOOLEAN
  183. SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
  184.                     USHORT ModeNo,USHORT ModeIdIndex)
  185. {
  186.   USHORT memorysize,modeflag;
  187.   ULONG  temp;
  188.   if (ModeNo<=0x13) {
  189.       modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  190.   } else {
  191.       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  192.   }
  193.   memorysize = modeflag & MemoryInfoFlag;
  194.   memorysize >>= MemorySizeShift; /* Get required memory size */
  195.   memorysize++;
  196.   temp = GetDRAMSize(SiS_Pr, HwDeviceExtension);        /* Get adapter memory size */
  197.   temp /= (1024*1024);    /* (in MB) */
  198.   if(temp < memorysize) return(FALSE);
  199.   else return(TRUE);
  200. }
  201. UCHAR
  202. SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  203. {
  204.    UCHAR index;
  205.    if(ModeNo<=0x13) {
  206.       index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
  207.    } else {
  208.       if(SiS_Pr->SiS_ModeType <= 0x02) index=0x1B;    /* 02 -> ModeEGA  */
  209.       else index=0x0F;
  210.    }
  211.    return index;
  212. }
  213. /* TW: Checked against 300, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
  214. void
  215. SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
  216. {
  217.    UCHAR SRdata;
  218.    USHORT i;
  219.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x00,0x03);            /* Set SR0  */
  220.    SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
  221.    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  222.        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  223.          SRdata |= 0x01;
  224.         }
  225.    }
  226.    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  227.      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  228.        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  229.          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  230.            SRdata |= 0x01;         /* 8 dot clock  */
  231.          }
  232.        }
  233.      }
  234.      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  235.        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  236.          SRdata |= 0x01;           /* 8 dot clock  */
  237.        }
  238.      }
  239.    }
  240.    SRdata |= 0x20;                 /* screen off  */
  241.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x01,SRdata);
  242.    for(i=02;i<=04;i++) {
  243.         SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
  244.       SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SRdata);
  245.    }
  246. }
  247. /* Checked against 300, 650/301LVx 1.10.6s and 650/LVDS 1.10.07 BIOS */
  248. void
  249. SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
  250. {
  251.    UCHAR Miscdata;
  252.    Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
  253.    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  254.       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  255.         Miscdata |= 0x0C;
  256.       }
  257.     }
  258.    SiS_SetReg3(SiS_Pr->SiS_P3c2,Miscdata);
  259. }
  260. /* Checked against 300, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS (630 code still there!) */
  261. void
  262. SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
  263.                 USHORT StandTableIndex)
  264. {
  265.   UCHAR CRTCdata;
  266.   USHORT i;
  267.   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
  268.   for(i=0;i<=0x18;i++) {
  269.      CRTCdata=SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
  270.      SiS_SetReg1(SiS_Pr->SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
  271.   }
  272.   if( ( (HwDeviceExtension->jChipType == SIS_630) ||
  273.         (HwDeviceExtension->jChipType == SIS_730) )  &&
  274.       (HwDeviceExtension->jChipRevision >= 0x30) ) {           /* for 630S0 */
  275.     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  276.       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
  277.         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
  278.       }
  279.     }
  280.   }
  281. }
  282. /* TW: Checked against 300, 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 630/301B BIOS */
  283. void
  284. SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex,USHORT ModeNo,
  285.                PSIS_HW_DEVICE_INFO HwDeviceExtension)
  286. {
  287.    UCHAR ARdata;
  288.    USHORT i;
  289.    for(i=0;i<=0x13;i++) {
  290.     ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
  291. #if 0
  292.     if((i <= 0x0f) || (i == 0x11)) {
  293.         if(ds:489 & 0x08) {
  294.    continue;
  295.         }
  296.     }
  297. #endif
  298.     if(i == 0x13) {
  299.       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  300.         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  ARdata=0;
  301.       }
  302.       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  303.         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  304.           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  305.             if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
  306.           }
  307.         }
  308.       }
  309.       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  310.         if(HwDeviceExtension->jChipType >= SIS_315H) {
  311.   /* TW: From 650/LVDS 1.10.07, 1.10a; 650/301LVx 1.10.6s */
  312.   ARdata = 0;
  313. } else {
  314.           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  315.      ARdata=0;
  316.           }
  317. }
  318.       }
  319.     }
  320.     SiS_GetReg2(SiS_Pr->SiS_P3da);                              /* reset 3da  */
  321.     SiS_SetReg3(SiS_Pr->SiS_P3c0,i);                            /* set index  */
  322.     SiS_SetReg3(SiS_Pr->SiS_P3c0,ARdata);                       /* set data   */
  323.    }
  324.    SiS_GetReg2(SiS_Pr->SiS_P3da);                               /* reset 3da  */
  325.    SiS_SetReg3(SiS_Pr->SiS_P3c0,0x14);                          /* set index  */
  326.    SiS_SetReg3(SiS_Pr->SiS_P3c0,0x00);                          /* set data   */
  327.    SiS_GetReg2(SiS_Pr->SiS_P3da);                               /* Enable Attribute  */
  328.    SiS_SetReg3(SiS_Pr->SiS_P3c0,0x20);
  329. }
  330. /* TW: Checked against 300, 650/LVDS (1.10.07, 1.10a) and 650/301LV BIOS */
  331. void
  332. SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
  333. {
  334.    UCHAR GRdata;
  335.    USHORT i;
  336.    for(i=0;i<=0x08;i++) {
  337.      GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];     /* Get GR from file */
  338.      SiS_SetReg1(SiS_Pr->SiS_P3ce,i,GRdata);                    /* Set GR(3ce) */
  339.    }
  340.    if(SiS_Pr->SiS_ModeType > ModeVGA) {
  341.      SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF); /* 256 color disable */
  342.    }
  343. }
  344. /* TW: Checked against 650/LVDS (1.10.07, 1.10a), 650/301LVx (1.10.6s) and 630/301B BIOS */
  345. void
  346. SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
  347. {
  348.   USHORT i;
  349.   for(i=0x0A;i<=0x0E;i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0x00);      /* Clear SR0A-SR0E */
  350.   /* TW: New from 650/LVDS/301LV BIOSes: */
  351.   if(HwDeviceExtension->jChipType >= SIS_315H) {
  352.      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
  353.   }
  354. }
  355. /* TW: Checked against 300, 650/LVDS (1.10.07) and 650/301LV BIOS */
  356. void
  357. SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex)
  358. {
  359.   USHORT sync;
  360.   USHORT temp;
  361.   sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
  362.   sync &= 0xC0;
  363.   temp = 0x2F | sync;
  364.   SiS_SetReg3(SiS_Pr->SiS_P3c2,temp);                                 /* Set Misc(3c2) */
  365. }
  366. /* TW: Checked against 300, 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS */
  367. void
  368. SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  369.                 USHORT RefreshRateTableIndex,
  370. PSIS_HW_DEVICE_INFO HwDeviceExtension)
  371. {
  372.   UCHAR  index;
  373.   USHORT tempah,i,modeflag,j;
  374. #ifdef SIS315H
  375.   USHORT temp;
  376.   USHORT ResInfo,DisplayType;
  377.   const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
  378. #endif
  379.   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /*unlock cr0-7  */
  380.   if(ModeNo<=0x13) {
  381.         modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  382.   } else {
  383.         modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  384.   }
  385.   if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
  386. #ifdef SIS315H
  387.      /* LCDA */
  388.      temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
  389.                        RefreshRateTableIndex,&ResInfo,&DisplayType);
  390.      switch(DisplayType) {
  391.       case Panel_800x600       : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1;           break;
  392.       case Panel_1024x768      : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;          break;
  393.       case Panel_1280x1024     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1;         break;
  394.       case Panel_1400x1050     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1;         break;
  395.       case Panel_1600x1200     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1;         break;
  396.       case Panel_800x600 + 16  : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1_H;         break;
  397.       case Panel_1024x768 + 16 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H;        break;
  398.       case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H;       break;
  399.       case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H;       break;
  400.       case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H;       break;
  401.       case Panel_800x600 + 32  : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2;           break;
  402.       case Panel_1024x768 + 32 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2;          break;
  403.       case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2;         break;
  404.       case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2;         break;
  405.       case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2;         break;
  406.       case Panel_800x600 + 48  : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2_H;         break;
  407.       case Panel_1024x768 + 48 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H;        break;
  408.       case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H;       break;
  409.       case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H;       break;
  410.       case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H;       break;
  411.       default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;          break;
  412.      }
  413.      tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
  414.      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
  415.      for(i=0x01,j=1;i<=0x07;i++,j++){
  416.        tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
  417.        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  418.      }
  419.      for(i=0x10,j=8;i<=0x12;i++,j++){
  420.        tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
  421.        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  422.      }
  423.      for(i=0x15,j=11;i<=0x16;i++,j++){
  424.        tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
  425.        SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  426.      }
  427.      for(i=0x0A,j=13;i<=0x0C;i++,j++){
  428.        tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
  429.        SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
  430.      }
  431.      tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
  432.      tempah &= 0x0E0;
  433.      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
  434.      tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
  435.      tempah &= 0x01;
  436.      tempah <<= 5;
  437.      if(modeflag & DoubleScanMode)  tempah |= 0x080;
  438.      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
  439. #endif
  440.   } else {
  441.      /* LVDS, 301, 301B, 301LV, 302LV, ... (non-LCDA) */
  442.      index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;   /* Get index */
  443.      if(HwDeviceExtension->jChipType < SIS_315H) {
  444.         index &= 0x3F;
  445.      }
  446.      for(i=0,j=0;i<=07;i++,j++) {
  447.        tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
  448.        SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
  449.      }
  450.      for(j=0x10;i<=10;i++,j++) {
  451.        tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
  452.        SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
  453.      }
  454.      for(j=0x15;i<=12;i++,j++) {
  455.        tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
  456.        SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
  457.      }
  458.      for(j=0x0A;i<=15;i++,j++) {
  459.        tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
  460.        SiS_SetReg1(SiS_Pr->SiS_P3c4,j,tempah);
  461.      }
  462.      tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
  463.      tempah &= 0xE0;
  464.      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
  465.      tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
  466.      tempah &= 0x01;
  467.      tempah <<= 5;
  468.      if(modeflag & DoubleScanMode)  tempah |= 0x80;
  469.      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
  470.   }
  471.   if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg1(SiS_Pr->SiS_P3d4,0x14,0x4F);
  472. }
  473. BOOLEAN
  474. SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  475.    USHORT RefreshRateTableIndex,USHORT *ResInfo,
  476.    USHORT *DisplayType)
  477.  {
  478.   USHORT tempbx=0,modeflag=0;
  479.   USHORT CRT2CRTC=0;
  480.   if(ModeNo<=0x13) {
  481.    modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  482.    CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
  483.   } else {
  484.    modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  485.    CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
  486.   }
  487.   tempbx = SiS_Pr->SiS_LCDResInfo;
  488.   if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 32;
  489.   if(modeflag & HalfDCLK)                   tempbx += 16;
  490.   *ResInfo = CRT2CRTC & 0x3F;
  491.   *DisplayType = tempbx;
  492.   return 1;
  493. }
  494. /* TW: Set offset and pitch - partly overruled by SetPitch() in XF86 */
  495. /* TW: Checked against 650/LVDS (1.10.07), 650/301LV and 315 BIOS */
  496. void
  497. SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  498.                   USHORT RefreshRateTableIndex,
  499.   PSIS_HW_DEVICE_INFO HwDeviceExtension)
  500. {
  501.    USHORT temp, DisplayUnit, infoflag;
  502.    infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
  503.    DisplayUnit = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
  504.                      RefreshRateTableIndex,HwDeviceExtension);
  505.    temp = (DisplayUnit >> 8) & 0x0f;
  506.    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
  507.    temp = DisplayUnit & 0xFF;
  508.    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x13,temp);
  509.    if(infoflag & InterlaceMode) DisplayUnit >>= 1;
  510.    DisplayUnit <<= 5;
  511.    temp = (DisplayUnit & 0xff00) >> 8;
  512.    if (DisplayUnit & 0xff) temp++;
  513.    temp++;
  514.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x10,temp);
  515. }
  516. /* TW: New from 650/LVDS 1.10.07, 630/301B and 630/LVDS BIOS */
  517. void
  518. SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
  519. {
  520.    USHORT index;
  521.    /* TW: We only need to do this if Panel Link is to be
  522.     *     initialized, thus on 630/LVDS/301B, and 650/LVDS
  523.     */
  524.    if(HwDeviceExtension->jChipType >= SIS_315H) {
  525.        if (SiS_Pr->SiS_IF_DEF_LVDS == 0)  return;
  526.    } else {
  527.        if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
  528.            (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
  529.    return;
  530.       }
  531.    }
  532.    if(HwDeviceExtension->jChipType >= SIS_315H) {
  533.     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
  534.    } else {
  535.     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
  536.    }
  537.    index = 1;
  538.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
  539.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
  540.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
  541.    if(HwDeviceExtension->jChipType >= SIS_315H) {
  542.     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
  543.    } else {
  544.     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
  545.    }
  546.    index = 0;
  547.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
  548.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
  549.    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
  550. }
  551. /* TW: Checked against 300, 650/LVDS, 650/301LVx, 315, 630/301B, 630/LVDS BIOS */
  552. void
  553. SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  554.                 PSIS_HW_DEVICE_INFO HwDeviceExtension,
  555. USHORT RefreshRateTableIndex)
  556. {
  557.   USHORT  index;
  558.   index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
  559.                   RefreshRateTableIndex,HwDeviceExtension);
  560.   if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
  561.                        && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){
  562.      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
  563.      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VBVCLKData[index].Part4_A);
  564.      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VBVCLKData[index].Part4_B);
  565.      if(HwDeviceExtension->jChipType >= SIS_315H) {
  566. SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
  567.     } else {
  568.      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
  569.      }
  570.   } else {
  571. if(HwDeviceExtension->jChipType >= SIS_315H) {
  572.     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
  573. } else {
  574.     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
  575. }
  576.      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
  577.      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
  578.      if(HwDeviceExtension->jChipType >= SIS_315H) {
  579.     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
  580. } else {
  581.            SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
  582.         }
  583.   }
  584. }
  585. #if 0  /* TW: Not used */
  586. void
  587. SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  588. {
  589.   USHORT ModeFlag;
  590.   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0x7F);
  591.   if(ModeNo > 0x13) {
  592.     ModeFlag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  593.     if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
  594.       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x80);
  595.       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xF7);
  596.     }
  597.   }
  598. }
  599. #endif
  600. /* TW: Checked against 300, 630/LVDS, 650/LVDS and 315 BIOS */
  601. void
  602. SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
  603.                     USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
  604. {
  605.   USHORT data,data2,data3;
  606.   USHORT infoflag=0,modeflag;
  607.   USHORT resindex,xres;
  608.   if(ModeNo > 0x13) {
  609.      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  610.      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
  611.   } else {
  612.      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  613.   }
  614.   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);  /* DAC pedestal */
  615.   if(ModeNo > 0x13) data = infoflag;
  616.   else data = 0;
  617.   data2 = 0;
  618.   if(ModeNo > 0x13) {
  619.     if(SiS_Pr->SiS_ModeType > 0x02) {
  620.        data2 |= 0x02;
  621.        data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
  622.        data2 |= data3;
  623.     }
  624.   }
  625.   if(data & InterlaceMode) data2 |= 0x20;
  626.   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0, data2);
  627.   resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
  628.   if(ModeNo <= 0x13) {
  629.        xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
  630.   } else {
  631.        xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
  632.   }
  633.   if(HwDeviceExtension->jChipType != SIS_300) {
  634.      data = 0x0000;
  635.      if(infoflag & InterlaceMode) {
  636.         if(xres == 1024) data = 0x0035;
  637.         else data = 0x0048;
  638.      }
  639.      data2 = data & 0x00FF;
  640.      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data2);
  641.      data2 = (data & 0xFF00) >> 8;
  642.      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,data2);
  643.   }
  644.   if(modeflag & HalfDCLK) {
  645.      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
  646.   }
  647.   if(HwDeviceExtension->jChipType == SIS_300) {
  648.      if(modeflag & LineCompareOff) {
  649.         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x08);
  650.      } else {
  651.         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xF7);
  652.      }
  653.   } else if(HwDeviceExtension->jChipType < SIS_315H) {
  654.      if(modeflag & LineCompareOff) {
  655.         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
  656.      } else {
  657.         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
  658.      }
  659.      /* 630 BIOS does something for mode 0x12 here */
  660.   } else {
  661.      if(modeflag & LineCompareOff) {
  662.         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
  663.      } else {
  664.         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
  665.      }
  666.   }
  667.   if(HwDeviceExtension->jChipType != SIS_300) {
  668.      if(SiS_Pr->SiS_ModeType == ModeEGA) {
  669.         if(ModeNo > 0x13) {
  670.       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
  671.         }
  672.      }
  673.   }
  674. #ifdef SIS315H
  675.   /* TW: 315 BIOS sets SR17 at this point */
  676.   if(HwDeviceExtension->jChipType == SIS_315PRO) {
  677.       data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
  678.       data = SiS_Pr->SiS_SR15[2][data];
  679.       if(SiS_Pr->SiS_ModeType == ModeText) {
  680.           data &= 0xc7;
  681.       } else {
  682.           data2 = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
  683.                                 RefreshRateTableIndex,HwDeviceExtension);
  684.   data2 >>= 1;
  685.   if(infoflag & InterlaceMode) data2 >>= 1;
  686.   data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
  687.   data3 >>= 1;
  688.   if(data3 == 0) data3++;
  689.   data2 /= data3;
  690.   if(data2 >= 0x50) {
  691.       data &= 0x0f;
  692.       data |= 0x50;
  693.   }
  694.       }
  695.       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data);
  696.   }
  697. #endif
  698.   data = 0x60;
  699.   if(SiS_Pr->SiS_ModeType != ModeText) {
  700.       data ^= 0x60;
  701.       if(SiS_Pr->SiS_ModeType != ModeEGA) {
  702.         data ^= 0xA0;
  703.       }
  704.   }
  705.   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
  706.   SiS_SetVCLKState(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex);
  707. #ifdef SIS315H
  708.   if(HwDeviceExtension->jChipType >= SIS_315H) {
  709.     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
  710.         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x2c);
  711.     } else {
  712.         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x6c);
  713.     }
  714.   }
  715. #endif
  716. }
  717. /* TW: Checked against 300, 315, 650/LVDS, 650/301LVx, 630/301B and 630/LVDS BIOS */
  718. void
  719. SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
  720.                  USHORT ModeNo,USHORT RefreshRateTableIndex,
  721.                  USHORT ModeIdIndex)
  722. {
  723.   USHORT data, data2=0;
  724.   USHORT VCLK, index=0;
  725.   if (ModeNo <= 0x13) VCLK = 0;
  726.   else {
  727.      index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
  728.                RefreshRateTableIndex,HwDeviceExtension);
  729.      VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
  730.   }
  731.   if(HwDeviceExtension->jChipType < SIS_315H) { /* 300 series */
  732.     data2 = 0x00;
  733.     if(VCLK > 150) data2 |= 0x80;
  734.     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2);  /* DAC speed */
  735.     data2 = 0x00;
  736.     if(VCLK >= 150) data2 |= 0x08;        /* VCLK > 150 */
  737.     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
  738.   } else {  /* 310/325 series */
  739.     data = 0;
  740.     if(VCLK >= 166) data |= 0x0c;          /* TW: Was 200; is 166 in 650 and 315 BIOSes */
  741.     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
  742.     if(VCLK >= 166) { /* TW: Was 200, is 166 in 650 and 315 BIOSes */
  743.        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
  744.     }
  745. #if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
  746.     data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);    /* DAC pedestal */
  747.     data &= 0xE7;
  748.     if(VCLK<200) data |= 0x10;
  749.     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data);    /* DAC pedestal */
  750. #endif
  751.   }
  752.   data2 = 0x03;
  753.   if((VCLK >= 135) && (VCLK < 160)) data2 = 0x02;
  754.   if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
  755.   if(VCLK >= 260) data2 = 0x00;
  756.   /* disable 24bit palette RAM gamma correction  */
  757.   if(HwDeviceExtension->jChipType == SIS_540) {
  758.      if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
  759.   }
  760.   if(HwDeviceExtension->jChipType < SIS_315H) {
  761.       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2);   /* DAC speed */
  762.   } else {
  763.       if(HwDeviceExtension->jChipType > SIS_315PRO) {
  764.          /* TW: This "if" is done in 650/LVDS/301LV BIOSes; Not in 315 BIOS */
  765.          if(ModeNo > 0x13) data2 &= 0xfc;
  766.       }
  767.       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2);   /* DAC speed */
  768.   }
  769. }
  770. /* TW: Checked against 650/301LVx 1.10.6s, 315, 630/301B BIOS */
  771. void
  772. SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
  773.             UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  774. {
  775.    USHORT data,data2;
  776.    USHORT time,i,j,k;
  777.    USHORT m,n,o;
  778.    USHORT si,di,bx,dl;
  779.    USHORT al,ah,dh;
  780.    USHORT DACAddr, DACData, shiftflag;
  781.    const USHORT *table = NULL;
  782. #if 0
  783.    USHORT tempah,tempch,tempcl,tempdh,tempal,tempbx;
  784. #endif
  785.    if (ModeNo<=0x13)
  786.         data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  787.    else
  788.         data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  789. #if 0
  790.    if(!(ds:489 & 0x08)) {
  791. #endif
  792. data &= DACInfoFlag;
  793. time = 64;
  794. if(data == 0x00) table = SiS_MDA_DAC;
  795. if(data == 0x08) table = SiS_CGA_DAC;
  796. if(data == 0x10) table = SiS_EGA_DAC;
  797. if(data == 0x18) {
  798.    time = 256;
  799.    table = SiS_VGA_DAC;
  800. }
  801. if(time == 256) j = 16;
  802. else            j = time;
  803. if( ( (HwDeviceExtension->jChipType < SIS_315H) &&         /* 630/301B */
  804.       (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
  805.       (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) )         ||
  806.     (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)            ||     /* LCDA */
  807.     (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) {         /* Programming CRT1 */
  808.    DACAddr = SiS_Pr->SiS_P3c8;
  809.    DACData = SiS_Pr->SiS_P3c9;
  810.    shiftflag = 0;
  811.    SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
  812. } else {
  813.    shiftflag = 1;
  814.    DACAddr = SiS_Pr->SiS_Part5Port;
  815.    DACData = SiS_Pr->SiS_Part5Port + 1;
  816. }
  817. SiS_SetReg3(DACAddr,0x00);
  818. for(i=0; i<j; i++) {
  819.    data = table[i];
  820.    for(k=0; k<3; k++) {
  821. data2 = 0;
  822. if(data & 0x01) data2 = 0x2A;
  823. if(data & 0x02) data2 += 0x15;
  824. if(shiftflag) data2 <<= 2;
  825. SiS_SetReg3(DACData,data2);
  826. data >>= 2;
  827.    }
  828. }
  829. if(time == 256) {
  830.    for(i = 16; i < 32; i++) {
  831. data = table[i];
  832. if(shiftflag) data <<= 2;
  833. for(k=0; k<3; k++) SiS_SetReg3(DACData,data);
  834.    }
  835.    si = 32;
  836.    for(m = 0; m < 9; m++) {
  837.       di = si;
  838.       bx = si + 4;
  839.       dl = 0;
  840.       for(n = 0; n < 3; n++) {
  841.  for(o = 0; o < 5; o++) {
  842.     dh = table[si];
  843.     ah = table[di];
  844.     al = table[bx];
  845.     si++;
  846.     SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
  847.  }
  848.  si -= 2;
  849.  for(o = 0; o < 3; o++) {
  850.     dh = table[bx];
  851.     ah = table[di];
  852.     al = table[si];
  853.     si--;
  854.     SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
  855.  }
  856.  dl++;
  857.       }            /* for n < 3 */
  858.       si += 5;
  859.    }               /* for m < 9 */
  860. }
  861. #if 0
  862.     }  /* ds:489 & 0x08 */
  863. #endif
  864. #if 0
  865.     if((!(ds:489 & 0x08)) && (ds:489 & 0x06)) {
  866.            tempbx = 0;
  867.    for(i=0; i< 256; i++) {
  868.                SiS_SetReg3(SiS_Pr->SiS_P3c8-1,tempbx);     /* 7f87 */
  869.                tempah = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);   /* 7f83 */
  870.        tempch = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);
  871.        tempcl = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);
  872.        tempdh = tempah;
  873.        tempal = 0x4d * tempdh;           /* 7fb8 */
  874.        tempbx += tempal;
  875.        tempal = 0x97 * tempch;
  876.        tempbx += tempal;
  877.        tempal = 0x1c * tempcl;
  878.        tempbx += tempal;
  879.        if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
  880.        tempdh = (tempbx & 0x00ff) >> 8;
  881.        tempch = tempdh;
  882.        tempcl = tempdh;
  883.        SiS_SetReg3(SiS_Pr->SiS_P3c8,(tempbx & 0xff));   /* 7f7c */
  884.        SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempdh);          /* 7f92 */
  885.        SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempch);
  886.        SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempcl);
  887.            }
  888.     }
  889. #endif
  890. }
  891. void
  892. SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT DACData, USHORT shiftflag,
  893.              USHORT dl, USHORT ah, USHORT al, USHORT dh)
  894. {
  895.   USHORT temp;
  896.   USHORT bh,bl;
  897.   bh = ah;
  898.   bl = al;
  899.   if(dl != 0) {
  900.     temp = bh;
  901.     bh = dh;
  902.     dh = temp;
  903.     if(dl == 1) {
  904.        temp = bl;
  905.        bl = dh;
  906.        dh = temp;
  907.     } else {
  908.        temp = bl;
  909.        bl = bh;
  910.        bh = temp;
  911.     }
  912.   }
  913.   if(shiftflag) {
  914.      dh <<= 2;
  915.      bh <<= 2;
  916.      bl <<= 2;
  917.   }
  918.   SiS_SetReg3(DACData,(USHORT)dh);
  919.   SiS_SetReg3(DACData,(USHORT)bh);
  920.   SiS_SetReg3(DACData,(USHORT)bl);
  921. }
  922. ULONG
  923. GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
  924. {
  925.   ULONG   AdapterMemorySize = 0;
  926. #ifdef SIS315H
  927.   USHORT  counter;
  928. #endif
  929. #ifdef SIS315H
  930.   if ((HwDeviceExtension->jChipType == SIS_315H) ||
  931.       (HwDeviceExtension->jChipType == SIS_315PRO)) {
  932.      counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
  933. AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
  934. counter >>= 2;
  935. counter &= 0x03;
  936. if(counter == 0x02) {
  937. AdapterMemorySize += (AdapterMemorySize / 2);      /* DDR asymetric */
  938. } else if(counter != 0) {
  939. AdapterMemorySize <<= 1;                           /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */
  940. }
  941. AdapterMemorySize *= (1024*1024);
  942.   } else if((HwDeviceExtension->jChipType == SIS_550) ||
  943.             (HwDeviceExtension->jChipType == SIS_640) ||
  944.             (HwDeviceExtension->jChipType == SIS_740) ||
  945.             (HwDeviceExtension->jChipType == SIS_650)) {
  946.        counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
  947.        counter++;
  948.        AdapterMemorySize = counter * 4;
  949.        AdapterMemorySize *= (1024*1024);
  950.   }
  951. #endif
  952. #ifdef SIS300
  953.   if ((HwDeviceExtension->jChipType==SIS_300) ||
  954.       (HwDeviceExtension->jChipType==SIS_540) ||
  955.       (HwDeviceExtension->jChipType==SIS_630) ||
  956.       (HwDeviceExtension->jChipType==SIS_730)) {
  957.        AdapterMemorySize = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
  958.        AdapterMemorySize++;
  959.        AdapterMemorySize *= (1024*1024);
  960.   }
  961. #endif
  962.   return AdapterMemorySize;
  963. }
  964. #ifndef LINUX_XF86
  965. void
  966. SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
  967. {
  968.   PVOID   VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress;
  969.   ULONG   AdapterMemorySize  = (ULONG)HwDeviceExtension->ulVideoMemorySize;
  970.   PUSHORT pBuffer;
  971.   int i;
  972.   if (SiS_Pr->SiS_ModeType>=ModeEGA) {
  973.     if(ModeNo > 0x13) {
  974.       AdapterMemorySize = GetDRAMSize(SiS_Pr, HwDeviceExtension);
  975.       SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
  976.     } else {
  977.       pBuffer = VideoMemoryAddress;
  978.       for(i=0; i<0x4000; i++)
  979.          pBuffer[i] = 0x0000;
  980.     }
  981.   } else {
  982.     pBuffer = VideoMemoryAddress;
  983.     if (SiS_Pr->SiS_ModeType < ModeCGA) {
  984.       for(i=0; i<0x4000; i++)
  985.          pBuffer[i] = 0x0720;
  986.     } else {
  987.       SiS_SetMemory(VideoMemoryAddress,0x8000,0);
  988.     }
  989.   }
  990. }
  991. #endif
  992. void
  993. SiS_DisplayOn(SiS_Private *SiS_Pr)
  994. {
  995.    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
  996. }
  997. void
  998. SiS_DisplayOff(SiS_Private *SiS_Pr)
  999. {
  1000.    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
  1001. }
  1002. /* ========================================== */
  1003. /*  SR CRTC GR */
  1004. void
  1005. SiS_SetReg1(USHORT port, USHORT index, USHORT data)
  1006. {
  1007.    OutPortByte(port,index);
  1008.    OutPortByte(port+1,data);
  1009. }
  1010. /* ========================================== */
  1011. /*  AR(3C0) */
  1012. void
  1013. SiS_SetReg2(SiS_Private *SiS_Pr, USHORT port, USHORT index, USHORT data)
  1014. {
  1015.    InPortByte(port+0x3da-0x3c0);
  1016.    OutPortByte(SiS_Pr->SiS_P3c0,index);
  1017.    OutPortByte(SiS_Pr->SiS_P3c0,data);
  1018.    OutPortByte(SiS_Pr->SiS_P3c0,0x20);
  1019. }
  1020. void
  1021. SiS_SetReg3(USHORT port, USHORT data)
  1022. {
  1023.    OutPortByte(port,data);
  1024. }
  1025. void
  1026. SiS_SetReg4(USHORT port, ULONG data)
  1027. {
  1028.    OutPortLong(port,data);
  1029. }
  1030. UCHAR SiS_GetReg1(USHORT port, USHORT index)
  1031. {
  1032.    UCHAR   data;
  1033.    OutPortByte(port,index);
  1034.    data = InPortByte(port+1);
  1035.    return(data);
  1036. }
  1037. UCHAR
  1038. SiS_GetReg2(USHORT port)
  1039. {
  1040.    UCHAR   data;
  1041.    data= InPortByte(port);
  1042.    return(data);
  1043. }
  1044. ULONG
  1045. SiS_GetReg3(USHORT port)
  1046. {
  1047.    ULONG   data;
  1048.    data = InPortLong(port);
  1049.    return(data);
  1050. }
  1051. void
  1052. SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
  1053. {
  1054.    int i;
  1055.    OutPortByte(port, 0);
  1056.    port++;
  1057.    for (i=0; i < (256 * 3); i++) {
  1058.       OutPortByte(port, 0);
  1059.    }
  1060. }
  1061. #if 0  /* TW: Unused */
  1062. void
  1063. SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex)
  1064. {
  1065.   ULONG Temp;
  1066.   USHORT data,Temp2;
  1067.   if (ModeNo<=0x13) return;
  1068.   Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x01);
  1069.   Temp++;
  1070.   Temp <<= 3;
  1071.   if(Temp == 1024) data = 0x0035;
  1072.   else if(Temp == 1280) data = 0x0048;
  1073.   else data = 0x0000;
  1074.   Temp2 = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
  1075.   Temp2 &= InterlaceMode;
  1076.   if(Temp2 == 0) data=0x0000;
  1077.   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data);
  1078.   Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x1A);
  1079.   Temp = (USHORT)(Temp & 0xFC);
  1080.   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp);
  1081.   Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x0f);
  1082.   Temp2 = (USHORT)Temp & 0xBF;
  1083.   if(ModeNo==0x37) Temp2 |= 0x40;
  1084.   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp2);
  1085. }
  1086. #endif
  1087. /* TW: Checked against 650/LVDS (1.10.07), 650/301LVx (1.10.6s) and 315 BIOS */
  1088. #ifdef SIS315H
  1089. void
  1090. SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  1091.                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
  1092. {
  1093.   USHORT modeflag;
  1094.   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
  1095.   if(ModeNo > 0x13) {
  1096.     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  1097.     if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
  1098.        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0x34);
  1099.        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
  1100.        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
  1101.     } else {
  1102.        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
  1103.        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
  1104.     }
  1105.   } else {
  1106.     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
  1107.     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
  1108.   }
  1109. }
  1110. #endif
  1111. #ifdef SIS300
  1112. void
  1113. SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
  1114.                     USHORT RefreshRateTableIndex)
  1115. {
  1116.   USHORT  ThresholdLow = 0;
  1117.   USHORT  index, VCLK, MCLK, colorth=0;
  1118.   USHORT  tempah, temp;
  1119.   if(ModeNo > 0x13) {
  1120.      index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  1121.      index &= 0x3F;
  1122.      VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
  1123.      switch (SiS_Pr->SiS_ModeType - ModeEGA) {     /* Get half colordepth */
  1124.         case 0 : colorth = 1; break;
  1125.         case 1 : colorth = 1; break;
  1126.         case 2 : colorth = 2; break;
  1127.         case 3 : colorth = 2; break;
  1128.         case 4 : colorth = 3; break;
  1129.         case 5 : colorth = 4; break;
  1130.      }
  1131.      index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
  1132.      index &= 0x07;
  1133.      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
  1134.      tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
  1135.      tempah &= 0xc3;
  1136.      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
  1137.      do {
  1138.         ThresholdLow = SiS_CalcDelay(SiS_Pr, ROMAddr, VCLK, colorth, MCLK);
  1139.         ThresholdLow++;
  1140.         if(ThresholdLow < 0x13) break;
  1141.         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
  1142.         ThresholdLow = 0x13;
  1143.         tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
  1144.         tempah >>= 6;
  1145.         if(!(tempah)) break;
  1146.         tempah--;
  1147.         tempah <<= 6;
  1148.         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
  1149.      } while(0);
  1150.   } else ThresholdLow = 2;
  1151.   /* Write CRT/CPU threshold low, CRT/Engine threshold high */
  1152.   temp = (ThresholdLow << 4) | 0x0f;
  1153.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,temp);
  1154.   temp = (ThresholdLow & 0x10) << 1;
  1155.   if(ModeNo > 0x13) temp |= 0x40;
  1156.   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
  1157.   /* What is this? */
  1158.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
  1159.   /* Write CRT/CPU threshold high */
  1160.   temp = ThresholdLow + 3;
  1161.   if(temp > 0x0f) temp = 0x0f;
  1162.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x09,temp);
  1163. }
  1164. USHORT
  1165. SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
  1166. {
  1167.   USHORT tempax, tempbx;
  1168.   tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
  1169.   tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
  1170.   if(tempax < 4) tempax = 4;
  1171.   tempax -= 4;
  1172.   if(tempbx < tempax) tempbx = tempax;
  1173.   return(tempbx);
  1174. }
  1175. USHORT
  1176. SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
  1177. {
  1178.   const UCHAR ThLowA[]   = { 61, 3,52, 5,68, 7,100,11,
  1179.                              43, 3,42, 5,54, 7, 78,11,
  1180.                              34, 3,37, 5,47, 7, 67,11 };
  1181.   const UCHAR ThLowB[]   = { 81, 4,72, 6,88, 8,120,12,
  1182.                              55, 4,54, 6,66, 8, 90,12,
  1183.                              42, 4,45, 6,55, 8, 75,12 };
  1184.   const UCHAR ThTiming[] = {  1, 2, 2, 3, 0, 1,  1, 2 };
  1185.   USHORT tempah, tempal, tempcl, tempbx, temp;
  1186.   ULONG  longtemp;
  1187.   tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
  1188.   tempah &= 0x62;
  1189.   tempah >>= 1;
  1190.   tempal = tempah;
  1191.   tempah >>= 3;
  1192.   tempal |= tempah;
  1193.   tempal &= 0x07;
  1194.   tempcl = ThTiming[tempal];
  1195.   tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
  1196.   tempbx >>= 6;
  1197.   tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
  1198.   tempah >>= 4;
  1199.   tempah &= 0x0c;
  1200.   tempbx |= tempah;
  1201.   tempbx <<= 1;
  1202.   if(key == 0) {
  1203.      tempal = ThLowA[tempbx + 1];
  1204.      tempal *= tempcl;
  1205.      tempal += ThLowA[tempbx];
  1206.   } else {
  1207.      tempal = ThLowB[tempbx + 1];
  1208.      tempal *= tempcl;
  1209.      tempal += ThLowB[tempbx];
  1210.   }
  1211.   longtemp = tempal * VCLK * colordepth;
  1212.   temp = longtemp % (MCLK * 16);
  1213.   longtemp /= (MCLK * 16);
  1214.   if(temp) longtemp++;
  1215.   return((USHORT)longtemp);
  1216. }
  1217. #if 0  /* TW: Old fragment, unused */
  1218. USHORT
  1219. SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT key)
  1220. {
  1221.   USHORT data,data2,temp0,temp1;
  1222.   UCHAR   ThLowA[]=   {61,3,52,5,68,7,100,11,
  1223.                        43,3,42,5,54,7, 78,11,
  1224.                        34,3,37,5,47,7, 67,11};
  1225.   UCHAR   ThLowB[]=   {81,4,72,6,88,8,120,12,
  1226.                        55,4,54,6,66,8, 90,12,
  1227.                        42,4,45,6,55,8, 75,12};
  1228.   UCHAR   ThTiming[]= {1,2,2,3,0,1,1,2};
  1229.   data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
  1230.   data=data>>6;
  1231.   data2=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
  1232.   data2=(data2>>4)&0x0C;
  1233.   data=data|data2;
  1234.   data=data<1;
  1235.   if(key==0) {
  1236.     temp0=(USHORT)ThLowA[data];
  1237.     temp1=(USHORT)ThLowA[data+1];
  1238.   } else {
  1239.     temp0=(USHORT)ThLowB[data];
  1240.     temp1=(USHORT)ThLowB[data+1];
  1241.   }
  1242.   data2=0;
  1243.   data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
  1244.   if(data&0x02) data2=data2|0x01;
  1245.   if(data&0x20) data2=data2|0x02;
  1246.   if(data&0x40) data2=data2|0x04;
  1247.   data=temp1*ThTiming[data2]+temp0;
  1248.   return(data);
  1249. }
  1250. #endif
  1251. void
  1252. SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
  1253.                     USHORT RefreshRateTableIndex)
  1254. {
  1255.   USHORT  i,index,data,VCLK,MCLK,colorth=0;
  1256.   ULONG   B,eax,bl,data2;
  1257.   USHORT  ThresholdLow=0;
  1258.   UCHAR   FQBQData[]= { 0x01,0x21,0x41,0x61,0x81,
  1259.                         0x31,0x51,0x71,0x91,0xb1,
  1260.                         0x00,0x20,0x40,0x60,0x80,
  1261.                         0x30,0x50,0x70,0x90,0xb0,0xFF};
  1262.   i=0;
  1263.   if(ModeNo >= 0x13) {
  1264.     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  1265.     index &= 0x3F;
  1266.     VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
  1267.     index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
  1268.     index &= 0x07;
  1269.     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
  1270.     data2 = SiS_Pr->SiS_ModeType - ModeEGA;   /* Get half colordepth */
  1271.     switch (data2) {
  1272.         case 0 : colorth = 1; break;
  1273.         case 1 : colorth = 1; break;
  1274.         case 2 : colorth = 2; break;
  1275.         case 3 : colorth = 2; break;
  1276.         case 4 : colorth = 3; break;
  1277.         case 5 : colorth = 4; break;
  1278.     }
  1279.     do{
  1280.        B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData[i]) * VCLK * colorth;
  1281.        bl = B / (MCLK * 16);
  1282.        if (B==bl*16*MCLK) {
  1283.          bl = bl + 1;
  1284.        } else {
  1285.          bl = bl + 2;
  1286.        }
  1287.        if(bl > 0x13) {
  1288.           if(FQBQData[i+1] == 0xFF) {
  1289.              ThresholdLow = 0x13;
  1290.              break;
  1291.           }
  1292.           i++;
  1293.        } else {
  1294.           ThresholdLow = bl;
  1295.           break;
  1296.        }
  1297.     } while(FQBQData[i] != 0xFF);
  1298.   }
  1299.   else {
  1300.     ThresholdLow = 0x02;
  1301.   }
  1302.   /* Write foreground and background queue */
  1303.   data2 = FQBQData[i];
  1304.   data2 = (data2 & 0xf0)>>4;
  1305.   data2 <<= 24;
  1306. #ifndef LINUX_XF86
  1307.   SiS_SetReg4(0xcf8,0x80000050);
  1308.   eax = SiS_GetReg3(0xcfc);
  1309.   eax &= 0xf0ffffff;
  1310.   eax |= data2;
  1311.   SiS_SetReg4(0xcfc,eax);
  1312. #else
  1313.   /* We use pci functions X offers. We use pcitag 0, because
  1314.    * we want to read/write to the host bridge (which is always
  1315.    * 00:00.0 on 630, 730 and 540), not the VGA device.
  1316.    */
  1317.   eax = pciReadLong(0x00000000, 0x50);
  1318.   eax &= 0xf0ffffff;
  1319.   eax |= data2;
  1320.   pciWriteLong(0x00000000, 0x50, eax);
  1321. #endif
  1322.   /* TODO: write GUI grant timer (PCI config 0xA3) */
  1323.   /* Write CRT/CPU threshold low, CRT/Engine threshold high */
  1324.   data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
  1325.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,data);
  1326.   data = (ThresholdLow & 0x10) << 1;
  1327.   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
  1328.   /* What is this? */
  1329.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
  1330.   /* Write CRT/CPU threshold high (gap = 3) */
  1331.   data = ThresholdLow + 3;
  1332.   if(data > 0x0f) data = 0x0f;
  1333.   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
  1334. }
  1335. USHORT
  1336. SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr,UCHAR key)
  1337. {
  1338.   USHORT data,index;
  1339.   UCHAR  LatencyFactor[] ={ 97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
  1340.                             00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
  1341.                             97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
  1342.                             00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
  1343.                             80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
  1344.                             00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
  1345.                             86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
  1346.                             00, 68, 66, 59, 57, 37};      /*; 128 bit    BQ=1   */
  1347.   index = (key & 0xE0) >> 5;
  1348.   if(key & 0x10) index +=6;
  1349.   if(!(key & 0x01)) index += 24;
  1350.   data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
  1351.   if(data & 0x0080) index += 12;
  1352.   data = LatencyFactor[index];
  1353.   return(data);
  1354. }
  1355. #endif
  1356. /* =============== Autodetection ================ */
  1357. /*             I N C O M P L E T E                */
  1358. BOOLEAN
  1359. SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
  1360. {
  1361.   const USHORT PanelTypeTable300[16] = {
  1362.       0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
  1363.       0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
  1364.   };
  1365.   const USHORT PanelTypeTable31030x[16] = {
  1366.       0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
  1367.       0x0189, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  1368.   };
  1369.   const USHORT PanelTypeTable310LVDS[16] = {
  1370.       0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
  1371.       0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  1372.   };
  1373.   USHORT tempax,tempbx,tempah,temp;
  1374.   if(HwDeviceExtension->jChipType < SIS_315H) {
  1375.     tempax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
  1376.     tempbx = tempax & 0x0F;
  1377.     if(!(tempax & 0x10)){
  1378.       if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
  1379.         tempbx = 0;
  1380.         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
  1381.         if(temp & 0x40) tempbx |= 0x08;
  1382.         if(temp & 0x20) tempbx |= 0x02;
  1383.         if(temp & 0x01) tempbx |= 0x01;
  1384.         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x39);
  1385.         if(temp & 0x80) tempbx |= 0x04;
  1386.       } else {
  1387.         return 0;
  1388.       }
  1389.     }
  1390.     tempbx = PanelTypeTable300[tempbx];
  1391.     tempbx |= LCDSync;
  1392.     temp = tempbx & 0x00FF;
  1393.     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
  1394.     temp = (tempbx & 0xFF00) >> 8;
  1395.     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
  1396.   } else {
  1397.     tempax = tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1a);
  1398.     tempax &= 0x1e;
  1399.     tempax >>= 1;
  1400.     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  1401.        if(tempax == 0) {
  1402.            /* TODO: Include HUGE detection routine
  1403.             (Probably not worth bothering)
  1404.     */
  1405.            return 0;
  1406.        }
  1407.        temp = tempax & 0xff;
  1408.        tempax--;
  1409.        tempbx = PanelTypeTable310LVDS[tempax];
  1410.     } else {
  1411.        tempbx = PanelTypeTable31030x[tempax];
  1412.        temp = tempbx & 0xff;
  1413.     }
  1414.     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
  1415.     tempbx = (tempbx & 0xff00) >> 8;
  1416.     temp = tempbx & 0xc1;
  1417.     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
  1418.     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
  1419.        temp = tempbx & 0x04;
  1420.        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
  1421.     }
  1422.   }
  1423.   return 1;
  1424. }
  1425. #ifdef LINUXBIOS
  1426. void
  1427. SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
  1428. {
  1429.   UCHAR  DAC_TEST_PARMS[] = {0x0F,0x0F,0x0F};
  1430.   UCHAR  DAC_CLR_PARMS[]  = {0x00,0x00,0x00};
  1431.   USHORT SR1F;
  1432.   SR1F = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F); /* backup DAC pedestal */
  1433.   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1F,0x04);
  1434.   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
  1435.     if(!(SiS_BridgeIsOn(SiS_Pr, BaseAddr))) {
  1436.       SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x41);
  1437.     }
  1438.   }
  1439.   SiSSetMode(SiS_Pr,HwDeviceExtension,0x2E);
  1440.   if(HwDeviceExtension->jChipType > SIS_315PRO) {
  1441.      /* TW: On 650 only - enable CRT1 */
  1442.      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
  1443.   }
  1444.   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
  1445.   SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8);
  1446.   SiS_LongWait(SiS_Pr);
  1447.   SiS_LongWait(SiS_Pr);
  1448.   SiS_LongWait(SiS_Pr);
  1449.   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x00);
  1450.   if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
  1451.     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
  1452.   } else if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
  1453.     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
  1454.   }
  1455.   SiS_TestMonitorType(SiS_Pr, DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]);
  1456.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,SR1F);
  1457. }
  1458. USHORT
  1459. SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC)
  1460. {
  1461.    USHORT temp,tempbx;
  1462.    tempbx = R_DAC * 0x4d + G_DAC * 0x97 + B_DAC * 0x1c;
  1463.    if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
  1464.    tempbx = (tempbx & 0xFF00) >> 8;
  1465.    R_DAC = (UCHAR) tempbx;
  1466.    G_DAC = (UCHAR) tempbx;
  1467.    B_DAC = (UCHAR) tempbx;
  1468.    SiS_SetReg3(SiS_Pr->SiS_P3c8,0x00);
  1469.    SiS_SetReg3(SiS_Pr->SiS_P3c9,R_DAC);
  1470.    SiS_SetReg3(SiS_Pr->SiS_P3c9,G_DAC);
  1471.    SiS_SetReg3(SiS_Pr->SiS_P3c9,B_DAC);
  1472.    SiS_LongWait(SiS_Pr);
  1473.    temp=SiS_GetReg2(SiS_Pr->SiS_P3c2);
  1474.    if(temp & 0x10) return(1);
  1475.    else return(0);
  1476. }
  1477. void
  1478. SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr)
  1479. {
  1480.   USHORT tempax=0,tempbx,tempcx,temp;
  1481.   USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*SiS_Pr->pSiS_OutputSelect;
  1482.   USHORT ModeIdIndex,i;
  1483.   USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
  1484.   if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
  1485.     SiS_GetPanelID(SiS_Pr);
  1486.     temp=LCDSense;
  1487.     temp=temp|SiS_SenseCHTV(SiS_Pr);
  1488.     tempbx=~(LCDSense|AVIDEOSense|SVIDEOSense);
  1489.     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,tempbx,temp);
  1490.   } else {       /* for 301 */
  1491.     if(SiS_Pr->SiS_IF_DEF_HiVision==1) {  /* for HiVision */
  1492.       tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
  1493.       temp=tempax&0x01;
  1494.       tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
  1495.       temp=temp|(tempax&0x02);
  1496.       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xA0,temp);
  1497.     } else {
  1498.       if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)==0) {    /* TW: Inserted "==0" */
  1499.         P2reg0 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
  1500.         if(!(SiS_BridgeIsEnable(SiS_Pr, BaseAddr,HwDeviceExtension))) {
  1501.           SenseModeNo=0x2e;
  1502.           temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&SenseModeNo,&ModeIdIndex);
  1503.           SiS_Pr->SiS_SetFlag = 0x00;
  1504.           SiS_Pr->SiS_ModeType = ModeVGA;
  1505.           SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
  1506.           SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
  1507.           for(i=0;i<20;i++) {
  1508.             SiS_LongWait(SiS_Pr);
  1509.           }
  1510.         }
  1511.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1c);
  1512.         tempax=0;
  1513.         tempbx=*SiS_Pr->pSiS_RGBSenseData;
  1514. if(SiS_Is301B(SiS_Pr, BaseAddr)){
  1515.                 tempbx=*SiS_Pr->pSiS_RGBSenseData2;
  1516.         }
  1517.         tempcx=0x0E08;
  1518.         if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
  1519.           if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
  1520.             tempax=tempax|Monitor2Sense;
  1521.           }
  1522.         }
  1523.         tempbx=*SiS_Pr->pSiS_YCSenseData;
  1524.         if(SiS_Is301B(SiS_Pr, BaseAddr)){
  1525.                tempbx=*SiS_Pr->pSiS_YCSenseData2;
  1526.         }
  1527.         tempcx=0x0604;
  1528.         if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
  1529.           if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
  1530.             tempax=tempax|SVIDEOSense;
  1531.           }
  1532.         }
  1533. if(ROMAddr && SiS_Pr->SiS_UseROM) {
  1534. #ifdef SIS300
  1535.    if((HwDeviceExtension->jChipType==SIS_630)||
  1536.               (HwDeviceExtension->jChipType==SIS_730)) {
  1537. OutputSelect = ROMAddr[0xfe];
  1538.    }
  1539. #endif
  1540. #ifdef SIS315H
  1541.    if(HwDeviceExtension->jChipType >= SIS_315H) {
  1542.         OutputSelect = ROMAddr[0xf3];
  1543.    }
  1544. #endif
  1545.         }
  1546.         if(OutputSelect&BoardTVType){
  1547.           tempbx=*SiS_Pr->pSiS_VideoSenseData;
  1548.           if(SiS_Is301B(SiS_Pr, BaseAddr)){
  1549.              tempbx=*SiS_Pr->pSiS_VideoSenseData2;
  1550.           }
  1551.           tempcx=0x0804;
  1552.           if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
  1553.             if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
  1554.               tempax=tempax|AVIDEOSense;
  1555.             }
  1556.           }
  1557.         } else {
  1558.           if(!(tempax&SVIDEOSense)){
  1559.             tempbx=*SiS_Pr->pSiS_VideoSenseData;
  1560.             if(SiS_Is301B(SiS_Pr, BaseAddr)){
  1561.               tempbx=*SiS_Pr->pSiS_VideoSenseData2;
  1562.             }
  1563.             tempcx=0x0804;
  1564.             if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
  1565.               if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
  1566.                 tempax=tempax|AVIDEOSense;
  1567.               }
  1568.             }
  1569.           }
  1570.         }
  1571.       }
  1572.       if(SiS_SenseLCD(SiS_Pr, HwDeviceExtension)){
  1573.         tempax=tempax|LCDSense;
  1574.       }
  1575.       tempbx=0;
  1576.       tempcx=0;
  1577.       SiS_Sense(SiS_Pr, tempbx,tempcx);
  1578.       if(SiS_Pr->SiS_VBType & (VB_SIS30xLV|VB_SIS30xLVX)){   /* TW: prev. 301LV|302LV */
  1579.          tempax &= 0x00ef;   /* 301lv to disable CRT2*/
  1580.       }
  1581.       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,~0xDF,tempax);
  1582.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
  1583.       if(!(P2reg0&0x20)) {
  1584.         SiS_Pr->SiS_VBInfo = DisableCRT2Display;
  1585.         SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
  1586.       }
  1587.     }
  1588.   }
  1589. }
  1590. BOOLEAN
  1591. SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx)
  1592. {
  1593.   USHORT temp,i,tempch;
  1594.   temp = tempbx & 0xFF;
  1595.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x11,temp);
  1596.   temp = (tempbx & 0xFF00) >> 8;
  1597.   temp |= (tempcx & 0x00FF);
  1598.   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,~0x1F,temp);
  1599.   for(i=0; i<10; i++) SiS_LongWait(SiS_Pr);
  1600.   tempch = (tempcx & 0x7F00) >> 8;
  1601.   temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x03);
  1602.   temp ^= 0x0E;
  1603.   temp &= tempch;
  1604.   if(temp>0) return 1;
  1605.   else return 0;
  1606. }
  1607. USHORT
  1608. SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
  1609. {
  1610.   USHORT temp;
  1611.   temp=SiS_GetPanelID(SiS_Pr);
  1612.   if(!temp)  temp=SiS_GetLCDDDCInfo(SiS_Pr, HwDeviceExtension);
  1613.   return(temp);
  1614. }
  1615. BOOLEAN
  1616. SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
  1617. {
  1618.   USHORT temp;
  1619.   /*add lcd sense*/
  1620.   if(HwDeviceExtension->ulCRT2LCDType==LCD_UNKNOWN)
  1621.      return 0;
  1622.   else{
  1623.       temp=(USHORT)HwDeviceExtension->ulCRT2LCDType;
  1624.       SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
  1625.    return 1;
  1626.   }
  1627. }
  1628. USHORT
  1629. SiS_SenseCHTV(SiS_Private *SiS_Pr)
  1630. {
  1631.   USHORT temp,push0e,status;
  1632.   status=0;
  1633.   push0e = SiS_GetCH700x(SiS_Pr, 0x0e);
  1634.   push0e = (push0e << 8) | 0x0e;
  1635.   SiS_SetCH700x(SiS_Pr, 0x0b0e);
  1636.   SiS_SetCH700x(SiS_Pr, 0x0110);
  1637.   SiS_SetCH700x(SiS_Pr, 0x0010);
  1638.   temp = SiS_GetCH700x(SiS_Pr, 0x10);
  1639.   if(temp & 0x08) status |= SVIDEOSense;
  1640.   if(temp & 0x02) status |= AVIDEOSense;
  1641.   SiS_SetCH700x(SiS_Pr, push0e);
  1642.   return(status);
  1643. }
  1644. #endif /* LINUXBIOS */
  1645. /*  ================ for TC only =================  */
  1646. #ifdef TC
  1647. int
  1648. INT1AReturnCode(union REGS regs)
  1649. {
  1650.   if (regs.x.cflag)
  1651.   {
  1652.     /*printf("Error to find pci device!n"); */
  1653.     return 1;
  1654.   }
  1655.   switch(regs.h.ah)
  1656.   {
  1657.     case 0: return 0;
  1658.             break;
  1659.     case 0x81: printf("Function not supportn");
  1660.                break;
  1661.     case 0x83: printf("bad vendor idn");
  1662.                break;
  1663.     case 0x86: printf("device not foundn");
  1664.                break;
  1665.     case 0x87: printf("bad register numbern");
  1666.                break;
  1667.     case 0x88: printf("set failedn");
  1668.                break;
  1669.     case 0x89: printf("buffer too small");
  1670.                break;
  1671.   }
  1672.   return 1;
  1673. }
  1674. unsigned
  1675. FindPCIIOBase(unsigned index,unsigned deviceid)
  1676. {
  1677.   union REGS regs;
  1678.   regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
  1679.   regs.h.al = 0x02;  /*FIND_PCI_DEVICE */
  1680.   regs.x.cx = deviceid;
  1681.   regs.x.dx = 0x1039;
  1682.   regs.x.si = index;  /* find n-th device */
  1683.   int86(0x1A, &regs, &regs);
  1684.   if (INT1AReturnCode(regs)!=0)
  1685.     return 0;
  1686.   /* regs.h.bh *//* bus number */
  1687.   /* regs.h.bl *//* device number */
  1688.   regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
  1689.   regs.h.al = 0x09;  /*READ_CONFIG_WORD */
  1690.   regs.x.cx = deviceid;
  1691.   regs.x.dx = 0x1039;
  1692.   regs.x.di = 0x18;  /* register number */
  1693.   int86(0x1A, &regs, &regs);
  1694.   if (INT1AReturnCode(regs)!=0)
  1695.     return 0;
  1696.   return regs.x.cx;
  1697. }
  1698. void
  1699. main(int argc, char *argv[])
  1700. {
  1701.   SIS_HW_DEVICE_INFO  HwDeviceExtension;
  1702.   USHORT temp;
  1703.   USHORT ModeNo;
  1704.   /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
  1705.   /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
  1706. #ifdef SIS300  
  1707.   HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
  1708.   HwDeviceExtension.jChipType = SIS_630;
  1709. #endif
  1710. #ifdef SIS315H  
  1711. //  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
  1712. //  HwDeviceExtension.jChipType = SIS_550;
  1713.   HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
  1714.   HwDeviceExtension.jChipType = SIS_315H;
  1715. #endif
  1716.   HwDeviceExtension.ujVBChipID = VB_CHIP_301;
  1717.   strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
  1718.   HwDeviceExtension.bSkipDramSizing = FALSE;
  1719.   HwDeviceExtension.ulVideoMemorySize = 0;
  1720.   if(argc==2) {
  1721.     ModeNo=atoi(argv[1]);
  1722.   }
  1723.   else {
  1724.     ModeNo=0x2e;
  1725.     /*ModeNo=0x37; */ /* 1024x768x 4bpp */
  1726.     /*ModeNo=0x38; *//* 1024x768x 8bpp */
  1727.     /*ModeNo=0x4A; *//* 1024x768x 16bpp */
  1728.     /*ModeNo=0x47;*/ /* 800x600x 16bpp */
  1729.   }
  1730.  /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
  1731.   SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
  1732. }
  1733. #endif /* TC END */
  1734. /* ================ LINUX XFREE86 ====================== */
  1735. /* Helper functions */
  1736. #ifdef LINUX_XF86
  1737. USHORT
  1738. SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
  1739. {
  1740.    SISPtr pSiS = SISPTR(pScrn);
  1741.    UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1;
  1742.    UShort ModeIndex = 0;
  1743.    switch(mode->HDisplay)
  1744.    {
  1745.      case 320:
  1746.           if(mode->VDisplay == 480) {
  1747.                 ModeIndex = ModeIndex_320x480[i];
  1748.   }
  1749.           break;
  1750.      case 512:
  1751.           if(mode->VDisplay == 384) {
  1752.              ModeIndex = ModeIndex_512x384[i];
  1753.   }
  1754.           break;
  1755.      case 640:
  1756.           if(mode->VDisplay == 480) {
  1757.              ModeIndex = ModeIndex_640x480[i];
  1758.   }
  1759.           break;
  1760.      case 720:
  1761.           if(mode->VDisplay == 480) {
  1762.                 ModeIndex = ModeIndex_720x480[i];
  1763.           } else if(mode->VDisplay == 576) {
  1764.                 ModeIndex = ModeIndex_720x576[i];
  1765.           }
  1766.           break;
  1767.      case 800:
  1768.   if(mode->VDisplay == 600) {
  1769.              ModeIndex = ModeIndex_800x600[i];
  1770.   } else if(pSiS->VGAEngine == SIS_315_VGA) {
  1771.      if(mode->VDisplay == 480) {
  1772.            ModeIndex = ModeIndex_800x480[i];
  1773.              }
  1774.   }
  1775.           break;
  1776.      case 1024:
  1777.           if(mode->VDisplay == 768) {
  1778.         ModeIndex = ModeIndex_1024x768[i];
  1779.   } else if(pSiS->VGAEngine == SIS_315_VGA) {
  1780.      if(mode->VDisplay == 576) {
  1781.         ModeIndex = ModeIndex_1024x576[i];
  1782.              }
  1783.   } else if(pSiS->VGAEngine == SIS_300_VGA) {
  1784.      if(mode->VDisplay == 600) {
  1785.         ModeIndex = ModeIndex_1024x600[i];
  1786.              }
  1787.   }
  1788.           break;
  1789.      case 1152:
  1790.           if(pSiS->VGAEngine == SIS_300_VGA) {
  1791.      if(mode->VDisplay == 768) {
  1792.         ModeIndex = ModeIndex_1152x768[i];
  1793.              }
  1794.   }
  1795.   break;
  1796.      case 1280:
  1797.           if(mode->VDisplay == 960) {
  1798.              if(pSiS->VGAEngine == SIS_300_VGA) {
  1799.         ModeIndex = ModeIndex_300_1280x960[i];
  1800.              } else {
  1801.                 ModeIndex = ModeIndex_310_1280x960[i];
  1802.              }
  1803.   } else if (mode->VDisplay == 1024) {
  1804.      ModeIndex = ModeIndex_1280x1024[i];
  1805.   } else if(pSiS->VGAEngine == SIS_315_VGA) {
  1806.      if (mode->VDisplay == 768) {
  1807.         ModeIndex = ModeIndex_1280x768[i];
  1808.      } else if (mode->VDisplay == 720) {
  1809.         ModeIndex = ModeIndex_1280x720[i];
  1810.              }
  1811.   }
  1812.           break;
  1813.      case 1400:
  1814.           if(pSiS->VGAEngine == SIS_315_VGA) {
  1815.      if(mode->VDisplay == 1050) {
  1816.         ModeIndex = ModeIndex_1400x1050[i];
  1817.              }
  1818.   }
  1819.           break;
  1820.      case 1600:
  1821.           if(mode->VDisplay == 1200) {
  1822.              ModeIndex = ModeIndex_1600x1200[i];
  1823.   }
  1824.           break;
  1825.      case 1920:
  1826.           if(mode->VDisplay == 1440) {
  1827.              ModeIndex = ModeIndex_1920x1440[i];
  1828.   }
  1829.           break;
  1830.      case 2048:
  1831.           if(pSiS->VGAEngine == SIS_315_VGA) {
  1832.      if(mode->VDisplay == 1536) {
  1833.          ModeIndex = ModeIndex_2048x1536[i];
  1834.              }
  1835.   }
  1836.           break;
  1837.    }
  1838.    return(ModeIndex);
  1839. }
  1840. USHORT
  1841. SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
  1842. {
  1843.    SISPtr pSiS = SISPTR(pScrn);
  1844.    UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1;    
  1845.    UShort ModeIndex = 0;
  1846.    if(VBFlags & CRT2_LCD) {
  1847.       if( (mode->HDisplay <= pSiS->LCDwidth) &&
  1848.           (mode->VDisplay <= pSiS->LCDheight) ) {
  1849.         if(VBFlags & VB_LVDS) {         /* LCD on LVDS */
  1850.           switch(mode->HDisplay)
  1851.      {
  1852.   case 512:
  1853. if(mode->VDisplay == 384) {
  1854.    ModeIndex = ModeIndex_512x384[i];
  1855. }
  1856. break;
  1857.   case 640:
  1858. if(mode->VDisplay == 480) {
  1859.    ModeIndex = ModeIndex_640x480[i];
  1860. }
  1861. break;
  1862.   case 800:
  1863. if(mode->VDisplay == 600) {
  1864.    ModeIndex = ModeIndex_800x600[i];
  1865. }
  1866. break;
  1867.   case 1024:
  1868. if(mode->VDisplay == 768) {
  1869.    ModeIndex = ModeIndex_1024x768[i];
  1870. } else if(pSiS->VGAEngine == SIS_300_VGA) {
  1871.    if(mode->VDisplay == 600) {
  1872.       ModeIndex = ModeIndex_1024x600[i];
  1873.    }
  1874. }
  1875. break;
  1876.   case 1152:
  1877. if(pSiS->VGAEngine == SIS_300_VGA) {
  1878.    if(mode->VDisplay == 768) {
  1879. ModeIndex = ModeIndex_1152x768[i];
  1880.    }
  1881. }
  1882. break;
  1883.   case 1280:
  1884. if(mode->VDisplay == 1024) {
  1885.    ModeIndex = ModeIndex_1280x1024[i];
  1886. } else if(pSiS->VGAEngine == SIS_315_VGA) {
  1887.    if(mode->VDisplay == 768) {
  1888.       ModeIndex = ModeIndex_1280x768[i];
  1889.    }
  1890. }
  1891. break;
  1892.   case 1400:
  1893.         if(mode->VDisplay == 1050) {
  1894.    if(pSiS->VGAEngine == SIS_315_VGA) {
  1895.       ModeIndex = ModeIndex_1400x1050[i];
  1896.    }
  1897. }
  1898. break;
  1899.           }
  1900.         } else {                          /* LCD on 301(B) */
  1901.           switch(mode->HDisplay)
  1902.   {
  1903.   case 512:
  1904. if(mode->VDisplay == 384) {
  1905.    ModeIndex = ModeIndex_512x384[i];
  1906. }
  1907. break;
  1908.   case 640:
  1909. if(mode->VDisplay == 480) {
  1910.    ModeIndex = ModeIndex_640x480[i];
  1911. }
  1912. break;
  1913.   case 800:
  1914. if(mode->VDisplay == 600) {
  1915.    ModeIndex = ModeIndex_800x600[i];
  1916. }
  1917. break;
  1918.   case 1024:
  1919. if(mode->VDisplay == 768) {
  1920.    ModeIndex = ModeIndex_1024x768[i];
  1921. } /* else if(pSiS->VGAEngine == SIS_300_VGA) {  --  not supported on 301(B) --
  1922.    if(mode->VDisplay == 600) {
  1923. ModeIndex = ModeIndex_1024x600[i];
  1924.    }
  1925. } */
  1926. break;
  1927.   case 1152:  /* not supported on 301(B) */
  1928. #if 0
  1929. if(pSiS->VGAEngine == SIS_300_VGA) {
  1930.    if(mode->VDisplay == 768) {
  1931. ModeIndex = ModeIndex_1152x768[i];
  1932.    }
  1933. }
  1934. #endif
  1935. break;
  1936.   case 1280:
  1937. if(mode->VDisplay == 960) {
  1938.    if(pSiS->VGAEngine == SIS_300_VGA) {
  1939.       ModeIndex = ModeIndex_300_1280x960[i];
  1940.    } else {
  1941.       ModeIndex = ModeIndex_310_1280x960[i];
  1942.    }
  1943.                 } else if (mode->VDisplay == 1024) {
  1944.              ModeIndex = ModeIndex_1280x1024[i];
  1945.         }
  1946.   case 1600:
  1947. if(mode->VDisplay == 1200) {
  1948.    ModeIndex = ModeIndex_1600x1200[i];
  1949. }
  1950. break;
  1951.   }
  1952.         }
  1953.       }
  1954.    } else if(VBFlags & CRT2_TV) {
  1955.       if(VBFlags & VB_CHRONTEL) { /* TV on Chrontel */
  1956.         switch(mode->HDisplay)
  1957. {
  1958.        case 512:
  1959. if(mode->VDisplay == 384) {
  1960.    ModeIndex = ModeIndex_512x384[i];
  1961. }
  1962. break;
  1963. case 640:
  1964. if(mode->VDisplay == 480) {
  1965.    ModeIndex = ModeIndex_640x480[i];
  1966. }
  1967. break;
  1968. case 800:
  1969. if(mode->VDisplay == 600) {
  1970.    ModeIndex = ModeIndex_800x600[i];
  1971. }
  1972. break;
  1973. case 1024:
  1974. if(mode->VDisplay == 768) {
  1975.    if(pSiS->VGAEngine == SIS_315_VGA) {
  1976.       ModeIndex = ModeIndex_1024x768[i];
  1977.    }
  1978. }
  1979. break;
  1980.         }
  1981.       } else {     /* TV on 301(B) */
  1982.         switch(mode->HDisplay)
  1983. {
  1984.        case 512:
  1985. if(mode->VDisplay == 384) {
  1986.    ModeIndex = ModeIndex_512x384[i];
  1987. }
  1988. break;
  1989. case 640:
  1990. if(mode->VDisplay == 480) {
  1991.    ModeIndex = ModeIndex_640x480[i];
  1992. }
  1993. break;
  1994. case 720:
  1995.                 if(mode->VDisplay == 480) {
  1996.                    ModeIndex = ModeIndex_720x480[i];
  1997.                 } else if(mode->VDisplay == 576) {
  1998.                    ModeIndex = ModeIndex_720x576[i];
  1999.                 }
  2000.                 break;
  2001. case 800:
  2002. if(mode->VDisplay == 600) {
  2003.    ModeIndex = ModeIndex_800x600[i];
  2004. }
  2005. break;
  2006. case 1024:
  2007. if(mode->VDisplay == 768) {
  2008.    if(VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
  2009.       ModeIndex = ModeIndex_1024x768[i];
  2010.    }
  2011. }
  2012. break;
  2013.         }
  2014.       }
  2015.    } else if(VBFlags & CRT2_VGA) { /* CRT2 is VGA2 */
  2016. switch(mode->HDisplay)
  2017. {
  2018. case 512:
  2019. if(mode->VDisplay == 384) {
  2020.     ModeIndex = ModeIndex_512x384[i];
  2021. }
  2022. break;
  2023. case 640:
  2024. if(mode->VDisplay == 480) {
  2025.    ModeIndex = ModeIndex_640x480[i];
  2026. }
  2027. break;
  2028. case 800:
  2029. if(mode->VDisplay == 600) {
  2030.    ModeIndex = ModeIndex_800x600[i];
  2031. } else if(pSiS->VGAEngine == SIS_315_VGA) {
  2032.    if(mode->VDisplay == 480) {
  2033. ModeIndex = ModeIndex_800x480[i];
  2034.    }
  2035. }
  2036. break;
  2037. case 1024:
  2038. if(mode->VDisplay == 768) {
  2039. ModeIndex = ModeIndex_1024x768[i];
  2040. } else if(pSiS->VGAEngine == SIS_315_VGA) {
  2041.    if(mode->VDisplay == 576) {
  2042. ModeIndex = ModeIndex_1024x576[i];
  2043.    }
  2044. }
  2045. break;
  2046. case 1152:
  2047. if(pSiS->VGAEngine == SIS_300_VGA) {
  2048.    if(mode->VDisplay == 768) {
  2049. ModeIndex = ModeIndex_1152x768[i];
  2050.    }
  2051. }
  2052. break;
  2053. case 1280:
  2054. if (mode->VDisplay == 1024) {
  2055.    ModeIndex = ModeIndex_1280x1024[i];
  2056. } else if(pSiS->VGAEngine == SIS_315_VGA) {
  2057.    if (mode->VDisplay == 768) {
  2058. ModeIndex = ModeIndex_1280x768[i];
  2059.    } else if (mode->VDisplay == 720) {
  2060. ModeIndex = ModeIndex_1280x720[i];
  2061.    }
  2062. }
  2063. break;
  2064. case 1400:
  2065. if(pSiS->VGAEngine == SIS_315_VGA) {
  2066.    ModeIndex = ModeIndex_1400x1050[i];
  2067. }
  2068. break;
  2069. }
  2070.    } else { /* CRT1 only, no CRT2 */
  2071.        ModeIndex = SiS_CalcModeIndex(pScrn, mode);
  2072.    }
  2073.    return(ModeIndex);
  2074. }
  2075. #define MODEID_OFF 0x449
  2076. unsigned char
  2077. SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
  2078. {
  2079.     return(SiS_GetSetMMIOReg(pScrn, MODEID_OFF, id));
  2080. }
  2081. unsigned char
  2082. SiS_GetSetMMIOReg(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
  2083. {
  2084.     unsigned char ret;
  2085.     unsigned char *base;
  2086.     SISPtr pSiS = SISPTR(pScrn);
  2087.     BOOLEAN mapped;
  2088.     if(pSiS->IOBase) {
  2089.      base = (unsigned char *)pSiS->IOBase;
  2090. mapped = FALSE;
  2091.     } else {
  2092.         base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
  2093. if(!base) {
  2094.      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
  2095.           "(init.c: Could not MMIO area!)n");
  2096.      return 0;
  2097. }
  2098. mapped = TRUE;
  2099.     }
  2100.     ret = *(base + offset);
  2101.     /* value != 0xff means: set register */
  2102.     if (value != 0xff)
  2103. *(base + offset) = value;
  2104.     if(mapped) xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
  2105.     return ret;
  2106. }
  2107. #endif