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

Linux/Unix编程

开发平台:

Unix_Linux

  1.              tempcx = 0x0061;    /* TW: BIOS; Was 0x0078; */
  2.        }
  3.        temp = (tempbx & 0x00FF) ;
  4.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
  5.        temp = (tempcx & 0x00FF) ;
  6.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
  7.        tempbx &= 0x0300;
  8.        temp = (tempcx & 0xFF00) >> 8;
  9.        temp = (temp & 0x0003) << 2;
  10.        temp |= (tempbx >> 8);
  11.        if(HwDeviceExtension->jChipType < SIS_315H) {
  12.           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
  13.        } else {
  14.           SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
  15.        }
  16.        temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
  17.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
  18.   }
  19.   temp = 0;
  20.   if((HwDeviceExtension->jChipType == SIS_630)||
  21.      (HwDeviceExtension->jChipType == SIS_730)) {
  22.      temp = 0x35;
  23.   } else if(HwDeviceExtension->jChipType >= SIS_315H) {
  24.      temp = 0x38;
  25.   }
  26.   if(temp) {
  27.       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  28.           if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
  29.                if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & 0x40) {
  30.                      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
  31.                      temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
  32.                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
  33.                }
  34.           }
  35.       }
  36.   }
  37. #ifdef oldHV
  38.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
  39.     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
  40.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
  41.     }
  42.   }
  43. #endif
  44.   if(HwDeviceExtension->jChipType < SIS_315H) {
  45.      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  return;
  46.   } else {
  47.      /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
  48.      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  49.        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
  50.          if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  51.            if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
  52.              if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
  53.                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
  54.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
  55.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
  56.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
  57.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
  58.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
  59.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
  60.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
  61.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
  62.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
  63.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
  64.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
  65.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
  66.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
  67.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
  68.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
  69.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
  70.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
  71.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
  72.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
  73.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
  74.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
  75.      }
  76.            }
  77.          }
  78.        }
  79.        return;
  80.      }
  81.   }
  82.   /* TW: From here: Part2 LCD setup */
  83.   tempbx = SiS_Pr->SiS_HDE;
  84.   /* TW: Inserted from 650/301LVx 1.10.6s */
  85.   if(HwDeviceExtension->jChipType >= SIS_315H) {
  86.       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
  87.   }
  88.   tempbx--;          /* RHACTE=HDE-1 */
  89.   temp = tempbx & 0x00FF;
  90.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
  91.   temp = (tempbx & 0xFF00) >> 8;
  92.   temp <<= 4;
  93.   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
  94.   temp = 0x01;
  95.   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
  96.     if(SiS_Pr->SiS_ModeType == ModeEGA) {
  97.       if(SiS_Pr->SiS_VGAHDE >= 1024) {
  98.         temp = 0x02;
  99. if(HwDeviceExtension->jChipType >= SIS_315H) {
  100.            if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
  101.              temp = 0x01;
  102.    }
  103. }
  104.       }
  105.     }
  106.   }
  107.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
  108.   tempbx = SiS_Pr->SiS_VDE;          /* RTVACTEO=(VDE-1)&0xFF */
  109.   push1 = tempbx;
  110.   tempbx--;
  111.   temp = tempbx & 0x00FF;
  112.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
  113.   temp = ((tempbx & 0xFF00) >> 8) & 0x07;
  114.   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
  115.   tempcx = SiS_Pr->SiS_VT;
  116.   push2 = tempcx;
  117.   tempcx--;
  118.   temp = tempcx & 0x00FF;    /* RVTVT=VT-1 */
  119.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
  120.   temp = (tempcx & 0xFF00) >> 8;
  121.   temp <<= 5;
  122.   if(HwDeviceExtension->jChipType < SIS_315H) {
  123.     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
  124.     else {
  125.       if(SiS_Pr->SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
  126.          temp |= 0x10;
  127.     }
  128.   } else {
  129.       /* TW: Inserted from 630/301LVx 1.10.6s */
  130.       if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
  131.          if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
  132.            temp |= 0x10;
  133.  }
  134.       }
  135.   }
  136.   /* 630/301 does not do all this */
  137.   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
  138.       if(HwDeviceExtension->jChipType >= SIS_315H) {
  139.         /* TW: Inserted from 650/301LVx 1.10.6s */
  140.         temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
  141.       } else {
  142.         tempbx = (tempbx & 0xFF00) | (SiS_Pr->SiS_LCDInfo & 0x0FF);
  143.         if(tempbx & LCDSync) {
  144.           tempbx &= (0xFF00 | LCDSyncBit);
  145.           tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> LCDSyncShift);
  146.           temp |= (tempbx & 0x00FF);
  147.         }
  148.       }
  149.   }
  150.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp);
  151.   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
  152.   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
  153.   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
  154.   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
  155.   if(HwDeviceExtension->jChipType >= SIS_315H) {   /* ------------- 310 series ------------ */
  156.       /* TW: Inserted this entire section from 650/301LV(x) BIOS */
  157.       SiS_GetCRT2Part2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
  158.                          &CRT2Index,&resindex);
  159.       switch(CRT2Index) {
  160.         case Panel_1024x768      : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
  161.         case Panel_1280x1024     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_1; break;
  162. case Panel_1400x1050     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_1; break;
  163. case Panel_1600x1200     : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_1; break;
  164.         case Panel_1024x768 + 16 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;  break;  /* Non-Expanding */
  165.         case Panel_1280x1024 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_2; break;
  166. case Panel_1400x1050 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_2; break;
  167. case Panel_1600x1200 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_2; break;
  168.         case Panel_1024x768 + 32 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;  /* VESA Timing */
  169.         case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
  170. case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
  171. case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
  172. default:                   CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;
  173.       }
  174.       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
  175.       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
  176.       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
  177.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
  178.       }
  179.       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
  180.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
  181.       }
  182.       for(j = 0x1f; j <= 0x21; i++, j++ ) {
  183.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
  184.       }
  185.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
  186.       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
  187.       if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
  188.         if(SiS_Pr->SiS_VGAVDE == 0x20d) {
  189.   temp = 0xc3;
  190.   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
  191.      temp++;
  192.      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
  193.   }
  194.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
  195.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3);
  196. }
  197. if(SiS_Pr->SiS_VGAVDE == 0x1a4) {
  198.   temp = 0x4d;
  199.   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
  200.      temp++;
  201.      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
  202.   }
  203.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
  204. }
  205.      }
  206.      /* TW: Inserted from 650/301LVx 1.10.6s: */
  207.      /* !!! This is a duplicate, done for LCDA as well - see above */
  208.      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  209.         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
  210.    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
  211.    temp = 1;
  212.    if(ModeNo<=0x13) temp = 3;
  213.    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
  214. }
  215.      }
  216.   } else {   /* ------------- 300 series ----------- */
  217.     tempcx++;
  218.     tempbx = 768;
  219.     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
  220.       tempbx = 1024;
  221.       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
  222.          tempbx = 1200;
  223.          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
  224.             if(tempbx != SiS_Pr->SiS_VDE) {
  225.                tempbx = 960;
  226.             }
  227.          }
  228.       }
  229.     }
  230.     if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
  231.       tempbx = SiS_Pr->SiS_VDE - 1;
  232.       tempcx--;
  233.     }
  234.     tempax = 1;
  235.     if(!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) {
  236.       if(tempbx != SiS_Pr->SiS_VDE){
  237.         tempax = tempbx;
  238.         if(tempax < SiS_Pr->SiS_VDE) {
  239.           tempax = 0;
  240.           tempcx = 0;
  241.         } else {
  242.           tempax -= SiS_Pr->SiS_VDE;
  243.         }
  244.         tempax >>= 1;
  245.       }
  246.       tempcx -= tempax; /* lcdvdes */
  247.       tempbx -= tempax; /* lcdvdee */
  248.     } else {
  249.       tempax >>= 1;
  250.       tempcx -= tempax; /* lcdvdes */
  251.       tempbx -= tempax; /* lcdvdee */
  252.     }
  253.     temp = tempcx & 0x00FF;    /* RVEQ1EQ=lcdvdes */
  254.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
  255.     temp = tempbx & 0x00FF;    /* RVEQ2EQ=lcdvdee */
  256.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,temp);
  257.     temp = ((tempbx & 0xFF00) >> 8 ) << 3;
  258.     temp |= ((tempcx & 0xFF00) >> 8);
  259.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
  260.     tempbx = push2;
  261.     tempax = push1;
  262.     tempcx = tempbx;
  263.     tempcx -= tempax;
  264.     tempcx >>= 4;
  265.     tempbx += tempax;
  266.     tempbx >>= 1;
  267.     if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)  tempbx -= 10;
  268.     temp = tempbx & 0x00FF;    /* RTVACTEE=lcdvrs */
  269.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
  270.     temp = ((tempbx & 0xFF00) >> 8) << 4;
  271.     tempbx += (tempcx + 1);
  272.     temp |= (tempbx & 0x000F);
  273.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
  274.     /* TW: Code from 630/301B (I+II) BIOS */
  275.     if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
  276.             (HwDeviceExtension->jChipType == SIS_730) ) &&
  277.           (HwDeviceExtension->jChipRevision > 2) )  &&
  278.         (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
  279.         (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
  280.         (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) ) {
  281.             if(ModeNo == 0x13) {
  282.               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
  283.               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
  284.               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
  285.             } else {
  286.               if((crt2crtc & 0x3F) == 4) {
  287.                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
  288.                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
  289.                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
  290.                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
  291.                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
  292.               }
  293.             }
  294.     }
  295.     /* TW: Inserted missing code from 630/301B BIOS: (II: 3258) */
  296.     if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
  297.          crt2crtc &= 0x1f;
  298.          tempcx = 0;
  299.          if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
  300.            if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  301.               tempcx += 7;
  302.            }
  303.          }
  304.          tempcx += crt2crtc;
  305.          if (crt2crtc >= 4) {
  306.            SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
  307.          }
  308.          if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
  309.            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  310.              if(crt2crtc == 4) {
  311.                 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
  312.              }
  313.            }
  314.          }
  315.          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
  316.          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
  317.     }
  318.     tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT-HDE)>>2     */
  319.     tempbx = SiS_Pr->SiS_HDE + 7;               /* lcdhdee         */
  320.     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  321.          tempbx += 2;
  322.     }
  323.     push1 = tempbx;
  324.     temp = tempbx & 0x00FF;               /* RHEQPLE=lcdhdee */
  325.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
  326.     temp = (tempbx & 0xFF00) >> 8;
  327.     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
  328.     temp = 7;
  329.     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  330.          temp += 2;
  331.     }
  332.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);     /* RHBLKE=lcdhdes */
  333.     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);
  334.     tempbx += tempcx;
  335.     push2 = tempbx;
  336.     temp = tempbx & 0xFF;                       /* RHBURSTS=lcdhrs */
  337.     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
  338.       if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) {
  339.         if(SiS_Pr->SiS_HDE == 1280)  temp = 0x47;
  340.       }
  341.     }
  342.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
  343.     temp = ((tempbx & 0xFF00) >> 8) << 4;
  344.     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
  345.     tempbx = push2;
  346.     tempcx <<= 1;
  347.     tempbx += tempcx;
  348.     temp = tempbx & 0x00FF;                       /* RHSYEXP2S=lcdhre */
  349.     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
  350.     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
  351.       if(SiS_Pr->SiS_VGAVDE == 525) {
  352.         if(SiS_Pr->SiS_ModeType <= ModeVGA)
  353.         temp=0xC6;
  354.         else
  355.            temp=0xC3;
  356.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
  357.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
  358.       } else if(SiS_Pr->SiS_VGAVDE == 420) {
  359.         if(SiS_Pr->SiS_ModeType <= ModeVGA)
  360.    temp=0x4F;
  361.         else
  362.            temp=0x4D;   /* 650: 4e */
  363.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
  364.       }
  365.     }
  366.   } /* HwDeviceExtension */
  367. }
  368. USHORT
  369. SiS_GetVGAHT2(SiS_Private *SiS_Pr)
  370. {
  371.   ULONG tempax,tempbx;
  372.   tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
  373.   tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
  374.   tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
  375.   return((USHORT) tempax);
  376. }
  377. /* TW: Set 301 Macrovision(tm) registers */
  378. /* TW: Double-Checked against 650/301LV, 650/301LVx and 630/301B BIOS */
  379. void
  380. SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
  381.               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
  382. {
  383.   USHORT temp;
  384. #ifdef oldHV
  385.   USHORT i;
  386.   const UCHAR  *tempdi;
  387. #endif
  388.   USHORT modeflag;
  389.   /* TW: Inserted from 650/301LVx 1.10.6s */
  390.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
  391.   if(ModeNo<=0x13)
  392.      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  393.   else
  394.      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  395.   SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
  396.   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
  397.     SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
  398.     SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
  399.   } else {
  400.     if(HwDeviceExtension->jChipType >= SIS_315H) {
  401.       SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
  402.       SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
  403.     } else {
  404.       SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
  405.       SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
  406.     }
  407.   }
  408.   temp = 0;
  409.   if((HwDeviceExtension->jChipType == SIS_630)||
  410.      (HwDeviceExtension->jChipType == SIS_730)) {
  411.      temp = 0x35;
  412.   } else if(HwDeviceExtension->jChipType >= SIS_315H) {
  413.      temp = 0x38;
  414.   }
  415.   if(temp) {
  416.       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  417.           if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
  418.               if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & 0x40){
  419.                   SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
  420.                   SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
  421.                   SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
  422.               }
  423.           }
  424.       }
  425.   }
  426. #ifdef oldHV
  427.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
  428.     tempdi = SiS_Pr->SiS_HiTVGroup3Data;
  429.     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
  430.       tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
  431.       if(!(modeflag & Charx8Dot)) {
  432.         tempdi = SiS_Pr->SiS_HiTVGroup3Text;
  433.       }
  434.     }
  435.     for(i=0; i<=0x3E; i++){
  436.        SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
  437.     }
  438.   }
  439. #endif
  440.   return;
  441. }
  442. /* TW: Set 301 VGA2 registers */
  443. /* TW: Double-Checked against 650/301LV(x) and 630/301B BIOS */
  444. void
  445. SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
  446.               USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
  447.       PSIS_HW_DEVICE_INFO HwDeviceExtension)
  448. {
  449.   USHORT tempax,tempcx,tempbx,modeflag,temp,temp2;
  450.   ULONG tempebx,tempeax,templong;
  451.   if(ModeNo<=0x13)
  452.      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  453.   else
  454.      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  455.   /* TW: From 650/301LVx 1.10.6s BIOS */
  456.   if(SiS_Pr->SiS_VBType & (VB_SIS30xLV | VB_SIS30xNEW)) {
  457.       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  458.           SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
  459.       }
  460.   }
  461.   if(SiS_Pr->SiS_VBType & VB_SIS30xNEW) {
  462.       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  463.           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
  464.       }
  465.   }
  466.   /* TW: From 650/301LV BIOS */
  467.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  468.    /* TW: This is a duplicate; done at the end, too */
  469. if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
  470. SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
  471. }
  472. SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
  473. SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
  474. SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
  475.     return;
  476.   }
  477.   temp = SiS_Pr->SiS_RVBHCFACT;
  478.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x13,temp);
  479.   tempbx = SiS_Pr->SiS_RVBHCMAX;
  480.   temp = tempbx & 0x00FF;
  481.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x14,temp);
  482.   temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
  483.   tempcx = SiS_Pr->SiS_VGAHT - 1;
  484.   temp = tempcx & 0x00FF;
  485.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x16,temp);
  486.   temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
  487.   temp2 |= temp;
  488.   tempcx = SiS_Pr->SiS_VGAVT - 1;
  489.   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempcx -= 5;
  490.   temp = tempcx & 0x00FF;
  491.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x17,temp);
  492.   temp = temp2 | ((tempcx & 0xFF00) >> 8);
  493.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x15,temp);
  494.   tempcx = SiS_Pr->SiS_VBInfo;
  495.   tempbx = SiS_Pr->SiS_VGAHDE;
  496.   if(modeflag & HalfDCLK)  tempbx >>= 1;
  497.   /* TW: New for 650/301LV and 630/301B */
  498.   temp = 0xA0;
  499. #ifdef oldHV
  500.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
  501.        temp = 0;
  502.        if(tempbx > 800) {
  503.           temp = 0xA0;
  504.           if(tempbx != 1024) {
  505.              temp = 0xC0;
  506.              if(tempbx != 1280) temp = 0;
  507.   }
  508.        }
  509.   } else
  510. #endif
  511.     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  512.       if(tempbx <= 800) {
  513.          temp = 0x80;
  514.  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD){
  515.             temp = 0;
  516.             if(tempbx > 800) temp = 0x60;
  517.          }
  518.       }
  519.   } else {
  520.       temp = 0x80;
  521.       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD){
  522.             temp = 0;
  523.             if(tempbx > 800) temp = 0x60;
  524.       }
  525.   }
  526.   if(SiS_Pr->SiS_HiVision & 0x03) {
  527.         temp = 0;
  528. if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
  529.   }
  530.   if(HwDeviceExtension->jChipType >= SIS_315H) {
  531.    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
  532.   }
  533.   if(SiS_Pr->SiS_VBType & VB_SIS301) {
  534.      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
  535.         temp |= 0x0A;
  536.   }
  537.   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
  538.   tempebx = SiS_Pr->SiS_VDE;
  539. #ifdef oldHV
  540.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
  541.      if(!(temp & 0xE0)) tempebx >>=1;
  542.   }
  543. #endif
  544.   tempcx = SiS_Pr->SiS_RVBHRS;
  545.   temp = tempcx & 0x00FF;
  546.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x18,temp);
  547.   tempeax = SiS_Pr->SiS_VGAVDE;
  548.   tempcx |= 0x4000;
  549.   if(tempeax <= tempebx){
  550.     tempcx ^= 0x4000;
  551.   } else {
  552.     tempeax -= tempebx;
  553.   }
  554.   templong = (tempeax * 256 * 1024) % tempebx;
  555.   tempeax = (tempeax * 256 * 1024) / tempebx;
  556.   tempebx = tempeax;
  557.   if(templong != 0) tempebx++;
  558.   temp = (USHORT)(tempebx & 0x000000FF);
  559.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1B,temp);
  560.   temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
  561.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1A,temp);
  562.   tempbx = (USHORT)(tempebx >> 16);
  563.   temp = tempbx & 0x00FF;
  564.   temp <<= 4;
  565.   temp |= ((tempcx & 0xFF00) >> 8);
  566.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x19,temp);
  567.   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  568.          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1C,0x28);
  569.  tempbx = 0;
  570.          tempax = SiS_Pr->SiS_VGAHDE;
  571.          if(modeflag & HalfDCLK) tempax >>= 1;
  572.          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
  573.      if(HwDeviceExtension->jChipType >= SIS_315H) {
  574.          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
  575.  else if(tempax > 800) tempax -= 800;
  576.      } else {
  577.                  if(tempax > 800) tempax -= 800;
  578.              }
  579.          }
  580.          if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
  581.            if(tempax > 800) {
  582.       tempbx = 8;
  583.               if(tempax == 1024)
  584.         tempax *= 25;
  585.               else
  586.         tempax *= 20;
  587.       temp = tempax % 32;
  588.       tempax /= 32;
  589.       tempax--;
  590.       if (temp!=0) tempax++;
  591.            }
  592.          }
  593.  tempax--;
  594.          temp = (tempax & 0xFF00) >> 8;
  595.          temp &= 0x03;
  596.  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
  597.  temp <<= 4;
  598.  temp |= tempbx;
  599.  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
  600.          temp = 0x0036;
  601.          if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
  602.                                (!(SiS_Pr->SiS_HiVision & 0x03))) {
  603. temp |= 0x01;
  604.         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  605.           if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
  606.                      temp &= 0xFE;
  607. }
  608.          }
  609.          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
  610.  tempbx = SiS_Pr->SiS_HT;
  611.  if(HwDeviceExtension->jChipType >= SIS_315H) {
  612.   if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
  613.  }
  614.          tempbx >>= 1;
  615.  tempbx -= 2;
  616.          temp = ((tempbx & 0x0700) >> 8) << 3;
  617.          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
  618.          temp = tempbx & 0x00FF;
  619.          SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
  620.          if( (SiS_Pr->SiS_VBType & (VB_SIS30xLV | VB_SIS30xNEW)) &&
  621.                         (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
  622.              SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
  623.  }
  624.          /* TW: 650 BIOS does this for all bridge types - assumingly wrong */
  625.  if(HwDeviceExtension->jChipType >= SIS_315H) {
  626.              /* TW: This is a duplicate; done for LCDA as well (see above) */
  627.      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
  628. SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
  629.      }
  630.      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
  631.      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
  632.      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
  633.          }
  634.   }  /* 301B */
  635.   SiS_SetCRT2VCLK(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
  636.                   RefreshRateTableIndex,HwDeviceExtension);
  637. }
  638. /* TW: Double-Checked against 650/301LV(x) and 630/301B BIOS */
  639. void
  640. SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  641.                  USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
  642. {
  643.   USHORT vclkindex;
  644.   USHORT tempah;
  645.   vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
  646.                               HwDeviceExtension);
  647.   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  648.     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
  649.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
  650.     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
  651.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
  652. /* TW: New from 650/301LV, LVx BIOS */
  653. if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
  654.            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  655.       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
  656.                  if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
  657.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
  658.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
  659.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
  660.                  }
  661.               }
  662.            }
  663. }
  664.   } else { /* 650/301LVx does not do this anymore, jumps to SetRegs above - BUG? */
  665.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
  666.     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
  667.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
  668.     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
  669.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
  670.   }
  671.   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
  672.   tempah = 0x08;
  673.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
  674.      tempah |= 0x20;
  675.   }
  676.   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
  677. }
  678. /* TW: Double-checked against 650/LVDS (1.10.07), 630/301B/LVDS/LVDS+CH, 650/301LVx (1.10.6s) BIOS */
  679. USHORT
  680. SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  681.                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
  682. {
  683.   USHORT tempbx;
  684. #ifdef SIS300
  685.   const USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
  686.   const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
  687.   const USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
  688.   const USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
  689. #endif
  690. #ifdef SIS315H
  691.   const USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
  692.   const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
  693.   const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
  694.   const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
  695.       /* {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2}; -  650/LVDS 1.10.07 */
  696. #endif
  697.   const USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
  698.   const USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
  699.   USHORT CRT2Index,VCLKIndex=0;
  700.   USHORT modeflag,resinfo;
  701.   const UCHAR *CHTVVCLKPtr=NULL;
  702.   const USHORT *LCDXlatVCLK1 = NULL;
  703.   const USHORT *LCDXlatVCLK2 = NULL;
  704.   const USHORT *LVDSXlatVCLK2 = NULL;
  705.   const USHORT *LVDSXlatVCLK3 = NULL;
  706. #ifdef SIS315H
  707.   if(HwDeviceExtension->jChipType >= SIS_315H) {
  708. LCDXlatVCLK1 = LCDXlat1VCLK310;
  709. LCDXlatVCLK2 = LCDXlat2VCLK310;
  710. LVDSXlatVCLK2 = LVDSXlat2VCLK310;
  711. LVDSXlatVCLK3 = LVDSXlat3VCLK310;
  712.   } else {
  713. #endif
  714. #ifdef SIS300
  715. LCDXlatVCLK1 = LCDXlat1VCLK300;
  716. LCDXlatVCLK2 = LCDXlat2VCLK300;
  717. LVDSXlatVCLK2 = LVDSXlat2VCLK300;
  718. LVDSXlatVCLK3 = LVDSXlat3VCLK300;
  719. #endif
  720. #ifdef SIS315H
  721.   }
  722. #endif
  723.   if(ModeNo<=0x13) {
  724.      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  725.      resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
  726.      CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
  727.   } else {
  728.      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  729.      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  730.      CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
  731.   }
  732.   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {    /* 301 */
  733.      if (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
  734.         CRT2Index >>= 6;
  735.         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
  736.             if(HwDeviceExtension->jChipType < SIS_315H) {
  737.        /* TW: Inserted from 630/301B BIOS */
  738.        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
  739.      VCLKIndex = LCDXlat0VCLK[CRT2Index];
  740.        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
  741.      VCLKIndex = LCDXlatVCLK1[CRT2Index];
  742.        else
  743.      VCLKIndex = LCDXlatVCLK2[CRT2Index];
  744.     } else {
  745.                /* TW: 650/301LV BIOS does not check expanding, 315 does  */
  746.        if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
  747.            (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding)) ) {
  748.                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
  749.      VCLKIndex = 0x19;
  750.   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
  751.      VCLKIndex = 0x19;
  752.   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
  753.      VCLKIndex = 0x21;
  754.   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
  755.      VCLKIndex = LCDXlatVCLK1[CRT2Index];
  756.                   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
  757.      VCLKIndex = 0x45;
  758.      if(resinfo == 0x09) VCLKIndex++;
  759.           } else {
  760.      VCLKIndex = LCDXlatVCLK2[CRT2Index];
  761.                  }
  762.        } else {
  763.                    VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));  /*  Port 3cch */
  764.              VCLKIndex = ((VCLKIndex >> 2) & 0x03);
  765.             if(ModeNo > 0x13) {
  766.            VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  767.             }
  768.    if(ModeNo <= 0x13) {  /* TW: Inserted from 315 BIOS */
  769.       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
  770.    }
  771.    if(VCLKIndex == 0) VCLKIndex = 0x41;
  772.    if(VCLKIndex == 1) VCLKIndex = 0x43;
  773.    if(VCLKIndex == 4) VCLKIndex = 0x44;
  774.        }
  775.     }
  776.         } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
  777.          if((SiS_Pr->SiS_IF_DEF_HiVision == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
  778.            if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = HiTVVCLKDIV2;
  779.       else                                  VCLKIndex = HiTVVCLK;
  780.            if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
  781.              if(modeflag & Charx8Dot)      VCLKIndex = HiTVSimuVCLK;
  782.              else        VCLKIndex = HiTVTextVCLK;
  783.            }
  784.          } else {
  785.         if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = TVVCLKDIV2;
  786.              else                        VCLKIndex = TVVCLK;
  787.            }
  788. if(HwDeviceExtension->jChipType >= SIS_315H) {
  789.                VCLKIndex += 25;
  790.    }
  791.         } else {          /* RAMDAC2 */
  792.          VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
  793.          VCLKIndex = ((VCLKIndex >> 2) & 0x03);
  794.          if(ModeNo > 0x13) {
  795.            VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  796. if(HwDeviceExtension->jChipType < SIS_315H) {
  797.            VCLKIndex &= 0x3f;
  798. if( (HwDeviceExtension->jChipType == SIS_630) &&
  799.     (HwDeviceExtension->jChipRevision >= 0x30)) {
  800.      if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
  801. }
  802. }
  803.          }
  804.         }
  805.     } else {   /* If not programming CRT2 */
  806.         VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
  807.         VCLKIndex = ((VCLKIndex >> 2) & 0x03);
  808.         if(ModeNo > 0x13) {
  809.              VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  810.      if(HwDeviceExtension->jChipType < SIS_315H) {
  811.                 VCLKIndex &= 0x3f;
  812. if( (HwDeviceExtension->jChipType != SIS_630) &&
  813.     (HwDeviceExtension->jChipType != SIS_300) ) {
  814.    if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
  815. }
  816.      }
  817.         }
  818.     }
  819.   } else {       /*   LVDS  */
  820.      VCLKIndex = CRT2Index;
  821. if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
  822.    if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
  823. VCLKIndex &= 0x1f;
  824.          tempbx = 0;
  825.          if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx += 2;
  826.          if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
  827.         switch(tempbx) {
  828.               case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
  829.              case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
  830.                    case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
  831.                    case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
  832.          }
  833.          VCLKIndex = CHTVVCLKPtr[VCLKIndex];
  834.    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  835.         VCLKIndex >>= 6;
  836.       if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
  837.                    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
  838.       VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
  839.       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
  840.       VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
  841. else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
  842.                         VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
  843.       else    VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
  844.    } else {
  845.         VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
  846.                 VCLKIndex = ((VCLKIndex >> 2) & 0x03);
  847.                 if(ModeNo > 0x13) {
  848.                      VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  849.      if( (HwDeviceExtension->jChipType == SIS_630) &&
  850.                          (HwDeviceExtension->jChipRevision >= 0x30) ) {
  851.           if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
  852.      }
  853.         }
  854.    }
  855. } else {  /* if not programming CRT2 */
  856.    VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
  857.            VCLKIndex = ((VCLKIndex >> 2) & 0x03);
  858.            if(ModeNo > 0x13) {
  859.               VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  860.               if(HwDeviceExtension->jChipType < SIS_315H) {
  861.          if( (HwDeviceExtension->jChipType != SIS_630) &&
  862.      (HwDeviceExtension->jChipType != SIS_300) ) {
  863.         if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
  864.          }
  865.       }
  866.    }
  867. }
  868.   }
  869.   if(HwDeviceExtension->jChipType < SIS_315H) {
  870.      VCLKIndex &= 0x3F;
  871.   }
  872.   return (VCLKIndex);
  873. }
  874. /* TW: Set 301 Palette address port registers */
  875. /* TW: Checked against 650/301LV BIOS */
  876. void
  877. SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
  878.               UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
  879. {
  880.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
  881.   if(SiS_Pr->SiS_ModeType == ModeVGA){
  882.     if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
  883.       SiS_EnableCRT2(SiS_Pr);
  884.       SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
  885.     }
  886.   }
  887.   return;
  888. }
  889. /* TW: Checked against 650/LVDS and 630/301B BIOS */
  890. void
  891. SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  892.                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
  893. {
  894.   USHORT temp,tempah,i,modeflag,j;
  895.   USHORT ResInfo,DisplayType;
  896.   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
  897.   if(ModeNo <= 0x13) {
  898.      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  899.   } else {
  900.      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  901.   }
  902.   temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
  903.                             &ResInfo,&DisplayType);
  904.   if(temp == 0) return;
  905.   /* TW: Inserted from 630/LVDS BIOS */
  906.   if(HwDeviceExtension->jChipType < SIS_315H) {
  907.      if(SiS_Pr->SiS_SetFlag & CRT2IsVGA) return;
  908.   }
  909.   switch(DisplayType) {
  910.     case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
  911.     case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
  912.     case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
  913.     case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
  914.     case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
  915.     case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
  916.     case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
  917.     case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
  918.     case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
  919.     case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
  920.     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
  921.     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
  922.     case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
  923.     case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
  924.     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
  925.     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
  926.     case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
  927.     case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
  928.     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
  929.     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
  930.     case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
  931.     case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
  932.     case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break; /* FSTN */
  933.     case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
  934.     case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
  935.     case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
  936.     case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
  937.     case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
  938.     case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
  939.     case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
  940.     case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
  941.     case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
  942.     case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
  943.     case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
  944.     case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
  945.   }
  946.   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
  947.   tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
  948.   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
  949.   for(i=0x02,j=1;i<=0x05;i++,j++){
  950.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  951.     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  952.   }
  953.   for(i=0x06,j=5;i<=0x07;i++,j++){
  954.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  955.     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  956.   }
  957.   for(i=0x10,j=7;i<=0x11;i++,j++){
  958.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  959.     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  960.   }
  961.   for(i=0x15,j=9;i<=0x16;i++,j++){
  962.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  963.     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  964.   }
  965.   for(i=0x0A,j=11;i<=0x0C;i++,j++){
  966.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  967.     SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
  968.   }
  969.   tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
  970.   tempah &= 0xE0;
  971.   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);      /* TW: Modfied (650/LVDS); Was SetReg(tempah) */
  972.   tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
  973.   tempah &= 0x01;
  974.   tempah <<= 5;
  975.   if(modeflag & DoubleScanMode){
  976.      tempah |= 0x080;
  977.   }
  978.   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
  979.   /* TW: Inserted from 650/LVDS BIOS */
  980.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  981.      if(modeflag & HalfDCLK)
  982.         SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
  983.   }
  984.   return;
  985. }
  986. #if 0 /* TW: Unused */
  987. /*301b*/
  988. void
  989. SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  990.                 USHORT RefreshRateTableIndex)
  991. {
  992.   USHORT temp,tempah,i,modeflag,j;
  993.   USHORT ResInfo,DisplayType;
  994.   SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
  995.   if(ModeNo<=0x13) {
  996.      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
  997.   } else {
  998.      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
  999.   }
  1000.   temp=SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
  1001.                        &ResInfo,&DisplayType);
  1002.   if(temp==0){
  1003.     return;
  1004.   }
  1005.   switch(DisplayType) {
  1006.     case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;           break;
  1007.     case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
  1008.     case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
  1009.     case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
  1010.     case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
  1011.     case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
  1012.     case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
  1013.     case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
  1014.     case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
  1015.     case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
  1016.     case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
  1017.     case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
  1018.     case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
  1019.     case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
  1020.     case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
  1021.     case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
  1022.     case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
  1023.     case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
  1024.     case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
  1025.     case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
  1026.     case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
  1027.     case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
  1028.     case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break; /* FSTN */
  1029.   }
  1030.   tempah=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);                        /*unlock cr0-7  */
  1031.   tempah=tempah&0x7F;
  1032.   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x11,tempah);
  1033.   tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
  1034.   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x0,tempah);
  1035.   for(i=0x02,j=1;i<=0x05;i++,j++){
  1036.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  1037.     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  1038.   }
  1039.   for(i=0x06,j=5;i<=0x07;i++,j++){
  1040.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  1041.     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  1042.   }
  1043.   for(i=0x10,j=7;i<=0x11;i++,j++){
  1044.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  1045.     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  1046.   }
  1047.   for(i=0x15,j=9;i<=0x16;i++,j++){
  1048.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  1049.     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
  1050.   }
  1051.   for(i=0x0A,j=11;i<=0x0C;i++,j++){
  1052.     tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
  1053.     SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
  1054.   }
  1055.   tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
  1056.   tempah=tempah&0x0E0;
  1057.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
  1058.   tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
  1059.   tempah=tempah&0x01;
  1060.   tempah=tempah<<5;
  1061.   if(modeflag&DoubleScanMode){
  1062.      tempah=tempah|0x080;
  1063.   }
  1064.   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
  1065.   return;
  1066. }
  1067. #endif
  1068. /* TW: Checked against 650/LVDS BIOS: modified for new panel resolutions */
  1069. BOOLEAN
  1070. SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  1071.    USHORT RefreshRateTableIndex,USHORT *ResInfo,
  1072.    USHORT *DisplayType)
  1073.  {
  1074.   USHORT tempbx,modeflag=0;
  1075.   USHORT Flag,CRT2CRTC;
  1076.   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  1077.       /* TW: Inserted from 650/LVDS BIOS */
  1078.       if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
  1079.           if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0;
  1080.       }
  1081.   }
  1082.   if(ModeNo <= 0x13) {
  1083.      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  1084.      CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
  1085.   } else {
  1086.      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  1087.      CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
  1088.   }
  1089.   Flag = 1;
  1090.   tempbx = 0;
  1091.   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  1092.     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
  1093.       Flag = 0;
  1094.       tempbx = 18;
  1095.       if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx += 2;
  1096.       if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
  1097.     }
  1098.   }
  1099.   if(Flag) {
  1100.     tempbx = SiS_Pr->SiS_LCDResInfo;
  1101.     tempbx -= SiS_Pr->SiS_PanelMinLVDS;
  1102.     if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
  1103.        if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 6;
  1104.        if(modeflag & HalfDCLK) tempbx += 3;
  1105.     } else {
  1106.        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
  1107.            tempbx = 14;
  1108.    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
  1109.    if(modeflag & HalfDCLK) tempbx++;
  1110.        } else if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
  1111.            tempbx = 12;
  1112.    if(modeflag & HalfDCLK) tempbx++;
  1113.        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
  1114.            tempbx = 23;
  1115.    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
  1116.    if(modeflag & HalfDCLK) tempbx++;
  1117.        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
  1118.            tempbx = 27;
  1119.    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
  1120.    if(modeflag & HalfDCLK) tempbx++;
  1121.        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
  1122.            tempbx = 36;
  1123.    if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 2;
  1124.    if(modeflag & HalfDCLK) tempbx++;
  1125.        }
  1126.     }
  1127.   }
  1128.   if(SiS_Pr->SiS_IF_DEF_FSTN){
  1129.      if(SiS_Pr->SiS_LCDResInfo==SiS_Pr->SiS_Panel320x480){
  1130.        tempbx=22;
  1131.      }
  1132.   }
  1133.   *ResInfo = CRT2CRTC & 0x3F;
  1134.   *DisplayType = tempbx;
  1135.   return 1;
  1136. }
  1137. /* TW: Checked against 650/LVDS (1.10a, 1.10.07), 630/301B (I/II) and 630/LVDS BIOS */
  1138. void
  1139. SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
  1140.            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
  1141. {
  1142.   USHORT tempah,tempal,pushax;
  1143.   USHORT vclkindex=0;
  1144.   if(HwDeviceExtension->jChipType < SIS_315H) {
  1145.      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  1146.         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) return;
  1147.      }
  1148.   }
  1149.   if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
  1150. SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
  1151.         tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  1152.      tempal &= 0x3F;
  1153. if(tempal == 2) RefreshRateTableIndex--;
  1154. vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
  1155.                                RefreshRateTableIndex,HwDeviceExtension);
  1156. SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
  1157.   } else {
  1158.         vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
  1159.                                RefreshRateTableIndex,HwDeviceExtension);
  1160.   }
  1161.   tempal = 0x02B;
  1162.   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
  1163.      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
  1164.      tempal += 3;
  1165.      }
  1166.   }
  1167.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
  1168.   pushax = tempal;
  1169.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
  1170.   tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
  1171.   SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
  1172.   tempal++;
  1173.   tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
  1174.   SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
  1175.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
  1176.   tempal = pushax;
  1177.   tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
  1178.   SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
  1179.   tempal++;
  1180.   tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
  1181.   SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
  1182.   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
  1183.   tempal = pushax;
  1184.   tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
  1185.   SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
  1186.   tempal++;
  1187.   tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
  1188.   SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
  1189.   return;
  1190. }
  1191. #if 0  /* TW: Not used */
  1192. void
  1193. SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr)
  1194. {
  1195.   USHORT  temp;
  1196.   if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
  1197.     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x40);
  1198.     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,0x80);
  1199.     temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
  1200.     temp &= 0xC3;
  1201.     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,temp);
  1202.   } else {
  1203.     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x02);
  1204.     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x00);
  1205.   }
  1206. }
  1207. #endif
  1208. /* TW: Start of Chrontel 70xx functions ---------------------- */
  1209. /* Set-up the Chrontel Registers */
  1210. void
  1211. SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
  1212.                USHORT RefreshRateTableIndex)
  1213. {
  1214.   USHORT temp, tempbx, tempcl;
  1215.   USHORT TVType, resindex;
  1216.   const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
  1217.   if(ModeNo <= 0x13)
  1218.      tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
  1219.   else
  1220.      tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
  1221.   TVType = 0;
  1222.   if(SiS_Pr->SiS_VBInfo & SetPALTV) TVType += 2;
  1223.   if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
  1224.   switch(TVType) {
  1225.      case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
  1226.      case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
  1227.      case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
  1228.      case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
  1229.   }
  1230.   resindex = tempcl & 0x3F;
  1231.   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
  1232.      /* Chrontel 7005 */
  1233.      /* TW: We don't support modes >800x600 */
  1234.      if (resindex > 5) return;
  1235.      if(SiS_Pr->SiS_VBInfo & SetPALTV) {
  1236.      SiS_SetCH700x(SiS_Pr,0x4304);   /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
  1237.      SiS_SetCH700x(SiS_Pr,0x6909); /* TW: Black level for PAL (105)*/
  1238.      } else {
  1239.      SiS_SetCH700x(SiS_Pr,0x0304);   /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
  1240.      SiS_SetCH700x(SiS_Pr,0x7109); /* TW: Black level for NTSC (113)*/
  1241.      }
  1242.      temp = CHTVRegData[resindex].Reg[0];
  1243.      tempbx=((temp&0x00FF)<<8)|0x00; /* TW: Mode register */
  1244.      SiS_SetCH700x(SiS_Pr,tempbx);
  1245.      temp = CHTVRegData[resindex].Reg[1];
  1246.      tempbx=((temp&0x00FF)<<8)|0x07; /* TW: Start active video register */
  1247.      SiS_SetCH700x(SiS_Pr,tempbx);
  1248.      temp = CHTVRegData[resindex].Reg[2];
  1249.      tempbx=((temp&0x00FF)<<8)|0x08; /* TW: Position overflow register */
  1250.      SiS_SetCH700x(SiS_Pr,tempbx);
  1251.      temp = CHTVRegData[resindex].Reg[3];
  1252.      tempbx=((temp&0x00FF)<<8)|0x0A; /* TW: Horiz Position register */
  1253.      SiS_SetCH700x(SiS_Pr,tempbx);
  1254.      temp = CHTVRegData[resindex].Reg[4];
  1255.      tempbx=((temp&0x00FF)<<8)|0x0B; /* TW: Vertical Position register */
  1256.      SiS_SetCH700x(SiS_Pr,tempbx);
  1257.      /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
  1258.                 minimum text enhancement (S3-2=10),
  1259.             maximum flicker filter for Chroma channel (S5-4=10)
  1260.         =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
  1261.       */
  1262.      SiS_SetCH700x(SiS_Pr,0x2801);
  1263.      /* TW: Set video bandwidth
  1264.             High bandwith Luma composite video filter(S0=1)
  1265.             low bandwith Luma S-video filter (S2-1=00)
  1266.     disable peak filter in S-video channel (S3=0)
  1267.     high bandwidth Chroma Filter (S5-4=11)
  1268.     =00110001=0x31
  1269.      */
  1270.      SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
  1271.      /* TW: Register 0x3D does not exist in non-macrovision register map
  1272.             (Maybe this is a macrovision register?)
  1273.       */
  1274.      /* SiS_SetCH70xx(SiS_Pr,0x003D); */
  1275.      /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
  1276.             all other bits a read-only. Macrovision?
  1277.       */
  1278.      SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
  1279.      /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
  1280.             contrast enhancement (set to 010 -> gain 2 Yout = 9/8*(Yin-57) )
  1281.       */
  1282.      SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
  1283.      /* TW: Clear DSEN
  1284.       */
  1285.      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
  1286.      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) { /* ---- NTSC ---- */
  1287.        if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) {
  1288.          if(resindex == 0x04) {    /* 640x480 overscan: Mode 16 */
  1289.           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);    /* loop filter off */
  1290.            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on, no need to set FSCI */
  1291.          } else {
  1292.            if(resindex == 0x05) {     /* 800x600 overscan: Mode 23 */
  1293.              SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */
  1294.              SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
  1295.              SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
  1296.              SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
  1297.              SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
  1298.              SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
  1299.              SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
  1300.              SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
  1301.              SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);     /* Loop filter on for mode 23 */
  1302.              SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);     /* ACIV off, need to set FSCI */
  1303.            }
  1304.          }
  1305.        } else {
  1306.          if(resindex == 0x04) {       /* ----- 640x480 underscan; Mode 17 */
  1307.            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);   /* loop filter off */
  1308.            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
  1309.          } else {
  1310.            if(resindex == 0x05) {     /* ----- 800x600 underscan: Mode 24 */
  1311.              SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);     /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
  1312.              SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);  /* FSCI for mode 24 is 428,554,851 */
  1313.              SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);
  1314.              SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
  1315.              SiS_SetCH70xxANDOR(SiS_Pr,0x031C,0xF0);
  1316.              SiS_SetCH70xxANDOR(SiS_Pr,0x0a1D,0xF0);
  1317.              SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
  1318.              SiS_SetCH70xxANDOR(SiS_Pr,0x031F,0xF0);
  1319.              SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);     /* loop filter off for mode 24 */
  1320.              SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);  /* ACIV off, need to set FSCI */
  1321.            }
  1322.          }
  1323.        }
  1324.      } else { /* ---- PAL ---- */
  1325.            /* TW: We don't play around with FSCI in PAL mode */
  1326.          if (resindex == 0x04) {
  1327.            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);  /* loop filter off */
  1328.            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
  1329.          } else {
  1330.            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);  /* loop filter off */
  1331.            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
  1332.          }
  1333.      }
  1334.   } else {
  1335.      /* Chrontel 7019 */
  1336.      /* TW: We don't support modes >1024x768 */
  1337.      if (resindex > 6) return;
  1338.      temp = CHTVRegData[resindex].Reg[0];
  1339.      tempbx=((temp & 0x00FF) <<8 ) | 0x00;
  1340.      SiS_SetCH701x(SiS_Pr,tempbx);
  1341.      temp = CHTVRegData[resindex].Reg[1];
  1342.      tempbx=((temp & 0x00FF) <<8 ) | 0x01;
  1343.      SiS_SetCH701x(SiS_Pr,tempbx);
  1344.      temp = CHTVRegData[resindex].Reg[2];
  1345.      tempbx=((temp & 0x00FF) <<8 ) | 0x02;
  1346.      SiS_SetCH701x(SiS_Pr,tempbx);
  1347.      temp = CHTVRegData[resindex].Reg[3];
  1348.      tempbx=((temp & 0x00FF) <<8 ) | 0x04;
  1349.      SiS_SetCH701x(SiS_Pr,tempbx);
  1350.      temp = CHTVRegData[resindex].Reg[4];
  1351.      tempbx=((temp & 0x00FF) <<8 ) | 0x03;
  1352.      SiS_SetCH701x(SiS_Pr,tempbx);
  1353.      temp = CHTVRegData[resindex].Reg[5];
  1354.      tempbx=((temp & 0x00FF) <<8 ) | 0x05;
  1355.      SiS_SetCH701x(SiS_Pr,tempbx);
  1356.      temp = CHTVRegData[resindex].Reg[6];
  1357.      tempbx=((temp & 0x00FF) <<8 ) | 0x06;
  1358.      SiS_SetCH701x(SiS_Pr,tempbx);
  1359.      temp = CHTVRegData[resindex].Reg[7];
  1360.      tempbx=((temp & 0x00FF) <<8 ) | 0x07;
  1361.      SiS_SetCH701x(SiS_Pr,tempbx);
  1362.      temp = CHTVRegData[resindex].Reg[8];
  1363.      tempbx=((temp & 0x00FF) <<8 ) | 0x08;
  1364.      SiS_SetCH701x(SiS_Pr,tempbx);
  1365.      temp = CHTVRegData[resindex].Reg[9];
  1366.      tempbx=((temp & 0x00FF) <<8 ) | 0x15;
  1367.      SiS_SetCH701x(SiS_Pr,tempbx);
  1368.      temp = CHTVRegData[resindex].Reg[10];
  1369.      tempbx=((temp & 0x00FF) <<8 ) | 0x1f;
  1370.      SiS_SetCH701x(SiS_Pr,tempbx);
  1371.      temp = CHTVRegData[resindex].Reg[11];
  1372.      tempbx=((temp & 0x00FF) <<8 ) | 0x0c;
  1373.      SiS_SetCH701x(SiS_Pr,tempbx);
  1374.      temp = CHTVRegData[resindex].Reg[12];
  1375.      tempbx=((temp & 0x00FF) <<8 ) | 0x0d;
  1376.      SiS_SetCH701x(SiS_Pr,tempbx);
  1377.      temp = CHTVRegData[resindex].Reg[13];
  1378.      tempbx=((temp & 0x00FF) <<8 ) | 0x0e;
  1379.      SiS_SetCH701x(SiS_Pr,tempbx);
  1380.      temp = CHTVRegData[resindex].Reg[14];
  1381.      tempbx=((temp & 0x00FF) <<8 ) | 0x0f;
  1382.      SiS_SetCH701x(SiS_Pr,tempbx);
  1383.      temp = CHTVRegData[resindex].Reg[15];
  1384.      tempbx=((temp & 0x00FF) <<8 ) | 0x10;
  1385.      SiS_SetCH701x(SiS_Pr,tempbx);
  1386.   }
  1387. }
  1388. void
  1389. SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
  1390. {
  1391.   UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
  1392.                         0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
  1393.   UCHAR table28b4[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
  1394.                         0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
  1395.   UCHAR table28c0[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
  1396.                         0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
  1397.   UCHAR *tableptr = NULL;
  1398.   USHORT tempbh;
  1399.   int i;
  1400.   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
  1401.       tableptr = table28c0;
  1402.   } else {
  1403.       tableptr = table28b4;
  1404.   }
  1405.   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
  1406.   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
  1407.      tempbh = SiS_GetCH701x(SiS_Pr,0x73);
  1408.      if(tempbh == 0xc8) {
  1409.         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) return;
  1410.      } else if(tempbh == 0xdb) {
  1411.         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
  1412.      }
  1413.   }
  1414.   for(i=0; i<0x0c; i++) {
  1415.      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
  1416.   }
  1417.   SiS_Chrontel19f2(SiS_Pr);
  1418.   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
  1419.   tempbh |= 0xc0;
  1420.   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
  1421. }
  1422. /* TW: Chrontel 701x functions ================================= */
  1423. void
  1424. SiS_Chrontel19f2(SiS_Private *SiS_Pr)
  1425. {
  1426.   UCHAR regtable[]  = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
  1427.   UCHAR table19e8[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
  1428.   UCHAR table19ed[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
  1429.   UCHAR *tableptr = NULL;
  1430.   int i;
  1431.   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
  1432.       tableptr = table19ed;
  1433.   } else {
  1434.       tableptr = table19e8;
  1435.   }
  1436.   for(i=0; i<5; i++) {
  1437.      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
  1438.   }
  1439. }
  1440. void
  1441. SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
  1442. {
  1443.   USHORT temp;
  1444.   /* TW: Enable Chrontel 7019 LCD panel backlight */
  1445.   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
  1446.         temp = SiS_GetCH701x(SiS_Pr,0x66);
  1447.         temp |= 0x20;
  1448. SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
  1449.   }
  1450. }
  1451. void
  1452. SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
  1453. {
  1454.   USHORT temp;
  1455.   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
  1456.      if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
  1457.         temp = SiS_GetCH701x(SiS_Pr,0x01);
  1458. temp &= 0x3f;
  1459. temp |= 0x80;
  1460. SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
  1461.      }
  1462.      SiS_SetCH701x(SiS_Pr,0x2049);    /* TW: Enable TV path */
  1463.      temp = SiS_GetCH701x(SiS_Pr,0x49);
  1464.      if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
  1465.         temp = SiS_GetCH701x(SiS_Pr,0x73);
  1466. temp |= 0x60;
  1467. SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
  1468.      }
  1469.      temp = SiS_GetCH701x(SiS_Pr,0x47);
  1470.      temp &= 0x7f;
  1471.      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
  1472.      SiS_LongDelay(SiS_Pr,2);
  1473.      temp = SiS_GetCH701x(SiS_Pr,0x47);
  1474.      temp |= 0x80;
  1475.      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
  1476.   }
  1477. }
  1478. void
  1479. SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr)
  1480. {
  1481.   USHORT temp;
  1482.   /* TW: Disable Chrontel 7019 LCD panel backlight */
  1483.   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
  1484.         temp = SiS_GetCH701x(SiS_Pr,0x66);
  1485.         temp &= 0xDF;
  1486. SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
  1487.   }
  1488. }
  1489. void
  1490. SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
  1491. {
  1492.   USHORT temp;
  1493.   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
  1494.         SiS_LongDelay(SiS_Pr,2);
  1495. /* TW: Complete power down of LVDS */
  1496. temp = SiS_GetCH701x(SiS_Pr,0x76);
  1497. temp &= 0xfc;
  1498. SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
  1499. SiS_SetCH701x(SiS_Pr,0x0066);
  1500.   }
  1501. }
  1502. void
  1503. SiS_ChrontelResetDB(SiS_Private *SiS_Pr)
  1504. {
  1505.      /* TW: Reset Chrontel 7019 datapath */
  1506.      SiS_SetCH701x(SiS_Pr,0x1048);
  1507.      SiS_LongDelay(SiS_Pr,1);
  1508.      SiS_SetCH701x(SiS_Pr,0x1848);
  1509. }
  1510. void
  1511. SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
  1512. {
  1513.      USHORT temp;
  1514.      SiS_SetCH701x(SiS_Pr,0xaf76);
  1515.      temp = SiS_GetCH701x(SiS_Pr,0x49);
  1516.      temp &= 1;
  1517.      if(temp != 1) {
  1518. temp = SiS_GetCH701x(SiS_Pr,0x47);
  1519. temp &= 0x70;
  1520. SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
  1521. SiS_LongDelay(SiS_Pr,3);
  1522. temp = SiS_GetCH701x(SiS_Pr,0x47);
  1523. temp |= 0x80;
  1524. SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
  1525.      }
  1526. }
  1527. void
  1528. SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
  1529.                          USHORT BaseAddr)
  1530. {
  1531.      USHORT temp,temp1;
  1532.      temp1 = 0;
  1533.      temp = SiS_GetCH701x(SiS_Pr,0x61);
  1534.      if(temp < 2) {
  1535.           temp++;
  1536.   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
  1537.   temp1 = 1;
  1538.      }
  1539.      SiS_SetCH701x(SiS_Pr,0xac76);
  1540.      temp = SiS_GetCH701x(SiS_Pr,0x66);
  1541.      temp |= 0x5f;
  1542.      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
  1543.      if(ModeNo > 0x13) {
  1544.          if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
  1545.     SiS_GenericDelay(SiS_Pr,0x3ff);
  1546.  } else {
  1547.     SiS_GenericDelay(SiS_Pr,0x2ff);
  1548.  }
  1549.      } else {
  1550.          if(!temp1)
  1551.     SiS_GenericDelay(SiS_Pr,0x2ff);
  1552.      }
  1553.      temp = SiS_GetCH701x(SiS_Pr,0x76);
  1554.      temp |= 0x03;
  1555.      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
  1556.      temp = SiS_GetCH701x(SiS_Pr,0x66);
  1557.      temp &= 0x7f;
  1558.      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
  1559.      SiS_LongDelay(SiS_Pr,1);
  1560. }
  1561. void
  1562. SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
  1563. {
  1564.      USHORT temp,tempcl,tempch;
  1565.      SiS_LongDelay(SiS_Pr, 1);
  1566.      tempcl = 3;
  1567.      tempch = 0;
  1568.      do {
  1569.        temp = SiS_GetCH701x(SiS_Pr,0x66);
  1570.        temp &= 0x04;
  1571.        if(temp == 0x04) break;
  1572.        SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension, BaseAddr);
  1573.        if(tempcl == 0) {
  1574.            if(tempch == 3) break;
  1575.    SiS_ChrontelResetDB(SiS_Pr);
  1576.    tempcl = 3;
  1577.    tempch++;
  1578.        }
  1579.        tempcl--;
  1580.        temp = SiS_GetCH701x(SiS_Pr,0x76);
  1581.        temp &= 0xfb;
  1582.        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
  1583.        SiS_LongDelay(SiS_Pr,2);
  1584.        temp = SiS_GetCH701x(SiS_Pr,0x76);
  1585.        temp |= 0x04;
  1586.        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
  1587.        SiS_SetCH701x(SiS_Pr,0x6078);
  1588.        SiS_LongDelay(SiS_Pr,2);
  1589.     } while(0);
  1590.     SiS_SetCH701x(SiS_Pr,0x0077);
  1591. }
  1592. void
  1593. SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
  1594.                          USHORT BaseAddr)
  1595. {
  1596.      USHORT temp;
  1597.      temp = SiS_GetCH701x(SiS_Pr,0x03);
  1598.      temp |= 0x80;
  1599.      temp &= 0xbf;
  1600.      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
  1601.      SiS_ChrontelResetDB(SiS_Pr);
  1602.      SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension, BaseAddr);
  1603.      temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
  1604.      SiS_ChrontelDoSomething3(SiS_Pr,temp, HwDeviceExtension, BaseAddr);
  1605.      SiS_SetCH701x(SiS_Pr,0xaf76);
  1606. }
  1607. /* TW: End of Chrontel 701x functions ==================================== */
  1608. /* TW: Generic Read/write routines for Chrontel ========================== */
  1609. /* TW: The Chrontel is connected to the 630/730 via
  1610.  * the 630/730's DDC/I2C port.
  1611.  *
  1612.  * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
  1613.  * possibly for working around the DDC problems
  1614.  */
  1615. void
  1616. SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
  1617. {
  1618.    if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
  1619.       SiS_SetCH700x(SiS_Pr,tempbx);
  1620.    else
  1621.       SiS_SetCH701x(SiS_Pr,tempbx);
  1622. }
  1623. /* TW: Write to Chrontel 700x */
  1624. /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
  1625. void
  1626. SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
  1627. {
  1628.   USHORT tempah,temp,i;
  1629.   if(!(SiS_Pr->SiS_ChrontelInit)) {
  1630.      SiS_Pr->SiS_DDC_Index = 0x11;    /* TW: Bit 0 = SC;  Bit 1 = SD */
  1631.      SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
  1632.      SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
  1633.      SiS_Pr->SiS_DDC_DataShift = 0x00;
  1634.      SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;      /* TW: DAB (Device Address Byte) */
  1635.   }
  1636.   for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
  1637.     /* SiS_SetSwitchDDC2(SiS_Pr); */
  1638.     if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
  1639.     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
  1640.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
  1641.     if(temp) continue; /* TW:    (ERROR: no ack) */
  1642.     tempah = tempbx & 0x00FF; /* TW: Write RAB */
  1643.     tempah |= 0x80;                             /* TW: (set bit 7, see datasheet) */
  1644.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
  1645.     if(temp) continue; /* TW:    (ERROR: no ack) */
  1646.     tempah = (tempbx & 0xFF00) >> 8;
  1647.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
  1648.     if(temp) continue; /* TW:    (ERROR: no ack) */
  1649.     if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
  1650.     SiS_Pr->SiS_ChrontelInit = 1;
  1651.     return;
  1652.   }
  1653.   /* TW: For 630ST */
  1654.   if(!(SiS_Pr->SiS_ChrontelInit)) {
  1655.      SiS_Pr->SiS_DDC_Index = 0x0a; /* TW: Bit 7 = SC;  Bit 6 = SD */
  1656.      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
  1657.      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
  1658.      SiS_Pr->SiS_DDC_DataShift = 0x00;
  1659.      SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;   /* TW: DAB (Device Address Byte) */
  1660.      for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
  1661.        /* SiS_SetSwitchDDC2(SiS_Pr); */
  1662.        if (SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
  1663.        tempah = SiS_Pr->SiS_DDC_DeviceAddr;
  1664.        temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
  1665.        if(temp) continue; /* TW:    (ERROR: no ack) */
  1666.        tempah = tempbx & 0x00FF; /* TW: Write RAB */
  1667.        tempah |= 0x80;                          /* TW: (set bit 7, see datasheet) */
  1668.        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
  1669.        if(temp) continue; /* TW:    (ERROR: no ack) */
  1670.        tempah = (tempbx & 0xFF00) >> 8;
  1671.        temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
  1672.        if(temp) continue; /* TW:    (ERROR: no ack) */
  1673.        if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
  1674.        SiS_Pr->SiS_ChrontelInit = 1;
  1675.        return;
  1676.     }
  1677.   }
  1678. }
  1679. /* TW: Write to Chrontel 701x */
  1680. /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
  1681. void
  1682. SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
  1683. {
  1684.   USHORT tempah,temp,i;
  1685.   SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC;  Bit 1 = SD */
  1686.   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
  1687.   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
  1688.   SiS_Pr->SiS_DDC_DataShift = 0x00;
  1689.   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;   /* TW: DAB (Device Address Byte) */
  1690.   for(i=0;i<10;i++) { /* TW: Do only 10 attempts to write */
  1691.     if (SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
  1692.     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
  1693.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
  1694.     if(temp) continue; /* TW:    (ERROR: no ack) */
  1695.     tempah = tempbx & 0x00FF;
  1696.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write RAB */
  1697.     if(temp) continue; /* TW:    (ERROR: no ack) */
  1698.     tempah = (tempbx & 0xFF00) >> 8;
  1699.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write data */
  1700.     if(temp) continue; /* TW:    (ERROR: no ack) */
  1701.     if(SiS_SetStop(SiS_Pr)) continue; /* TW: Set stop condition */
  1702.     return;
  1703.   }
  1704. }
  1705. /* TW: Read from Chrontel 70xx */
  1706. /* Parameter is [Register no (S7-S0)] */
  1707. USHORT
  1708. SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
  1709. {
  1710.    if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
  1711.       return(SiS_GetCH700x(SiS_Pr,tempbx));
  1712.    else
  1713.       return(SiS_GetCH701x(SiS_Pr,tempbx));
  1714. }
  1715. /* TW: Read from Chrontel 700x */
  1716. /* Parameter is [Register no (S7-S0)] */
  1717. USHORT
  1718. SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
  1719. {
  1720.   USHORT tempah,temp,i;
  1721.   if(!(SiS_Pr->SiS_ChrontelInit)) {
  1722.      SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC;  Bit 1 = SD */
  1723.      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
  1724.      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
  1725.      SiS_Pr->SiS_DDC_DataShift = 0x00;
  1726.      SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB */
  1727.   }
  1728.   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
  1729.   for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
  1730.     /* SiS_SetSwitchDDC2(SiS_Pr); */
  1731.     if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
  1732.     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
  1733.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
  1734.     if(temp) continue; /* TW:        (ERROR: no ack) */
  1735.     tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* TW: Write RAB | 0x80 */
  1736.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
  1737.     if(temp) continue; /* TW:        (ERROR: no ack) */
  1738.     if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
  1739.     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
  1740.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
  1741.     if(temp) continue; /* TW:        (ERROR: no ack) */
  1742.     tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
  1743.     if (SiS_SetStop(SiS_Pr)) continue; /* TW: Stop condition */
  1744.     SiS_Pr->SiS_ChrontelInit = 1;
  1745.     return(tempah);
  1746.   }
  1747.   /* TW: For 630ST */
  1748.   if(!SiS_Pr->SiS_ChrontelInit) {
  1749.      SiS_Pr->SiS_DDC_Index = 0x0a; /* TW: Bit 0 = SC;  Bit 1 = SD */
  1750.      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
  1751.      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
  1752.      SiS_Pr->SiS_DDC_DataShift = 0x00;
  1753.      SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;   /* TW: DAB (Device Address Byte) */
  1754.      for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
  1755.        /* SiS_SetSwitchDDC2(SiS_Pr); */
  1756.        if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
  1757.        tempah = SiS_Pr->SiS_DDC_DeviceAddr;
  1758.        temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
  1759.        if(temp) continue; /* TW:        (ERROR: no ack) */
  1760.        tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80; /* TW: Write RAB | 0x80 */
  1761.        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
  1762.        if(temp) continue; /* TW:        (ERROR: no ack) */
  1763.        if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
  1764.        tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;  /* DAB | 0x01 = Read */
  1765.        temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
  1766.        if(temp) continue; /* TW:        (ERROR: no ack) */
  1767.        tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
  1768.        if (SiS_SetStop(SiS_Pr)) continue; /* TW: Stop condition */
  1769.        SiS_Pr->SiS_ChrontelInit = 1;
  1770.        return(tempah);
  1771.      }
  1772.   }
  1773.   return(0xFFFF);
  1774. }
  1775. /* TW: Read from Chrontel 701x */
  1776. /* Parameter is [Register no (S7-S0)] */
  1777. USHORT
  1778. SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
  1779. {
  1780.   USHORT tempah,temp,i;
  1781.   SiS_Pr->SiS_DDC_Index = 0x11; /* TW: Bit 0 = SC;  Bit 1 = SD */
  1782.   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
  1783.   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
  1784.   SiS_Pr->SiS_DDC_DataShift = 0x00;
  1785.   SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* TW: DAB */
  1786.   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
  1787.    for(i=0;i<20;i++) { /* TW: Do only 20 attempts to read */
  1788.     if(SiS_SetStart(SiS_Pr)) continue; /* TW: Set start condition */
  1789.     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
  1790.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: Write DAB (S0=0=write) */
  1791.     if(temp) continue; /* TW:        (ERROR: no ack) */
  1792.     tempah = SiS_Pr->SiS_DDC_ReadAddr; /* TW: Write RAB */
  1793.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
  1794.     if(temp) continue; /* TW:        (ERROR: no ack) */
  1795.     if (SiS_SetStart(SiS_Pr)) continue; /* TW: Re-start */
  1796.     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
  1797.     temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* TW: DAB (S0=1=read) */
  1798.     if(temp) continue; /* TW:        (ERROR: no ack) */
  1799.     tempah = SiS_ReadDDC2Data(SiS_Pr,tempah); /* TW: Read byte */
  1800.     SiS_SetStop(SiS_Pr); /* TW: Stop condition */
  1801.     return(tempah);
  1802.    }
  1803.   return 0xFFFF;
  1804. }
  1805. #ifdef LINUX_XF86
  1806. /* TW: Our own DDC functions */
  1807. USHORT
  1808. SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype)
  1809. {
  1810.      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6};
  1811.      unsigned char flag, cr32;
  1812.      USHORT        temp = 0, myadaptnum = adaptnum;
  1813.      SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
  1814.      SiS_Pr->SiS_DDC_SecAddr = 0;
  1815.      SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
  1816.      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
  1817.      SiS_Pr->SiS_DDC_Index = 0x11;
  1818.      flag = 0xff;
  1819.      cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
  1820.      if(pSiS->VGAEngine == SIS_300_VGA) { /* 300 series */
  1821.         if(pSiS->VBFlags & VB_SISBRIDGE) {
  1822.    if(myadaptnum == 0) {
  1823.       if(!(cr32 & 0x20)) {
  1824.          myadaptnum = 2;
  1825.  if(!(cr32 & 0x10)) {
  1826.     myadaptnum = 1;
  1827.     if(!(cr32 & 0x08)) {
  1828.        myadaptnum = 0;
  1829.     }
  1830.  }
  1831.               }
  1832.    }
  1833. }
  1834.         if(myadaptnum != 0) {
  1835.    flag = 0;
  1836.    if(pSiS->VBFlags & VB_SISBRIDGE) {
  1837.       SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
  1838.               SiS_Pr->SiS_DDC_Index = 0x0f;
  1839.    }
  1840.         }
  1841. if(cr32 & 0x80) {
  1842.            if(myadaptnum >= 1) {
  1843.       if(!(cr32 & 0x08)) {
  1844.           myadaptnum = 1;
  1845.   if(!(cr32 & 0x10)) return 0xFFFF;
  1846.               }
  1847.    }
  1848. }
  1849. temp = 4 - (myadaptnum * 2);
  1850. if(flag) temp = 0;
  1851. SiS_Pr->SiS_DDC_Data = 0x02 << temp;
  1852.         SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
  1853.      } else { /* 310/325 series */
  1854.         if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) myadaptnum = 0;
  1855. if(pSiS->VBFlags & VB_SISBRIDGE) {
  1856.    if(myadaptnum == 0) {
  1857.       if(!(cr32 & 0x20)) {
  1858.          myadaptnum = 2;
  1859.  if(!(cr32 & 0x10)) {
  1860.     myadaptnum = 1;
  1861.     if(!(cr32 & 0x08)) {
  1862.        myadaptnum = 0;
  1863.     }
  1864.  }
  1865.               }
  1866.    }
  1867.    if(myadaptnum == 2) {
  1868.       myadaptnum = 1;
  1869.            }
  1870. }
  1871.         if(myadaptnum == 1) {
  1872.          flag = 0;
  1873.    if(pSiS->VBFlags & VB_SISBRIDGE) {
  1874.       SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
  1875.               SiS_Pr->SiS_DDC_Index = 0x0f;
  1876.    }
  1877.         }
  1878.         if(cr32 & 0x80) {
  1879.            if(myadaptnum >= 1) {
  1880.       if(!(cr32 & 0x08)) {
  1881.          myadaptnum = 1;
  1882.  if(!(cr32 & 0x10)) return 0xFFFF;
  1883.       }
  1884.    }
  1885.         }
  1886.         temp = myadaptnum;
  1887.         if(myadaptnum == 1) {
  1888.            temp = 0;
  1889.    if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
  1890.         }
  1891. if(flag) temp = 0;
  1892.         SiS_Pr->SiS_DDC_Data = 0x02 << temp;
  1893.         SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
  1894.     }
  1895.     return 0;
  1896. }
  1897. USHORT
  1898. SiS_WriteDABDDC(SiS_Private *SiS_Pr)
  1899. {
  1900.    SiS_SetStart(SiS_Pr);
  1901.    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) return 0xFFFF;
  1902.    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) return 0xFFFF;
  1903.    return(0);
  1904. }
  1905. USHORT
  1906. SiS_PrepareReadDDC(SiS_Private *SiS_Pr)
  1907. {
  1908.    SiS_SetStart(SiS_Pr);
  1909.    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) return 0xFFFF;
  1910.    return(0);
  1911. }
  1912. USHORT
  1913. SiS_PrepareDDC(SiS_Private *SiS_Pr)
  1914. {
  1915.    if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
  1916.    if(SiS_PrepareReadDDC(SiS_Pr)) return(SiS_PrepareReadDDC(SiS_Pr));
  1917.    return(0);
  1918. }
  1919. void
  1920. SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno)
  1921. {
  1922.    SiS_SetSCLKLow(SiS_Pr);
  1923.    if(yesno) {
  1924.       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index,
  1925.                       ~SiS_Pr->SiS_DDC_Data, SiS_Pr->SiS_DDC_Data);
  1926.    } else {
  1927.       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index,
  1928.                       ~SiS_Pr->SiS_DDC_Data, 0);
  1929.    }
  1930.    SiS_SetSCLKHigh(SiS_Pr);
  1931. }
  1932. USHORT
  1933. SiS_DoProbeDDC(SiS_Private *SiS_Pr)
  1934. {
  1935.     unsigned char mask, value;
  1936.     USHORT  temp, ret;
  1937.     SiS_SetSwitchDDC2(SiS_Pr);
  1938.     if(SiS_PrepareDDC(SiS_Pr)) {
  1939.          SiS_SetStop(SiS_Pr);
  1940.          return(0xFFFF);
  1941.     }
  1942.     mask = 0xf0;
  1943.     value = 0x20;
  1944.     if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
  1945.        temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
  1946.        SiS_SendACK(SiS_Pr, 0);
  1947.        if(temp == 0) {
  1948.            mask = 0xff;
  1949.    value = 0xff;
  1950.        }
  1951.     }
  1952.     temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
  1953.     SiS_SendACK(SiS_Pr, 1);
  1954.     temp &= mask;
  1955.     if(temp == value) ret = 0;
  1956.     else {
  1957.        ret = 0xFFFF;
  1958.        if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
  1959.            if(value == 0x30) ret = 0;
  1960.        }
  1961.     }
  1962.     SiS_SetStop(SiS_Pr);
  1963.     return(ret);
  1964. }
  1965. USHORT
  1966. SiS_ProbeDDC(SiS_Private *SiS_Pr)
  1967. {
  1968.    USHORT flag;
  1969.    flag = 0x180;
  1970.    SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
  1971.    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
  1972.    SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
  1973.    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
  1974.    SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
  1975.    if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
  1976.    if(!(flag & 0x1a)) flag = 0;
  1977.    return(flag);
  1978. }
  1979. USHORT
  1980. SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
  1981. {
  1982.    USHORT flag, length, i;
  1983.    unsigned char chksum,gotcha;
  1984.    if(DDCdatatype > 3) return 0xFFFF;  /* incomplete! */
  1985.    flag = 0;
  1986.    SiS_SetSwitchDDC2(SiS_Pr);
  1987.    if(!(SiS_PrepareDDC(SiS_Pr))) {
  1988.       length = 127;
  1989.       if(DDCdatatype != 1) length = 255;
  1990.       chksum = 0;
  1991.       gotcha = 0;
  1992.       for(i=0; i<length; i++) {
  1993.          buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
  1994.  chksum += buffer[i];
  1995.  gotcha |= buffer[i];
  1996.  SiS_SendACK(SiS_Pr, 0);
  1997.       }
  1998.       buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
  1999.       chksum += buffer[i];
  2000.       SiS_SendACK(SiS_Pr, 1);
  2001.       if(gotcha) flag = (USHORT)chksum;
  2002.       else flag = 0xFFFF;
  2003.    } else {
  2004.       flag = 0xFFFF;
  2005.    }
  2006.    SiS_SetStop(SiS_Pr);
  2007.    return(flag);
  2008. }
  2009. /* TW: Our private DDC function
  2010.    It complies somewhat with the corresponding VESA function
  2011.    in arguments and return values.
  2012.    Since this is probably called before the mode is changed,
  2013.    we use our pre-detected pSiS-values instead of SiS_Pr as
  2014.    regards chipset and video bridge type.
  2015.    Arguments:
  2016.        adaptnum: 0=CRT1, 1=CRT2
  2017.                  CRT2 DDC is not supported in some cases.
  2018.        DDCdatatype: 0=Probe, 1=EDID, 2=VDIF(not supported), 3=?, 4=?(not supported)
  2019.        buffer: ptr to 256 data bytes which will be filled with read data.
  2020.    Returns 0xFFFF if error, otherwise
  2021.        if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
  2022.        if DDCdatatype = 0:  Returns supported DDC modes
  2023.  */
  2024. USHORT
  2025. SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
  2026.               USHORT DDCdatatype, unsigned char *buffer)
  2027. {
  2028.    if(DDCdatatype == 2) return 0xFFFF;
  2029.    if(adaptnum > 2) return 0xFFFF;
  2030.    if(pSiS->VGAEngine == SIS_300_VGA) {
  2031.       if((adaptnum != 0) && (DDCdatatype != 0)) return 0xFFFF;
  2032.    }
  2033.    if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
  2034.    if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype) == 0xFFFF) return 0xFFFF;
  2035.    if(DDCdatatype == 0) {
  2036.        return(SiS_ProbeDDC(SiS_Pr));
  2037.    } else {
  2038.        if(DDCdatatype > 4) return 0xFFFF;
  2039.        return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
  2040.    }
  2041. }
  2042. /* TW: Generic I2C functions (compliant to i2c library) */
  2043. #if 0
  2044. USHORT
  2045. SiS_I2C_GetByte(SiS_Private *SiS_Pr)
  2046. {
  2047.    return(SiS_ReadDDC2Data(SiS_Pr,0));
  2048. }
  2049. Bool
  2050. SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data)
  2051. {
  2052.    if(SiS_WriteDDC2Data(SiS_Pr,data)) return FALSE;
  2053.    return TRUE;
  2054. }
  2055. Bool
  2056. SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr)
  2057. {
  2058.    if(SiS_SetStart(SiS_Pr)) return FALSE;
  2059.    if(SiS_WriteDDC2Data(SiS_Pr,addr)) return FALSE;
  2060.    return TRUE;
  2061. }
  2062. void
  2063. SiS_I2C_Stop(SiS_Private *SiS_Pr)
  2064. {
  2065.    SiS_SetStop(SiS_Pr);
  2066. }
  2067. #endif
  2068. #endif
  2069. void
  2070. SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
  2071. {
  2072.   USHORT tempal,tempah,tempbl;
  2073.   tempal = tempax & 0x00FF;
  2074.   tempah =(tempax >> 8) & 0x00FF;
  2075.   tempbl = SiS_GetCH70xx(SiS_Pr,tempal);
  2076.   tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
  2077.   SiS_SetCH70xx(SiS_Pr,tempbl);
  2078. }
  2079. /* TW: Generic I2C functions for Chrontel --------- */
  2080. void
  2081. SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
  2082. {
  2083.   SiS_SetSCLKHigh(SiS_Pr);
  2084.   /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
  2085.   SiS_WaitRetraceDDC(SiS_Pr);
  2086.   SiS_SetSCLKLow(SiS_Pr);
  2087.   /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
  2088.   SiS_WaitRetraceDDC(SiS_Pr);
  2089. }
  2090. /* TW: Set I2C start condition */
  2091. /* TW: This is done by a SD high-to-low transition while SC is high */
  2092. USHORT
  2093. SiS_SetStart(SiS_Private *SiS_Pr)
  2094. {
  2095.   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;            /* TW: (SC->low)  */
  2096.   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2097.                   ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* TW: SD->high */
  2098.   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;            /* TW: SC->high */
  2099.   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2100.                   ~SiS_Pr->SiS_DDC_Data,0x00);                             /* TW: SD->low = start condition */
  2101.   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;            /* TW: (SC->low) */
  2102.   return 0;
  2103. }
  2104. /* TW: Set I2C stop condition */
  2105. /* TW: This is done by a SD low-to-high transition while SC is high */
  2106. USHORT
  2107. SiS_SetStop(SiS_Private *SiS_Pr)
  2108. {
  2109.   if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;            /* TW: (SC->low) */
  2110.   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2111.                   ~SiS_Pr->SiS_DDC_Data,0x00);              /* TW: SD->low   */
  2112.   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;            /* TW: SC->high  */
  2113.   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2114.                   ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);      /* TW: SD->high = stop condition */
  2115.   if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;            /* TW: (SC->high) */
  2116.   return 0;
  2117. }
  2118. /* TW: Write 8 bits of data */
  2119. USHORT
  2120. SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
  2121. {
  2122.   USHORT i,flag,temp;
  2123.   flag=0x80;
  2124.   for(i=0;i<8;i++) {
  2125.     SiS_SetSCLKLow(SiS_Pr);                       /* TW: SC->low */
  2126.     if(tempax & flag) {
  2127.       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2128.                       ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* TW: Write bit (1) to SD */
  2129.     } else {
  2130.       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2131.                       ~SiS_Pr->SiS_DDC_Data,0x00);                            /* TW: Write bit (0) to SD */
  2132.     }
  2133.     SiS_SetSCLKHigh(SiS_Pr);                       /* TW: SC->high */
  2134.     flag >>= 1;
  2135.   }
  2136.   temp = SiS_CheckACK(SiS_Pr);                       /* TW: Check acknowledge */
  2137.   return(temp);
  2138. }
  2139. USHORT
  2140. SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
  2141. {
  2142.   USHORT i,temp,getdata;
  2143.   getdata=0;
  2144.   for(i=0; i<8; i++) {
  2145.     getdata <<= 1;
  2146.     SiS_SetSCLKLow(SiS_Pr);
  2147.     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2148.                     ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);
  2149.     SiS_SetSCLKHigh(SiS_Pr);
  2150.     temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
  2151.     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
  2152.   }
  2153.   return(getdata);
  2154. }
  2155. USHORT
  2156. SiS_SetSCLKLow(SiS_Private *SiS_Pr)
  2157. {
  2158.   USHORT temp, watchdog=50000;
  2159.   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2160.                   ~SiS_Pr->SiS_DDC_Clk,0x00);       /* SetSCLKLow()  */
  2161.   do {
  2162.     temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
  2163.   } while((temp & SiS_Pr->SiS_DDC_Clk) && --watchdog);
  2164.   if (!watchdog) return 0xFFFF;
  2165.   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
  2166.   return 0;
  2167. }
  2168. USHORT
  2169. SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
  2170. {
  2171.   USHORT temp,watchdog=50000;
  2172.   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2173.                   ~SiS_Pr->SiS_DDC_Clk,SiS_Pr->SiS_DDC_Clk);   /* SetSCLKHigh()  */
  2174.   do {
  2175.     temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
  2176.   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
  2177.   if (!watchdog) return 0xFFFF;
  2178.   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
  2179.   return 0;
  2180. }
  2181. void
  2182. SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
  2183. {
  2184.   USHORT i;
  2185.   for(i=0; i<delaytime; i++) {
  2186.     SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
  2187.   }
  2188. }
  2189. /* TW: Check I2C acknowledge */
  2190. /* Returns 0 if ack ok, non-0 if ack not ok */
  2191. USHORT
  2192. SiS_CheckACK(SiS_Private *SiS_Pr)
  2193. {
  2194.   USHORT tempah;
  2195.   SiS_SetSCLKLow(SiS_Pr);            /* TW: (SC->low) */
  2196.   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
  2197.                   ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* TW: (SD->high) */
  2198.   SiS_SetSCLKHigh(SiS_Pr);            /* TW: SC->high = clock impulse for ack */
  2199.   tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
  2200.   SiS_SetSCLKLow(SiS_Pr);            /* TW: SC->low = end of clock impulse */
  2201.   if(tempah & SiS_Pr->SiS_DDC_Data) return(1);    /* TW: Ack OK if bit = 0 */
  2202.   else return(0);
  2203. }
  2204. /* TW: End of I2C functions ----------------------- */
  2205. /* =============== SiS 310/325 O.E.M. ================= */
  2206. #ifdef SIS315H
  2207. USHORT
  2208. GetLCDPtrIndex(SiS_Private *SiS_Pr)
  2209. {
  2210.   USHORT index;
  2211.   index = SiS_Pr->SiS_LCDResInfo & 0x0F;
  2212.   index--;
  2213.   index *= 3;
  2214.   if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) index += 2;
  2215.   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
  2216.   return index;
  2217. }
  2218. /*
  2219. ---------------------------------------------------------
  2220.        GetTVPtrIndex()
  2221.           return       0 : NTSC Enhanced/Standard
  2222.                        1 : NTSC Standard TVSimuMode
  2223.                        2 : PAL Enhanced/Standard
  2224.                        3 : PAL Standard TVSimuMode
  2225.                        4 : HiVision Enhanced/Standard
  2226.                        5 : HiVision Standard TVSimuMode
  2227. ---------------------------------------------------------
  2228. */
  2229. USHORT
  2230. GetTVPtrIndex(SiS_Private *SiS_Pr)
  2231. {
  2232.   USHORT index;
  2233.   index = 0;
  2234.   if(SiS_Pr->SiS_VBInfo & SetPALTV) index++;
  2235.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index++;  /* Hivision TV use PAL */
  2236.   index <<= 1;
  2237.   if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (SiS_Pr->SiS_SetFlag & TVSimuMode))
  2238.     index++;
  2239.   return index;
  2240. }
  2241. /* TW: Checked against 650/LVDS (1.10.07) and 650/301LVx (1.10.6s) BIOS (including data) */
  2242. void
  2243. SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2244.              UCHAR *ROMAddr,USHORT ModeNo)
  2245. {
  2246.   USHORT delay,index;
  2247.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
  2248.      delay = SiS310_CRT2DelayCompensation1;
  2249.      if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B))
  2250.        delay = SiS310_CRT2DelayCompensation2;
  2251.      if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
  2252.        delay = SiS310_CRT2DelayCompensation3;
  2253.   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  2254.      index = GetLCDPtrIndex(SiS_Pr);
  2255.      delay = SiS310_LCDDelayCompensation1[index];
  2256.      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
  2257.        delay = SiS310_LCDDelayCompensation2[index];
  2258.      if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
  2259.        delay = SiS310_LCDDelayCompensation3[index];
  2260.   } else {
  2261.      index = GetTVPtrIndex(SiS_Pr);
  2262.      delay = SiS310_TVDelayCompensation1[index];
  2263.      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
  2264.        delay = SiS310_TVDelayCompensation2[index];
  2265.      if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
  2266.        delay = SiS310_TVDelayCompensation3[index];
  2267.   }
  2268.   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  2269.     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  2270.        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
  2271.     } else {
  2272.        delay <<= 4;
  2273.        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
  2274.     }
  2275.   } else {
  2276.      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);  /* index 2D D[3:0] */
  2277.   }
  2278. }
  2279. /* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
  2280. void
  2281. SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2282.                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2283. {
  2284.   USHORT index,temp;
  2285.   temp = GetTVPtrIndex(SiS_Pr);
  2286.   temp >>= 1;     /* 0: NTSC, 1: PAL, 2: HiTV */
  2287.   if (ModeNo<=0x13)
  2288.     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
  2289.   else
  2290.     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
  2291.   temp = SiS310_TVAntiFlick1[temp][index];
  2292.   temp <<= 4;
  2293.   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
  2294. }
  2295. /* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
  2296. void
  2297. SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2298.                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2299. {
  2300.   USHORT index,temp;
  2301.   temp = GetTVPtrIndex(SiS_Pr);
  2302.   temp >>= 1;               /* 0: NTSC, 1: PAL, 2: HiTV */
  2303.   if (ModeNo<=0x13)
  2304.     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
  2305.   else
  2306.     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
  2307.   temp = SiS310_TVEdge1[temp][index];
  2308.   temp <<= 5;
  2309.   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
  2310. }
  2311. /* TW: Checked against 650/301LVx 1.10.6s BIOS (incl data) */
  2312. void
  2313. SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2314.            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2315. {
  2316.   USHORT index, temp, i, j;
  2317.   UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
  2318.   temp = GetTVPtrIndex(SiS_Pr);
  2319.   temp >>= 1;   /* 0: NTSC, 1: PAL, 2: HiTV */
  2320.   if (ModeNo<=0x13) {
  2321.     index =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
  2322.   } else {
  2323.     index =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
  2324.   }
  2325.   if(SiS_Pr->SiS_VBInfo&SetCRT2ToHiVisionTV)  temp = 1;  /* Hivision TV uses PAL */
  2326.   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  2327.     for(i=0x35, j=0; i<=0x38; i++, j++) {
  2328.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
  2329.     }
  2330.     for(i=0x48; i<=0x4A; i++, j++) {
  2331.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
  2332.     }
  2333.   } else {
  2334.     for(i=0x35, j=0; i<=0x38; i++, j++){
  2335.        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
  2336.     }
  2337.   }
  2338.   
  2339.   if(ROMAddr && SiS_Pr->SiS_UseROM) {
  2340.    OutputSelect = ROMAddr[0xf3];
  2341.   }
  2342.   if(OutputSelect & EnablePALMN) {
  2343.       if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
  2344.          temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
  2345.          temp &= (EnablePALMN | EnablePALN);
  2346.          if(temp == EnablePALMN) {
  2347.               if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  2348.                  for(i=0x35, j=0; i<=0x38; i++, j++){
  2349.                       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
  2350.                  }
  2351.                  for(i=0x48; i<=0x4A; i++, j++) {
  2352.                        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
  2353.                  }
  2354.               } else {
  2355.                  for(i=0x35, j=0; i<=0x38; i++, j++) {
  2356.                        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter[index][j]);
  2357.                  }
  2358.               }
  2359.          }
  2360.          if(temp == EnablePALN) {
  2361.               if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  2362.                  for(i=0x35, j=0; i<=0x38; i++, j++) {
  2363.                       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
  2364.                  }
  2365.                  for(i=0x48, j=0; i<=0x4A; i++, j++) {
  2366.                        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
  2367.                  }
  2368.              } else {
  2369.                  for(i=0x35, j=0; i<=0x38; i++, j++)
  2370.                        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter[index][j]);
  2371.              }
  2372.          }
  2373.       }
  2374.   }
  2375. }
  2376. /* TW: Checked against 650/301LVx 1.10.6s BIOS (including data) */
  2377. void
  2378. SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2379.              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2380. {
  2381.   USHORT index,temp,temp1,i,j,resinfo;
  2382.   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
  2383.   temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);        /* if PALM/N not set */
  2384.   temp1 &=  (EnablePALMN | EnablePALN);
  2385.   if(temp1) return;
  2386.   if (ModeNo<=0x13) {
  2387.     resinfo =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
  2388.   } else {
  2389.     resinfo =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  2390.   }
  2391.   temp = GetTVPtrIndex(SiS_Pr);
  2392.   /* 0: NTSC Graphics, 1: NTSC Text,    2:PAL Graphics,
  2393.    * 3: PAL Text,      4: HiTV Graphics 5:HiTV Text
  2394.    */
  2395.   index = temp % 2;
  2396.   temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
  2397.   for(j=0, i=0x31; i<=0x34; i++, j++) {
  2398.      if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
  2399.   SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
  2400.      else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_SetFlag & TVSimuMode))
  2401.           SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
  2402.      else
  2403.           SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
  2404.   }
  2405.   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
  2406.      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
  2407.         if(resinfo == 6) {
  2408.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
  2409.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
  2410.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
  2411.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
  2412. } else if (resinfo == 7) {
  2413.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
  2414.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
  2415.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
  2416.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
  2417. } else if (resinfo == 8) {
  2418.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
  2419.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
  2420.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
  2421.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7b);
  2422. }
  2423.      }
  2424.   }
  2425. }
  2426. void
  2427. SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2428.                   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2429. {
  2430.    SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
  2431.    /* TW: The TV funtions are not for LVDS */
  2432.    if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
  2433.        SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2434.        SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2435.        SetYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2436.        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
  2437.           SetEdgeEnhance(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2438.        }
  2439.    }
  2440. }
  2441. /* TW: New from 650/301LVx 1.10.6s - clashes with OEMLCD() */
  2442. void
  2443. SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
  2444.                 USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
  2445. {
  2446.   USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
  2447.   USHORT resinfo;
  2448.   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
  2449.   if(ModeNo<=0x13) {
  2450. resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
  2451.   } else {
  2452.      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  2453.   }
  2454.   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  2455.      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
  2456.         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
  2457. SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
  2458. SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
  2459.      }
  2460.      tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
  2461.      tempch &= 0xf0;
  2462.      tempch >>= 4;
  2463.      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  2464. if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
  2465.    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
  2466. }
  2467.      } else {
  2468.         tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
  2469. tempcl &= 0x0f;
  2470. tempbh &= 0x70;
  2471. tempbh >>= 4;
  2472. tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
  2473. tempbx = (tempbh << 8) | tempbl;
  2474. if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
  2475.    if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & LCDNonExpanding))) {
  2476.       if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
  2477.        tempbx = 770;
  2478.       } else {
  2479.         if(tempbx > 770) tempbx = 770;
  2480. if(SiS_Pr->SiS_VGAVDE < 600) {                   /* Shouldn't that be <=? */
  2481.    tempax = 768 - SiS_Pr->SiS_VGAVDE;
  2482.    tempax >>= 3;
  2483.    if(SiS_Pr->SiS_VGAVDE < 480)  tempax >>= 1;   /* Shouldn't that be <=? */
  2484.    tempbx -= tempax;
  2485. }
  2486.       }
  2487.    } else return;
  2488. }
  2489. #if 0
  2490. if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
  2491. }
  2492. #endif
  2493. temp = tempbx & 0xff;
  2494. SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
  2495. temp = (tempbx & 0xff00) >> 8;
  2496. temp <<= 4;
  2497. temp |= tempcl;
  2498. SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
  2499.      }
  2500.   }
  2501. }
  2502. /* TW: New and checked from 650/301LV BIOS */
  2503. /* This might clash with newer "FinalizeLCD()" function */
  2504. void
  2505. SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2506.                   UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2507. {
  2508.    USHORT tempbx,tempah,tempbl,tempbh,tempcl;
  2509.    if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
  2510.    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  2511.       SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
  2512.       tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
  2513.       tempbh &= 0x38;
  2514.       tempbh >>= 3;
  2515.       tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
  2516.       tempbx = (tempbh << 8) | tempbl;
  2517.       if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
  2518.       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
  2519.       tempah = (tempbx & 0xff00) >> 8;
  2520.       tempah &= 0x07;
  2521.       tempah <<= 3;
  2522.       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
  2523.       tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
  2524.       tempah &= 0x0f;
  2525.       if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah -= 2;
  2526.       tempah &= 0x0f;
  2527.       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
  2528.       tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
  2529.       if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah++;
  2530.       tempah -= 8;
  2531.       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
  2532.    } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  2533.       tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
  2534.       tempbh &= 0x70;
  2535.       tempbh >>= 4;
  2536.       tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
  2537.       tempbx = (tempbh << 8) | tempbl;
  2538.       if(SiS_Pr->SiS_LCDTypeInfo == 1)  {
  2539.            tempbx -= 0x1e;
  2540.    tempcl &= 0x0f;
  2541.    tempcl -= 4;
  2542.    tempcl &= 0x0f;
  2543.       }
  2544.       tempbl = tempbx & 0x00ff;
  2545.       tempbh = (tempbx >> 8) & 0x00ff;
  2546.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
  2547.       tempbh <<= 4;
  2548.       tempbh |= tempcl;
  2549.       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
  2550.    }
  2551. }
  2552. #endif
  2553. /*  =================  SiS 300 O.E.M. ================== */
  2554. #ifdef SIS300
  2555. #if 0   /* Not used */
  2556. USHORT
  2557. GetRevisionID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
  2558. {
  2559.    ULONG temp1;
  2560. #ifndef LINUX_XF86
  2561.    ULONG base;
  2562. #endif
  2563.    USHORT temp2 = 0;
  2564.    if((HwDeviceExtension->jChipType==SIS_540)||
  2565.       (HwDeviceExtension->jChipType==SIS_630)||
  2566.       (HwDeviceExtension->jChipType==SIS_730)) {
  2567. #ifndef LINUX_XF86
  2568.       base = 0x80000008;
  2569.       OutPortLong(base,0xcf8);
  2570.       temp1 = InPortLong(0xcfc);
  2571. #else
  2572. temp1=pciReadLong(0x00000000, 0x08);
  2573. #endif
  2574.       temp1 &= 0x000000FF;
  2575.       temp2 = (USHORT)(temp1);
  2576.      return temp2;
  2577.    }
  2578.    return 0;
  2579. }
  2580. #endif
  2581. /* TW: Checked against 630/301B BIOS (incl data) */
  2582. USHORT
  2583. GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, int Flag)
  2584. {
  2585.   USHORT tempbx=0;
  2586.   UCHAR customtable[] = {
  2587.    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  2588. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
  2589.   };
  2590.   if(Flag) {
  2591.       if(customtable[SiS_Pr->SiS_LCDTypeInfo] == 0xFF) return 0xFFFF;
  2592.   }
  2593.   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
  2594.         tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
  2595. if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
  2596. if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx++;
  2597.   } else {
  2598.    tempbx = SiS_Pr->SiS_LCDTypeInfo;
  2599. if(SiS_Pr->SiS_LCDInfo & LCDNonExpanding) tempbx += 16;
  2600.   }
  2601.   return tempbx;
  2602. }
  2603. /* TW: Checked against 630/301B and 630/LVDS BIOS (incl data) */
  2604. void
  2605. SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2606.                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2607. {
  2608.   USHORT index,temp;
  2609.   /* TW: The Panel Compensation Delay should be set according to tables
  2610.    *     here. Unfortunately, the different BIOS versions don't case about
  2611.    *     a uniform way using eg. ROM byte 0x220, but use different
  2612.    *     hard coded delays (0x04, 0x20, 0x18) in SetGroup1(). So we can't
  2613.    *     rely on the other OEM bits in 0x237, 0x238 here either.
  2614.    *     ROMAddr > 0x233 is even used for code (!) in newer BIOSes!
  2615.    */
  2616. #if 0
  2617.   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
  2618.      if(!(ROMAddr[0x237] & 0x01)) return;
  2619.      if(!(ROMAddr[0x237] & 0x02)) return;
  2620.   }
  2621. #endif
  2622.   /* TW: We just check if a non-standard delay has been set; if not,
  2623.    * we use our tables. Otherwise don't do anything here.
  2624.    */
  2625.   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
  2626.      if(ROMAddr[0x220] & 0x80) return;
  2627.   }
  2628.   /* TW: We don't need to set this if the user select a custom pdc */
  2629.   if(HwDeviceExtension->pdc) return;
  2630.   temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, 0);
  2631.   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
  2632.   if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
  2633.      temp = SiS300_OEMLCDDelay2[temp][index];
  2634.   } else {
  2635.         temp = SiS300_OEMLCDDelay3[temp][index];
  2636.   }
  2637.   temp &= 0x3c;
  2638.   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
  2639. }
  2640. /* TW: Checked against 630/301B 2.04.50 and 630/LVDS BIOS */
  2641. USHORT
  2642. GetOEMTVPtr(SiS_Private *SiS_Pr)
  2643. {
  2644.   USHORT index;
  2645.   index = 0;
  2646.   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
  2647.   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
  2648.      if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
  2649.      else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) index += 3;
  2650.      else if(SiS_Pr->SiS_VBInfo & SetPALTV)   index += 1;
  2651.   } else {
  2652.      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) index += 2;
  2653.      if(SiS_Pr->SiS_VBInfo & SetPALTV)        index += 1;
  2654.   }
  2655.   return index;
  2656. }
  2657. /* TW: Checked against 630/301B 2.04.50 and 630/LVDS BIOS (incl data) */
  2658. void
  2659. SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2660.               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2661. {
  2662.   USHORT index,temp;
  2663. #if 0  /* TW: Not used in newer BIOSes (2.04.5a) */
  2664.   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
  2665.      if(!(ROMAddr[0x238] & 0x01)) return;
  2666.      if(!(ROMAddr[0x238] & 0x02)) return;
  2667.   }
  2668. #endif
  2669.   temp = GetOEMTVPtr(SiS_Pr);
  2670.   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
  2671.   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
  2672.      temp = SiS300_OEMTVDelay301[temp][index];
  2673.   } else {
  2674.      temp = SiS300_OEMTVDelayLVDS[temp][index];
  2675.   }
  2676.   temp &= 0x3c;
  2677.   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
  2678. }
  2679. /* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
  2680. void
  2681. SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
  2682.                   USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
  2683.   USHORT ModeIdIndex)
  2684. {
  2685.   USHORT index,temp;
  2686.   temp = GetOEMTVPtr(SiS_Pr);
  2687.   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
  2688.   temp = SiS300_OEMTVFlicker[temp][index];
  2689.   temp &= 0x70;
  2690.   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);  /* index 0A D[6:4] */
  2691. }
  2692. /* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
  2693. void
  2694. SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2695.                 UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2696. {
  2697.   USHORT index,i,j,temp;
  2698.   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) return;
  2699.   temp = GetOEMTVPtr(SiS_Pr);
  2700.   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
  2701.   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  2702.        for(i=0x31, j=0; i<=0x34; i++, j++) {
  2703.           SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
  2704.        }
  2705.   } else {
  2706.        for(i=0x31, j=0; i<=0x34; i++, j++) {
  2707.           SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
  2708.        }
  2709.   }
  2710. }
  2711. /* TW: Checked against 630/301B 2.04.50 BIOS (incl data) */
  2712. void
  2713. SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
  2714.               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
  2715. {
  2716.   USHORT index,temp,temp1,i,j;
  2717.   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return;
  2718.   temp = GetOEMTVPtr(SiS_Pr);
  2719.   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
  2720.   if(HwDeviceExtension->jChipType > SIS_300) {
  2721.      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
  2722.        temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
  2723.        if(temp1 & (EnablePALMN | EnablePALN)) {
  2724.           temp = 8;
  2725.   if(temp1 & EnablePALN) temp = 9;
  2726.        }
  2727.      }
  2728.   }
  2729.   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
  2730.       for(i=0x35, j=0; i<=0x38; i++, j++) {
  2731.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
  2732.       }
  2733.       for(i=0x48; i<=0x4A; i++, j++) {
  2734.       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
  2735.       }
  2736.   } else {
  2737.       for(i=0x35, j=0; i<=0x38; i++, j++) {
  2738.         SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
  2739.       }
  2740.   }
  2741. }
  2742. void
  2743. SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
  2744.   USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
  2745. {
  2746.   USHORT ModeIdIndex;
  2747.   ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
  2748.   if(!(ModeIdIndex)) return;
  2749.   if (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  2750.        SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2751.   }
  2752.   if (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  2753.        SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2754.        if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
  2755.         SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2756.      SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2757.         SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
  2758.        }
  2759.   }
  2760. }
  2761. #endif