linux/drivers/staging/xgifb/vb_setmode.c
<<
>>
Prefs
   1#include <linux/delay.h>
   2#include "XGIfb.h"
   3
   4#include "vb_def.h"
   5#include "vb_init.h"
   6#include "vb_util.h"
   7#include "vb_table.h"
   8#include "vb_setmode.h"
   9
  10#define  IndexMask 0xff
  11#define TVCLKBASE_315_25 (TVCLKBASE_315 + 25)
  12
  13static const unsigned short XGINew_VGA_DAC[] = {
  14        0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
  15        0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
  16        0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
  17        0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
  18        0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
  19        0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
  20        0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
  21        0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
  22        0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
  23        0x0B, 0x0C, 0x0D, 0x0F, 0x10};
  24
  25void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
  26{
  27        pVBInfo->MCLKData = XGI340New_MCLKData;
  28
  29        pVBInfo->LCDResInfo = 0;
  30        pVBInfo->LCDTypeInfo = 0;
  31        pVBInfo->LCDInfo = 0;
  32        pVBInfo->VBInfo = 0;
  33        pVBInfo->TVInfo = 0;
  34
  35        pVBInfo->SR18 = XGI340_SR18;
  36        pVBInfo->CR40 = XGI340_cr41;
  37
  38        /* 310 customization related */
  39        if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
  40                pVBInfo->LCDCapList = XGI_LCDDLCapList;
  41        else
  42                pVBInfo->LCDCapList = XGI_LCDCapList;
  43
  44        if (ChipType >= XG20)
  45                pVBInfo->XGINew_CR97 = 0x10;
  46
  47        if (ChipType == XG27) {
  48                unsigned char temp;
  49                pVBInfo->MCLKData = XGI27New_MCLKData;
  50                pVBInfo->CR40 = XGI27_cr41;
  51                pVBInfo->XGINew_CR97 = 0xc1;
  52                pVBInfo->SR18 = XG27_SR18;
  53
  54                /*Z11m DDR*/
  55                temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
  56                /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
  57                if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
  58                        pVBInfo->XGINew_CR97 = 0x80;
  59        }
  60
  61}
  62
  63static void XGI_SetSeqRegs(unsigned short ModeNo,
  64                           unsigned short ModeIdIndex,
  65                           struct vb_device_info *pVBInfo)
  66{
  67        unsigned char SRdata, i;
  68
  69        xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
  70
  71        for (i = 0; i < 4; i++) {
  72                /* Get SR1,2,3,4 from file */
  73                /* SR1 is with screen off 0x20 */
  74                SRdata = XGI330_StandTable.SR[i];
  75                xgifb_reg_set(pVBInfo->P3c4, i+1, SRdata); /* Set SR 1 2 3 4 */
  76        }
  77}
  78
  79static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
  80                            struct vb_device_info *pVBInfo)
  81{
  82        unsigned char CRTCdata;
  83        unsigned short i;
  84
  85        CRTCdata = xgifb_reg_get(pVBInfo->P3d4, 0x11);
  86        CRTCdata &= 0x7f;
  87        xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
  88
  89        for (i = 0; i <= 0x18; i++) {
  90                /* Get CRTC from file */
  91                CRTCdata = XGI330_StandTable.CRTC[i];
  92                xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
  93        }
  94}
  95
  96static void XGI_SetATTRegs(unsigned short ModeNo,
  97                           unsigned short ModeIdIndex,
  98                           struct vb_device_info *pVBInfo)
  99{
 100        unsigned char ARdata;
 101        unsigned short i, modeflag;
 102
 103        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 104
 105        for (i = 0; i <= 0x13; i++) {
 106                ARdata = XGI330_StandTable.ATTR[i];
 107
 108                if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */
 109                        if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 110                                ARdata = 0;
 111                        } else if ((pVBInfo->VBInfo &
 112                                     (SetCRT2ToTV | SetCRT2ToLCD)) &&
 113                                    (pVBInfo->VBInfo & SetInSlaveMode)) {
 114                                        ARdata = 0;
 115                        }
 116                }
 117
 118                inb(pVBInfo->P3da); /* reset 3da */
 119                outb(i, pVBInfo->P3c0); /* set index */
 120                outb(ARdata, pVBInfo->P3c0); /* set data */
 121        }
 122
 123        inb(pVBInfo->P3da); /* reset 3da */
 124        outb(0x14, pVBInfo->P3c0); /* set index */
 125        outb(0x00, pVBInfo->P3c0); /* set data */
 126        inb(pVBInfo->P3da); /* Enable Attribute */
 127        outb(0x20, pVBInfo->P3c0);
 128}
 129
 130static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo)
 131{
 132        unsigned char GRdata;
 133        unsigned short i;
 134
 135        for (i = 0; i <= 0x08; i++) {
 136                /* Get GR from file */
 137                GRdata = XGI330_StandTable.GRC[i];
 138                xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
 139        }
 140
 141        if (pVBInfo->ModeType > ModeVGA) {
 142                GRdata = xgifb_reg_get(pVBInfo->P3ce, 0x05);
 143                GRdata &= 0xBF; /* 256 color disable */
 144                xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata);
 145        }
 146}
 147
 148static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo)
 149{
 150        unsigned short i;
 151
 152        for (i = 0x0A; i <= 0x0E; i++)
 153                xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */
 154}
 155
 156static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo)
 157{
 158
 159        xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20);
 160        xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[0].SR2B);
 161        xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[0].SR2C);
 162
 163        xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10);
 164        xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[1].SR2B);
 165        xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[1].SR2C);
 166
 167        xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30);
 168        return 0;
 169}
 170
 171static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
 172                unsigned short ModeIdIndex,
 173                unsigned short RefreshRateTableIndex, unsigned short *i,
 174                struct vb_device_info *pVBInfo)
 175{
 176        unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
 177
 178        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 179        resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 180        tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
 181        tempax = 0;
 182
 183        if (pVBInfo->IF_DEF_LVDS == 0) {
 184                if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
 185                        tempax |= SupportRAMDAC2;
 186
 187                        if (pVBInfo->VBType & VB_XGI301C)
 188                                tempax |= SupportCRT2in301C;
 189                }
 190
 191                /* 301b */
 192                if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 193                        tempax |= SupportLCD;
 194
 195                        if (pVBInfo->LCDResInfo != Panel_1280x1024 &&
 196                            pVBInfo->LCDResInfo != Panel_1280x960 &&
 197                            (pVBInfo->LCDInfo & LCDNonExpanding) &&
 198                            resinfo >= 9)
 199                                return 0;
 200                }
 201
 202                if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */
 203                        tempax |= SupportHiVision;
 204                        if ((pVBInfo->VBInfo & SetInSlaveMode) &&
 205                            ((resinfo == 4) ||
 206                             (resinfo == 3 &&
 207                              (pVBInfo->SetFlag & TVSimuMode)) ||
 208                             (resinfo > 7)))
 209                                        return 0;
 210                } else if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO |
 211                                               SetCRT2ToSVIDEO |
 212                                               SetCRT2ToSCART |
 213                                               SetCRT2ToYPbPr525750 |
 214                                               SetCRT2ToHiVision)) {
 215                        tempax |= SupportTV;
 216
 217                        if (pVBInfo->VBType & (VB_SIS301B |
 218                                               VB_SIS302B |
 219                                               VB_SIS301LV |
 220                                               VB_SIS302LV |
 221                                               VB_XGI301C))
 222                                tempax |= SupportTV1024;
 223
 224                        if (!(pVBInfo->VBInfo & TVSetPAL) &&
 225                            (modeflag & NoSupportSimuTV) &&
 226                            (pVBInfo->VBInfo & SetInSlaveMode) &&
 227                            (!(pVBInfo->VBInfo & SetNotSimuMode)))
 228                                return 0;
 229                }
 230        } else if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* for LVDS */
 231                tempax |= SupportLCD;
 232
 233                if (resinfo > 0x08)
 234                        return 0; /* 1024x768 */
 235
 236                if (pVBInfo->LCDResInfo < Panel_1024x768) {
 237                        if (resinfo > 0x07)
 238                                return 0; /* 800x600 */
 239
 240                        if (resinfo == 0x04)
 241                                return 0; /* 512x384 */
 242                }
 243        }
 244
 245        for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
 246               tempbx; (*i)--) {
 247                infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].
 248                                Ext_InfoFlag;
 249                if (infoflag & tempax)
 250                        return 1;
 251
 252                if ((*i) == 0)
 253                        break;
 254        }
 255
 256        for ((*i) = 0;; (*i)++) {
 257                infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)].
 258                                Ext_InfoFlag;
 259                if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID
 260                                != tempbx) {
 261                        return 0;
 262                }
 263
 264                if (infoflag & tempax)
 265                        return 1;
 266        }
 267        return 1;
 268}
 269
 270static void XGI_SetSync(unsigned short RefreshRateTableIndex,
 271                struct vb_device_info *pVBInfo)
 272{
 273        unsigned short sync, temp;
 274
 275        /* di+0x00 */
 276        sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
 277        sync &= 0xC0;
 278        temp = 0x2F;
 279        temp |= sync;
 280        outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */
 281}
 282
 283static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo,
 284                struct xgi_hw_device_info *HwDeviceExtension)
 285{
 286        unsigned char data, data1, pushax;
 287        unsigned short i, j;
 288
 289        /* unlock cr0-7 */
 290        data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
 291        data &= 0x7F;
 292        xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
 293
 294        data = pVBInfo->TimingH.data[0];
 295        xgifb_reg_set(pVBInfo->P3d4, 0, data);
 296
 297        for (i = 0x01; i <= 0x04; i++) {
 298                data = pVBInfo->TimingH.data[i];
 299                xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data);
 300        }
 301
 302        for (i = 0x05; i <= 0x06; i++) {
 303                data = pVBInfo->TimingH.data[i];
 304                xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data);
 305        }
 306
 307        j = xgifb_reg_get(pVBInfo->P3c4, 0x0e);
 308        j &= 0x1F;
 309        data = pVBInfo->TimingH.data[7];
 310        data &= 0xE0;
 311        data |= j;
 312        xgifb_reg_set(pVBInfo->P3c4, 0x0e, data);
 313
 314        if (HwDeviceExtension->jChipType >= XG20) {
 315                data = xgifb_reg_get(pVBInfo->P3d4, 0x04);
 316                data = data - 1;
 317                xgifb_reg_set(pVBInfo->P3d4, 0x04, data);
 318                data = xgifb_reg_get(pVBInfo->P3d4, 0x05);
 319                data1 = data;
 320                data1 &= 0xE0;
 321                data &= 0x1F;
 322                if (data == 0) {
 323                        pushax = data;
 324                        data = xgifb_reg_get(pVBInfo->P3c4, 0x0c);
 325                        data &= 0xFB;
 326                        xgifb_reg_set(pVBInfo->P3c4, 0x0c, data);
 327                        data = pushax;
 328                }
 329                data = data - 1;
 330                data |= data1;
 331                xgifb_reg_set(pVBInfo->P3d4, 0x05, data);
 332                data = xgifb_reg_get(pVBInfo->P3c4, 0x0e);
 333                data = data >> 5;
 334                data = data + 3;
 335                if (data > 7)
 336                        data = data - 7;
 337                data = data << 5;
 338                xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data);
 339        }
 340}
 341
 342static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
 343                                unsigned short ModeNo,
 344                                struct vb_device_info *pVBInfo)
 345{
 346        unsigned char data;
 347        unsigned short i, j;
 348
 349        for (i = 0x00; i <= 0x01; i++) {
 350                data = pVBInfo->TimingV.data[i];
 351                xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data);
 352        }
 353
 354        for (i = 0x02; i <= 0x03; i++) {
 355                data = pVBInfo->TimingV.data[i];
 356                xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data);
 357        }
 358
 359        for (i = 0x04; i <= 0x05; i++) {
 360                data = pVBInfo->TimingV.data[i];
 361                xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data);
 362        }
 363
 364        j = xgifb_reg_get(pVBInfo->P3c4, 0x0a);
 365        j &= 0xC0;
 366        data = pVBInfo->TimingV.data[6];
 367        data &= 0x3F;
 368        data |= j;
 369        xgifb_reg_set(pVBInfo->P3c4, 0x0a, data);
 370
 371        data = pVBInfo->TimingV.data[6];
 372        data &= 0x80;
 373        data = data >> 2;
 374
 375        i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 376        i &= DoubleScanMode;
 377        if (i)
 378                data |= 0x80;
 379
 380        j = xgifb_reg_get(pVBInfo->P3d4, 0x09);
 381        j &= 0x5F;
 382        data |= j;
 383        xgifb_reg_set(pVBInfo->P3d4, 0x09, data);
 384}
 385
 386static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
 387                unsigned short RefreshRateTableIndex,
 388                struct vb_device_info *pVBInfo,
 389                struct xgi_hw_device_info *HwDeviceExtension)
 390{
 391        unsigned char index, data;
 392        unsigned short i;
 393
 394        /* Get index */
 395        index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 396        index = index & IndexMask;
 397
 398        data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
 399        data &= 0x7F;
 400        xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
 401
 402        for (i = 0; i < 8; i++)
 403                pVBInfo->TimingH.data[i]
 404                                = XGI_CRT1Table[index].CR[i];
 405
 406        for (i = 0; i < 7; i++)
 407                pVBInfo->TimingV.data[i]
 408                                = XGI_CRT1Table[index].CR[i + 8];
 409
 410        XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
 411
 412        XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
 413
 414        if (pVBInfo->ModeType > 0x03)
 415                xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F);
 416}
 417
 418/* --------------------------------------------------------------------- */
 419/* Function : XGI_SetXG21CRTC */
 420/* Input : Stand or enhance CRTC table */
 421/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
 422/* Description : Set LCD timing */
 423/* --------------------------------------------------------------------- */
 424static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
 425                unsigned short RefreshRateTableIndex,
 426                struct vb_device_info *pVBInfo)
 427{
 428        unsigned char index, Tempax, Tempbx, Tempcx, Tempdx;
 429        unsigned short Temp1, Temp2, Temp3;
 430
 431        index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 432        /* Tempax: CR4 HRS */
 433        Tempax = XGI_CRT1Table[index].CR[3];
 434        Tempcx = Tempax; /* Tempcx: HRS */
 435        /* SR2E[7:0]->HRS */
 436        xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
 437
 438        Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */
 439        Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
 440        Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */
 441        Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */
 442        Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */
 443
 444        Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
 445        Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
 446
 447        Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */
 448        Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */
 449        Tempbx <<= 3; /* Tempbx[5]: HRE[5] */
 450        Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */
 451
 452        Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */
 453        Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */
 454
 455        Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */
 456        if (Tempax < Tempcx) /* HRE < HRS */
 457                Temp2 |= 0x40; /* Temp2 + 0x40 */
 458
 459        Temp2 &= 0xFF;
 460        Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */
 461        Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
 462        Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
 463        Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
 464        /* SR2F D[7:2]->HRE, D[1:0]->HRS */
 465        xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
 466        xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
 467
 468        /* CR10 VRS */
 469        Tempax = XGI_CRT1Table[index].CR[10];
 470        Tempbx = Tempax; /* Tempbx: VRS */
 471        Tempax &= 0x01; /* Tempax[0]: VRS[0] */
 472        xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
 473        /* CR7[2][7] VRE */
 474        Tempax = XGI_CRT1Table[index].CR[9];
 475        Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
 476        Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
 477        Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
 478        Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */
 479        xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */
 480
 481        Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */
 482        Temp1 <<= 1; /* Temp1[8]: VRS[8] */
 483        Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
 484        Tempax &= 0x80;
 485        Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
 486        Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
 487        /* Tempax: SRA */
 488        Tempax = XGI_CRT1Table[index].CR[14];
 489        Tempax &= 0x08; /* Tempax[3]: VRS[3] */
 490        Temp2 = Tempax;
 491        Temp2 <<= 7; /* Temp2[10]: VRS[10] */
 492        Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
 493
 494        /* Tempax: CR11 VRE */
 495        Tempax = XGI_CRT1Table[index].CR[11];
 496        Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
 497        /* Tempbx: SRA */
 498        Tempbx = XGI_CRT1Table[index].CR[14];
 499        Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
 500        Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
 501        Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
 502        Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */
 503        Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */
 504
 505        Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */
 506        if (Tempax < Temp3) /* VRE < VRS */
 507                Temp2 |= 0x20; /* VRE + 0x20 */
 508
 509        Temp2 &= 0xFF;
 510        Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */
 511        Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */
 512        Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */
 513        Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */
 514        Tempbx = (unsigned char) Temp1;
 515        Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
 516        Tempax &= 0x7F;
 517        /* SR3F D[7:2]->VRE D[1:0]->VRS */
 518        xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
 519}
 520
 521static void XGI_SetXG27CRTC(unsigned short ModeNo,
 522                            unsigned short ModeIdIndex,
 523                            unsigned short RefreshRateTableIndex,
 524                            struct vb_device_info *pVBInfo)
 525{
 526        unsigned short index, Tempax, Tempbx, Tempcx;
 527
 528        index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 529        /* Tempax: CR4 HRS */
 530        Tempax = XGI_CRT1Table[index].CR[3];
 531        Tempbx = Tempax; /* Tempbx: HRS[7:0] */
 532        /* SR2E[7:0]->HRS */
 533        xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
 534
 535        /* SR0B */
 536        Tempax = XGI_CRT1Table[index].CR[5];
 537        Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
 538        Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
 539
 540        Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */
 541        Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */
 542        Tempcx = Tempax; /* Tempcx: HRE[4:0] */
 543
 544        Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */
 545        Tempax &= 0x04; /* Tempax[2]: HRE[5] */
 546        Tempax <<= 3; /* Tempax[5]: HRE[5] */
 547        Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */
 548
 549        Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
 550        Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
 551
 552        /* Tempax: CR4 HRS */
 553        Tempax = XGI_CRT1Table[index].CR[3];
 554        Tempax &= 0x3F; /* Tempax: HRS[5:0] */
 555        if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
 556                Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
 557
 558        Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */
 559        Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
 560        Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
 561        Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
 562        /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
 563        xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
 564        xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
 565
 566        /* CR10 VRS */
 567        Tempax = XGI_CRT1Table[index].CR[10];
 568        /* SR34[7:0]->VRS[7:0] */
 569        xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
 570
 571        Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
 572        /* CR7[7][2] VRS[9][8] */
 573        Tempax = XGI_CRT1Table[index].CR[9];
 574        Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
 575        Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
 576        Tempax >>= 2; /* Tempax[0]: VRS[8] */
 577        /* SR35[0]: VRS[8] */
 578        xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
 579        Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
 580        Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
 581        /* Tempax: SR0A */
 582        Tempax = XGI_CRT1Table[index].CR[14];
 583        Tempax &= 0x08; /* SR0A[3] VRS[10] */
 584        Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
 585
 586        /* Tempax: CR11 VRE */
 587        Tempax = XGI_CRT1Table[index].CR[11];
 588        Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
 589        /* Tempbx: SR0A */
 590        Tempbx = XGI_CRT1Table[index].CR[14];
 591        Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
 592        Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
 593        Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
 594        Tempbx = Tempcx; /* Tempbx: VRS[10:0] */
 595        Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */
 596        Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */
 597
 598        if (Tempbx <= Tempcx) /* VRE <= VRS */
 599                Tempbx |= 0x20; /* VRE + 0x20 */
 600
 601        /* Tempax: Tempax[7:0]; VRE[5:0]00 */
 602        Tempax = (Tempbx << 2) & 0xFF;
 603        /* SR3F[7:2]:VRE[5:0] */
 604        xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
 605        Tempax = Tempcx >> 8;
 606        /* SR35[2:0]:VRS[10:8] */
 607        xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax);
 608}
 609
 610static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo)
 611{
 612        unsigned char temp;
 613
 614        /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
 615        temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
 616        temp = (temp & 3) << 6;
 617        /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
 618        xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
 619        /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
 620        xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
 621
 622}
 623
 624static void xgifb_set_lcd(int chip_id,
 625                          struct vb_device_info *pVBInfo,
 626                          unsigned short RefreshRateTableIndex,
 627                          unsigned short ModeNo)
 628{
 629        unsigned short temp;
 630
 631        xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00);
 632        xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00);
 633        xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00);
 634        xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00);
 635
 636        if (chip_id == XG27) {
 637                temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
 638                if ((temp & 0x03) == 0) { /* dual 12 */
 639                        xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13);
 640                        xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13);
 641                }
 642        }
 643
 644        if (chip_id == XG27) {
 645                XGI_SetXG27FPBits(pVBInfo);
 646        } else {
 647                temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
 648                if (temp & 0x01) {
 649                        /* 18 bits FP */
 650                        xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40);
 651                        xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40);
 652                }
 653        }
 654
 655        xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */
 656
 657        xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */
 658        xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */
 659
 660        temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 661        if (temp & 0x4000)
 662                /* Hsync polarity */
 663                xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
 664        if (temp & 0x8000)
 665                /* Vsync polarity */
 666                xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
 667}
 668
 669/* --------------------------------------------------------------------- */
 670/* Function : XGI_UpdateXG21CRTC */
 671/* Input : */
 672/* Output : CRT1 CRTC */
 673/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
 674/* --------------------------------------------------------------------- */
 675static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
 676                               struct vb_device_info *pVBInfo,
 677                               unsigned short RefreshRateTableIndex)
 678{
 679        int index = -1;
 680
 681        xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */
 682        if (ModeNo == 0x2E &&
 683            (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
 684                                                      RES640x480x60))
 685                index = 12;
 686        else if (ModeNo == 0x2E && (XGI330_RefIndex[RefreshRateTableIndex].
 687                                Ext_CRT1CRTC == RES640x480x72))
 688                index = 13;
 689        else if (ModeNo == 0x2F)
 690                index = 14;
 691        else if (ModeNo == 0x50)
 692                index = 15;
 693        else if (ModeNo == 0x59)
 694                index = 16;
 695
 696        if (index != -1) {
 697                xgifb_reg_set(pVBInfo->P3d4, 0x02,
 698                                XGI_UpdateCRT1Table[index].CR02);
 699                xgifb_reg_set(pVBInfo->P3d4, 0x03,
 700                                XGI_UpdateCRT1Table[index].CR03);
 701                xgifb_reg_set(pVBInfo->P3d4, 0x15,
 702                                XGI_UpdateCRT1Table[index].CR15);
 703                xgifb_reg_set(pVBInfo->P3d4, 0x16,
 704                                XGI_UpdateCRT1Table[index].CR16);
 705        }
 706}
 707
 708static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension,
 709                unsigned short ModeNo, unsigned short ModeIdIndex,
 710                unsigned short RefreshRateTableIndex,
 711                struct vb_device_info *pVBInfo)
 712{
 713        unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag;
 714
 715        unsigned char data;
 716
 717        resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 718
 719        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 720        tempax = XGI330_ModeResInfo[resindex].HTotal;
 721        tempbx = XGI330_ModeResInfo[resindex].VTotal;
 722
 723        if (modeflag & HalfDCLK)
 724                tempax = tempax >> 1;
 725
 726        if (modeflag & HalfDCLK)
 727                tempax = tempax << 1;
 728
 729        temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 730
 731        if (temp & InterlaceMode)
 732                tempbx = tempbx >> 1;
 733
 734        if (modeflag & DoubleScanMode)
 735                tempbx = tempbx << 1;
 736
 737        tempcx = 8;
 738
 739        tempax /= tempcx;
 740        tempax -= 1;
 741        tempbx -= 1;
 742        tempcx = tempax;
 743        temp = xgifb_reg_get(pVBInfo->P3d4, 0x11);
 744        data = xgifb_reg_get(pVBInfo->P3d4, 0x11);
 745        data &= 0x7F;
 746        xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
 747        xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff));
 748        xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c,
 749                        (unsigned short) ((tempcx & 0x0ff00) >> 10));
 750        xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff));
 751        tempax = 0;
 752        tempbx = tempbx >> 8;
 753
 754        if (tempbx & 0x01)
 755                tempax |= 0x02;
 756
 757        if (tempbx & 0x02)
 758                tempax |= 0x40;
 759
 760        xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax);
 761        data = xgifb_reg_get(pVBInfo->P3d4, 0x07);
 762        data &= 0xFF;
 763        tempax = 0;
 764
 765        if (tempbx & 0x04)
 766                tempax |= 0x02;
 767
 768        xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax);
 769        xgifb_reg_set(pVBInfo->P3d4, 0x11, temp);
 770}
 771
 772static void XGI_SetCRT1Offset(unsigned short ModeNo,
 773                              unsigned short ModeIdIndex,
 774                              unsigned short RefreshRateTableIndex,
 775                              struct xgi_hw_device_info *HwDeviceExtension,
 776                              struct vb_device_info *pVBInfo)
 777{
 778        unsigned short temp, ah, al, temp2, i, DisplayUnit;
 779
 780        /* GetOffset */
 781        temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
 782        temp = temp >> 8;
 783        temp = XGI330_ScreenOffset[temp];
 784
 785        temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 786        temp2 &= InterlaceMode;
 787
 788        if (temp2)
 789                temp = temp << 1;
 790
 791        temp2 = pVBInfo->ModeType - ModeEGA;
 792
 793        switch (temp2) {
 794        case 0:
 795                temp2 = 1;
 796                break;
 797        case 1:
 798                temp2 = 2;
 799                break;
 800        case 2:
 801                temp2 = 4;
 802                break;
 803        case 3:
 804                temp2 = 4;
 805                break;
 806        case 4:
 807                temp2 = 6;
 808                break;
 809        case 5:
 810                temp2 = 8;
 811                break;
 812        default:
 813                break;
 814        }
 815
 816        if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
 817                temp = temp * temp2 + temp2 / 2;
 818        else
 819                temp *= temp2;
 820
 821        /* SetOffset */
 822        DisplayUnit = temp;
 823        temp2 = temp;
 824        temp = temp >> 8; /* ah */
 825        temp &= 0x0F;
 826        i = xgifb_reg_get(pVBInfo->P3c4, 0x0E);
 827        i &= 0xF0;
 828        i |= temp;
 829        xgifb_reg_set(pVBInfo->P3c4, 0x0E, i);
 830
 831        temp = (unsigned char) temp2;
 832        temp &= 0xFF; /* al */
 833        xgifb_reg_set(pVBInfo->P3d4, 0x13, temp);
 834
 835        /* SetDisplayUnit */
 836        temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 837        temp2 &= InterlaceMode;
 838        if (temp2)
 839                DisplayUnit >>= 1;
 840
 841        DisplayUnit = DisplayUnit << 5;
 842        ah = (DisplayUnit & 0xff00) >> 8;
 843        al = DisplayUnit & 0x00ff;
 844        if (al == 0)
 845                ah += 1;
 846        else
 847                ah += 2;
 848
 849        if (HwDeviceExtension->jChipType >= XG20)
 850                if ((ModeNo == 0x4A) | (ModeNo == 0x49))
 851                        ah -= 1;
 852
 853        xgifb_reg_set(pVBInfo->P3c4, 0x10, ah);
 854}
 855
 856static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
 857                unsigned short ModeIdIndex,
 858                unsigned short RefreshRateTableIndex,
 859                struct xgi_hw_device_info *HwDeviceExtension,
 860                struct vb_device_info *pVBInfo)
 861{
 862        unsigned short VCLKIndex, modeflag;
 863
 864        /* si+Ext_ResInfo */
 865        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 866
 867        if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/
 868                if (pVBInfo->LCDResInfo != Panel_1024x768)
 869                        /* LCDXlat2VCLK */
 870                        VCLKIndex = VCLK108_2_315 + 5;
 871                else
 872                        VCLKIndex = VCLK65_315 + 2; /* LCDXlat1VCLK */
 873        } else if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 874                if (pVBInfo->SetFlag & RPLLDIV2XO)
 875                        VCLKIndex = TVCLKBASE_315_25 + HiTVVCLKDIV2;
 876                else
 877                        VCLKIndex = TVCLKBASE_315_25 + HiTVVCLK;
 878
 879                if (pVBInfo->SetFlag & TVSimuMode) {
 880                        if (modeflag & Charx8Dot) {
 881                                VCLKIndex = TVCLKBASE_315_25 + HiTVSimuVCLK;
 882                        } else {
 883                                VCLKIndex = TVCLKBASE_315_25 + HiTVTextVCLK;
 884                        }
 885                }
 886
 887                /* 301lv */
 888                if (pVBInfo->VBType & VB_SIS301LV) {
 889                        if (pVBInfo->SetFlag & RPLLDIV2XO)
 890                                VCLKIndex = YPbPr525iVCLK_2;
 891                        else
 892                                VCLKIndex = YPbPr525iVCLK;
 893                }
 894        } else if (pVBInfo->VBInfo & SetCRT2ToTV) {
 895                if (pVBInfo->SetFlag & RPLLDIV2XO)
 896                        VCLKIndex = TVCLKBASE_315_25 + TVVCLKDIV2;
 897                else
 898                        VCLKIndex = TVCLKBASE_315_25 + TVVCLK;
 899        } else { /* for CRT2 */
 900                /* di+Ext_CRTVCLK */
 901                VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
 902                VCLKIndex &= IndexMask;
 903        }
 904
 905        return VCLKIndex;
 906}
 907
 908static void XGI_SetCRT1VCLK(unsigned short ModeNo,
 909                            unsigned short ModeIdIndex,
 910                            struct xgi_hw_device_info *HwDeviceExtension,
 911                            unsigned short RefreshRateTableIndex,
 912                            struct vb_device_info *pVBInfo)
 913{
 914        unsigned char index, data;
 915        unsigned short vclkindex;
 916
 917        if (pVBInfo->IF_DEF_LVDS == 1) {
 918                index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
 919                data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
 920                xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
 921                xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B);
 922                xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C);
 923                xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
 924        } else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
 925                        | VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo
 926                        & XGI_SetCRT2ToLCDA)) {
 927                vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex,
 928                                RefreshRateTableIndex, HwDeviceExtension,
 929                                pVBInfo);
 930                data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
 931                xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
 932                data = XGI_VBVCLKData[vclkindex].Part4_A;
 933                xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
 934                data = XGI_VBVCLKData[vclkindex].Part4_B;
 935                xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
 936                xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
 937        } else {
 938                index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
 939                data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF;
 940                xgifb_reg_set(pVBInfo->P3c4, 0x31, data);
 941                xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B);
 942                xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C);
 943                xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
 944        }
 945
 946        if (HwDeviceExtension->jChipType >= XG20) {
 947                if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag &
 948                    HalfDCLK) {
 949                        data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
 950                        xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
 951                        data = xgifb_reg_get(pVBInfo->P3c4, 0x2C);
 952                        index = data;
 953                        index &= 0xE0;
 954                        data &= 0x1F;
 955                        data = data << 1;
 956                        data += 1;
 957                        data |= index;
 958                        xgifb_reg_set(pVBInfo->P3c4, 0x2C, data);
 959                }
 960        }
 961}
 962
 963static void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo)
 964{
 965        unsigned char temp;
 966
 967        temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
 968        temp = (temp & 1) << 6;
 969        /* SR06[6] 18bit Dither */
 970        xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp);
 971        /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
 972        xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
 973
 974}
 975
 976static void XGI_SetCRT1FIFO(unsigned short ModeNo,
 977                struct xgi_hw_device_info *HwDeviceExtension,
 978                struct vb_device_info *pVBInfo)
 979{
 980        unsigned short data;
 981
 982        data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
 983        data &= 0xfe;
 984        xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
 985
 986        xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34);
 987        data = xgifb_reg_get(pVBInfo->P3c4, 0x09);
 988        data &= 0xC0;
 989        xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30);
 990        data = xgifb_reg_get(pVBInfo->P3c4, 0x3D);
 991        data |= 0x01;
 992        xgifb_reg_set(pVBInfo->P3c4, 0x3D, data);
 993
 994        if (HwDeviceExtension->jChipType == XG21)
 995                XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
 996}
 997
 998static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension,
 999                unsigned short ModeNo, unsigned short RefreshRateTableIndex,
1000                struct vb_device_info *pVBInfo)
1001{
1002        unsigned short data, data2 = 0;
1003        short VCLK;
1004
1005        unsigned char index;
1006
1007        index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1008        index &= IndexMask;
1009        VCLK = XGI_VCLKData[index].CLOCK;
1010
1011        data = xgifb_reg_get(pVBInfo->P3c4, 0x32);
1012        data &= 0xf3;
1013        if (VCLK >= 200)
1014                data |= 0x0c; /* VCLK > 200 */
1015
1016        if (HwDeviceExtension->jChipType >= XG20)
1017                data &= ~0x04; /* 2 pixel mode */
1018
1019        xgifb_reg_set(pVBInfo->P3c4, 0x32, data);
1020
1021        if (HwDeviceExtension->jChipType < XG20) {
1022                data = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
1023                data &= 0xE7;
1024                if (VCLK < 200)
1025                        data |= 0x10;
1026                xgifb_reg_set(pVBInfo->P3c4, 0x1F, data);
1027        }
1028
1029        data2 = 0x00;
1030
1031        xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2);
1032        if (HwDeviceExtension->jChipType >= XG27)
1033                xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03);
1034
1035}
1036
1037static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension,
1038                unsigned short ModeNo, unsigned short ModeIdIndex,
1039                unsigned short RefreshRateTableIndex,
1040                struct vb_device_info *pVBInfo)
1041{
1042        unsigned short data, data2, data3, infoflag = 0, modeflag, resindex,
1043                        xres;
1044
1045        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1046        infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
1047
1048        if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
1049                xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
1050
1051        data = infoflag;
1052        data2 = 0;
1053        data2 |= 0x02;
1054        data3 = pVBInfo->ModeType - ModeVGA;
1055        data3 = data3 << 2;
1056        data2 |= data3;
1057        data &= InterlaceMode;
1058
1059        if (data)
1060                data2 |= 0x20;
1061
1062        xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2);
1063        resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1064        xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
1065
1066        data = 0x0000;
1067        if (infoflag & InterlaceMode) {
1068                if (xres == 1024)
1069                        data = 0x0035;
1070                else if (xres == 1280)
1071                        data = 0x0048;
1072        }
1073
1074        xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data);
1075        xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, 0);
1076
1077        if (modeflag & HalfDCLK)
1078                xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08);
1079
1080        data2 = 0;
1081
1082        if (modeflag & LineCompareOff)
1083                data2 |= 0x08;
1084
1085        xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2);
1086        data = 0x60;
1087        data = data ^ 0x60;
1088        data = data ^ 0xA0;
1089        xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data);
1090
1091        XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
1092                        pVBInfo);
1093
1094        data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
1095
1096        if (HwDeviceExtension->jChipType == XG27) {
1097                if (data & 0x40)
1098                        data = 0x2c;
1099                else
1100                        data = 0x6c;
1101                xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1102                xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10);
1103        } else if (HwDeviceExtension->jChipType >= XG20) {
1104                if (data & 0x40)
1105                        data = 0x33;
1106                else
1107                        data = 0x73;
1108                xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1109                xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02);
1110        } else {
1111                if (data & 0x40)
1112                        data = 0x2c;
1113                else
1114                        data = 0x6c;
1115                xgifb_reg_set(pVBInfo->P3d4, 0x52, data);
1116        }
1117
1118}
1119
1120static void XGI_WriteDAC(unsigned short dl,
1121                         unsigned short ah,
1122                         unsigned short al,
1123                         unsigned short dh,
1124                         struct vb_device_info *pVBInfo)
1125{
1126        unsigned short temp, bh, bl;
1127
1128        bh = ah;
1129        bl = al;
1130
1131        if (dl != 0) {
1132                temp = bh;
1133                bh = dh;
1134                dh = temp;
1135                if (dl == 1) {
1136                        temp = bl;
1137                        bl = dh;
1138                        dh = temp;
1139                } else {
1140                        temp = bl;
1141                        bl = bh;
1142                        bh = temp;
1143                }
1144        }
1145        outb((unsigned short) dh, pVBInfo->P3c9);
1146        outb((unsigned short) bh, pVBInfo->P3c9);
1147        outb((unsigned short) bl, pVBInfo->P3c9);
1148}
1149
1150static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex,
1151                struct vb_device_info *pVBInfo)
1152{
1153        unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh;
1154        const unsigned short *table = XGINew_VGA_DAC;
1155
1156        outb(0xFF, pVBInfo->P3c6);
1157        outb(0x00, pVBInfo->P3c8);
1158
1159        for (i = 0; i < 16; i++) {
1160                data = table[i];
1161
1162                for (k = 0; k < 3; k++) {
1163                        data2 = 0;
1164
1165                        if (data & 0x01)
1166                                data2 = 0x2A;
1167
1168                        if (data & 0x02)
1169                                data2 += 0x15;
1170
1171                        outb(data2, pVBInfo->P3c9);
1172                        data = data >> 2;
1173                }
1174        }
1175
1176        for (i = 16; i < 32; i++) {
1177                data = table[i];
1178
1179                for (k = 0; k < 3; k++)
1180                        outb(data, pVBInfo->P3c9);
1181        }
1182
1183        si = 32;
1184
1185        for (m = 0; m < 9; m++) {
1186                di = si;
1187                bx = si + 0x04;
1188                dl = 0;
1189
1190                for (n = 0; n < 3; n++) {
1191                        for (o = 0; o < 5; o++) {
1192                                dh = table[si];
1193                                ah = table[di];
1194                                al = table[bx];
1195                                si++;
1196                                XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1197                        }
1198
1199                        si -= 2;
1200
1201                        for (o = 0; o < 3; o++) {
1202                                dh = table[bx];
1203                                ah = table[di];
1204                                al = table[si];
1205                                si--;
1206                                XGI_WriteDAC(dl, ah, al, dh, pVBInfo);
1207                        }
1208
1209                        dl++;
1210                }
1211
1212                si += 5;
1213        }
1214}
1215
1216static void XGI_GetLVDSResInfo(unsigned short ModeNo,
1217                               unsigned short ModeIdIndex,
1218                               struct vb_device_info *pVBInfo)
1219{
1220        unsigned short resindex, xres, yres, modeflag;
1221
1222        /* si+Ext_ResInfo */
1223        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1224
1225        /* si+Ext_ResInfo */
1226        resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
1227
1228        xres = XGI330_ModeResInfo[resindex].HTotal;
1229        yres = XGI330_ModeResInfo[resindex].VTotal;
1230
1231        if (modeflag & HalfDCLK)
1232                xres = xres << 1;
1233
1234        if (modeflag & DoubleScanMode)
1235                yres = yres << 1;
1236
1237        if (xres == 720)
1238                xres = 640;
1239
1240        pVBInfo->VGAHDE = xres;
1241        pVBInfo->HDE = xres;
1242        pVBInfo->VGAVDE = yres;
1243        pVBInfo->VDE = yres;
1244}
1245
1246static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table,
1247                unsigned short ModeNo,
1248                unsigned short ModeIdIndex,
1249                unsigned short RefreshRateTableIndex,
1250                struct vb_device_info *pVBInfo)
1251{
1252        unsigned short i, tempdx, tempbx, modeflag;
1253
1254        tempbx = 0;
1255
1256        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1257
1258        i = 0;
1259
1260        while (table[i].PANELID != 0xff) {
1261                tempdx = pVBInfo->LCDResInfo;
1262                if (tempbx & 0x0080) { /* OEMUtil */
1263                        tempbx &= (~0x0080);
1264                        tempdx = pVBInfo->LCDTypeInfo;
1265                }
1266
1267                if (pVBInfo->LCDInfo & EnableScalingLCD)
1268                        tempdx &= (~PanelResInfo);
1269
1270                if (table[i].PANELID == tempdx) {
1271                        tempbx = table[i].MASK;
1272                        tempdx = pVBInfo->LCDInfo;
1273
1274                        if (modeflag & HalfDCLK)
1275                                tempdx |= SetLCDLowResolution;
1276
1277                        tempbx &= tempdx;
1278                        if (tempbx == table[i].CAP)
1279                                break;
1280                }
1281                i++;
1282        }
1283
1284        return table[i].DATAPTR;
1285}
1286
1287static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo,
1288                unsigned short ModeIdIndex,
1289                unsigned short RefreshRateTableIndex,
1290                struct vb_device_info *pVBInfo)
1291{
1292        unsigned short i, tempdx, tempal, modeflag;
1293
1294        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1295        tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
1296        tempal = tempal & 0x3f;
1297        tempdx = pVBInfo->TVInfo;
1298
1299        if (pVBInfo->VBInfo & SetInSlaveMode)
1300                tempdx = tempdx | SetTVLockMode;
1301
1302        if (modeflag & HalfDCLK)
1303                tempdx = tempdx | SetTVLowResolution;
1304
1305        i = 0;
1306
1307        while (XGI_TVDataTable[i].MASK != 0xffff) {
1308                if ((tempdx & XGI_TVDataTable[i].MASK) ==
1309                        XGI_TVDataTable[i].CAP)
1310                        break;
1311                i++;
1312        }
1313
1314        return &XGI_TVDataTable[i].DATAPTR[tempal];
1315}
1316
1317static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
1318                unsigned short RefreshRateTableIndex,
1319                struct vb_device_info *pVBInfo)
1320{
1321        struct SiS_LVDSData const *LCDPtr;
1322
1323        if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
1324                return;
1325
1326        LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeNo, ModeIdIndex,
1327                               RefreshRateTableIndex, pVBInfo);
1328        pVBInfo->VGAHT  = LCDPtr->VGAHT;
1329        pVBInfo->VGAVT  = LCDPtr->VGAVT;
1330        pVBInfo->HT     = LCDPtr->LCDHT;
1331        pVBInfo->VT     = LCDPtr->LCDVT;
1332
1333        if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))
1334                return;
1335
1336        if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1337            (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
1338                pVBInfo->HDE = 1024;
1339                pVBInfo->VDE = 768;
1340        } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1341                   (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
1342                pVBInfo->HDE = 1280;
1343                pVBInfo->VDE = 1024;
1344        } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
1345                pVBInfo->HDE = 1400;
1346                pVBInfo->VDE = 1050;
1347        } else {
1348                pVBInfo->HDE = 1600;
1349                pVBInfo->VDE = 1200;
1350        }
1351}
1352
1353static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
1354                unsigned short RefreshRateTableIndex,
1355                struct xgi_hw_device_info *HwDeviceExtension,
1356                struct vb_device_info *pVBInfo)
1357{
1358        unsigned short i;
1359        struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL;
1360        struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL;
1361
1362        if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1363                LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeNo, ModeIdIndex,
1364                                       RefreshRateTableIndex, pVBInfo);
1365
1366                for (i = 0; i < 8; i++)
1367                        pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
1368        }
1369
1370        XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
1371
1372        if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1373                LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeNo,
1374                                        ModeIdIndex, RefreshRateTableIndex,
1375                                        pVBInfo);
1376                for (i = 0; i < 7; i++)
1377                        pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
1378        }
1379
1380        XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
1381}
1382
1383static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo)
1384{
1385        unsigned char tempal, tempah, tempbl, i;
1386
1387        tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36);
1388        tempal = tempah & 0x0F;
1389        tempah = tempah & 0xF0;
1390        i = 0;
1391        tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1392
1393        while (tempbl != 0xFF) {
1394                if (tempbl & 0x80) { /* OEMUtil */
1395                        tempal = tempah;
1396                        tempbl = tempbl & ~(0x80);
1397                }
1398
1399                if (tempal == tempbl)
1400                        break;
1401
1402                i++;
1403
1404                tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1405        }
1406
1407        return i;
1408}
1409
1410static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
1411{
1412        unsigned short tempah, tempal, tempbl, i;
1413
1414        tempal = pVBInfo->LCDResInfo;
1415        tempah = pVBInfo->LCDTypeInfo;
1416
1417        i = 0;
1418        tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1419
1420        while (tempbl != 0xFF) {
1421                if ((tempbl & 0x80) && (tempbl != 0x80)) {
1422                        tempal = tempah;
1423                        tempbl &= ~0x80;
1424                }
1425
1426                if (tempal == tempbl)
1427                        break;
1428
1429                i++;
1430                tempbl = pVBInfo->LCDCapList[i].LCD_ID;
1431        }
1432
1433        if (tempbl == 0xFF) {
1434                pVBInfo->LCDResInfo = Panel_1024x768;
1435                pVBInfo->LCDTypeInfo = 0;
1436                i = 0;
1437        }
1438
1439        return i;
1440}
1441
1442static void XGI_GetLCDSync(unsigned short *HSyncWidth,
1443                           unsigned short *VSyncWidth,
1444                           struct vb_device_info *pVBInfo)
1445{
1446        unsigned short Index;
1447
1448        Index = XGI_GetLCDCapPtr(pVBInfo);
1449        *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
1450        *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
1451
1452        return;
1453}
1454
1455static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
1456                unsigned short RefreshRateTableIndex,
1457                struct vb_device_info *pVBInfo)
1458{
1459        unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
1460        unsigned long temp, temp1, temp2, temp3, push3;
1461        struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL;
1462
1463        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1464        LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeNo, ModeIdIndex,
1465                                        RefreshRateTableIndex, pVBInfo);
1466
1467        XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
1468        push1 = tempbx;
1469        push2 = tempax;
1470
1471        /* GetLCDResInfo */
1472        if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
1473            (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
1474                tempax = 1024;
1475                tempbx = 768;
1476        } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
1477                   (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
1478                tempax = 1280;
1479                tempbx = 1024;
1480        } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
1481                tempax = 1400;
1482                tempbx = 1050;
1483        } else {
1484                tempax = 1600;
1485                tempbx = 1200;
1486        }
1487
1488        if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
1489                pVBInfo->HDE = tempax;
1490                pVBInfo->VDE = tempbx;
1491                pVBInfo->VGAHDE = tempax;
1492                pVBInfo->VGAVDE = tempbx;
1493        }
1494
1495        tempax = pVBInfo->HT;
1496
1497        tempbx = LCDPtr1->LCDHDES;
1498
1499        tempcx = pVBInfo->HDE;
1500        tempbx = tempbx & 0x0fff;
1501        tempcx += tempbx;
1502
1503        if (tempcx >= tempax)
1504                tempcx -= tempax;
1505
1506        xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
1507
1508        tempcx = tempcx >> 3;
1509        tempbx = tempbx >> 3;
1510
1511        xgifb_reg_set(pVBInfo->Part1Port, 0x16,
1512                        (unsigned short) (tempbx & 0xff));
1513        xgifb_reg_set(pVBInfo->Part1Port, 0x17,
1514                        (unsigned short) (tempcx & 0xff));
1515
1516        tempax = pVBInfo->HT;
1517
1518        tempbx = LCDPtr1->LCDHRS;
1519
1520        tempcx = push2;
1521
1522        if (pVBInfo->LCDInfo & EnableScalingLCD)
1523                tempcx = LCDPtr1->LCDHSync;
1524
1525        tempcx += tempbx;
1526
1527        if (tempcx >= tempax)
1528                tempcx -= tempax;
1529
1530        tempax = tempbx & 0x07;
1531        tempax = tempax >> 5;
1532        tempcx = tempcx >> 3;
1533        tempbx = tempbx >> 3;
1534
1535        tempcx &= 0x1f;
1536        tempax |= tempcx;
1537
1538        xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax);
1539        xgifb_reg_set(pVBInfo->Part1Port, 0x14,
1540                        (unsigned short) (tempbx & 0xff));
1541
1542        tempax = pVBInfo->VT;
1543        tempbx = LCDPtr1->LCDVDES;
1544        tempcx = pVBInfo->VDE;
1545
1546        tempbx = tempbx & 0x0fff;
1547        tempcx += tempbx;
1548        if (tempcx >= tempax)
1549                tempcx -= tempax;
1550
1551        xgifb_reg_set(pVBInfo->Part1Port, 0x1b,
1552                        (unsigned short) (tempbx & 0xff));
1553        xgifb_reg_set(pVBInfo->Part1Port, 0x1c,
1554                        (unsigned short) (tempcx & 0xff));
1555
1556        tempbx = (tempbx >> 8) & 0x07;
1557        tempcx = (tempcx >> 8) & 0x07;
1558
1559        xgifb_reg_set(pVBInfo->Part1Port, 0x1d,
1560                        (unsigned short) ((tempcx << 3)
1561                                        | tempbx));
1562
1563        tempax = pVBInfo->VT;
1564        tempbx = LCDPtr1->LCDVRS;
1565
1566        tempcx = push1;
1567
1568        if (pVBInfo->LCDInfo & EnableScalingLCD)
1569                tempcx = LCDPtr1->LCDVSync;
1570
1571        tempcx += tempbx;
1572        if (tempcx >= tempax)
1573                tempcx -= tempax;
1574
1575        xgifb_reg_set(pVBInfo->Part1Port, 0x18,
1576                        (unsigned short) (tempbx & 0xff));
1577        xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f,
1578                        (unsigned short) (tempcx & 0x0f));
1579
1580        tempax = ((tempbx >> 8) & 0x07) << 3;
1581
1582        tempbx = pVBInfo->VGAVDE;
1583        if (tempbx != pVBInfo->VDE)
1584                tempax |= 0x40;
1585
1586        if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA)
1587                tempax |= 0x40;
1588
1589        xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07,
1590                                tempax);
1591
1592        tempcx = pVBInfo->VGAVT;
1593        tempbx = pVBInfo->VDE;
1594        tempax = pVBInfo->VGAVDE;
1595        tempcx -= tempax;
1596
1597        temp = tempax; /* 0430 ylshieh */
1598        temp1 = (temp << 18) / tempbx;
1599
1600        tempdx = (unsigned short) ((temp << 18) % tempbx);
1601
1602        if (tempdx != 0)
1603                temp1 += 1;
1604
1605        temp2 = temp1;
1606        push3 = temp2;
1607
1608        xgifb_reg_set(pVBInfo->Part1Port, 0x37,
1609                        (unsigned short) (temp2 & 0xff));
1610        xgifb_reg_set(pVBInfo->Part1Port, 0x36,
1611                        (unsigned short) ((temp2 >> 8) & 0xff));
1612
1613        tempbx = (unsigned short) (temp2 >> 16);
1614        tempax = tempbx & 0x03;
1615
1616        tempbx = pVBInfo->VGAVDE;
1617        if (tempbx == pVBInfo->VDE)
1618                tempax |= 0x04;
1619
1620        xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax);
1621
1622        if (pVBInfo->VBType & VB_XGI301C) {
1623                temp2 = push3;
1624                xgifb_reg_set(pVBInfo->Part4Port,
1625                              0x3c,
1626                              (unsigned short) (temp2 & 0xff));
1627                xgifb_reg_set(pVBInfo->Part4Port,
1628                              0x3b,
1629                              (unsigned short) ((temp2 >> 8) &
1630                              0xff));
1631                tempbx = (unsigned short) (temp2 >> 16);
1632                xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a,
1633                                ~0xc0,
1634                                (unsigned short) ((tempbx &
1635                                                   0xff) << 6));
1636
1637                tempcx = pVBInfo->VGAVDE;
1638                if (tempcx == pVBInfo->VDE)
1639                        xgifb_reg_and_or(pVBInfo->Part4Port,
1640                                        0x30, ~0x0c, 0x00);
1641                else
1642                        xgifb_reg_and_or(pVBInfo->Part4Port,
1643                                        0x30, ~0x0c, 0x08);
1644        }
1645
1646        tempcx = pVBInfo->VGAHDE;
1647        tempbx = pVBInfo->HDE;
1648
1649        temp1 = tempcx << 16;
1650
1651        tempax = (unsigned short) (temp1 / tempbx);
1652
1653        if ((tempbx & 0xffff) == (tempcx & 0xffff))
1654                tempax = 65535;
1655
1656        temp3 = tempax;
1657        temp1 = pVBInfo->VGAHDE << 16;
1658
1659        temp1 /= temp3;
1660        temp3 = temp3 << 16;
1661        temp1 -= 1;
1662
1663        temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
1664
1665        tempax = (unsigned short) (temp3 & 0xff);
1666        xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax);
1667
1668        temp1 = pVBInfo->VGAVDE << 18;
1669        temp1 = temp1 / push3;
1670        tempbx = (unsigned short) (temp1 & 0xffff);
1671
1672        if (pVBInfo->LCDResInfo == Panel_1024x768)
1673                tempbx -= 1;
1674
1675        tempax = ((tempbx >> 8) & 0xff) << 3;
1676        tempax |= (unsigned short) ((temp3 >> 8) & 0x07);
1677        xgifb_reg_set(pVBInfo->Part1Port, 0x20,
1678                        (unsigned short) (tempax & 0xff));
1679        xgifb_reg_set(pVBInfo->Part1Port, 0x21,
1680                        (unsigned short) (tempbx & 0xff));
1681
1682        temp3 = temp3 >> 16;
1683
1684        if (modeflag & HalfDCLK)
1685                temp3 = temp3 >> 1;
1686
1687        xgifb_reg_set(pVBInfo->Part1Port, 0x22,
1688                        (unsigned short) ((temp3 >> 8) & 0xff));
1689        xgifb_reg_set(pVBInfo->Part1Port, 0x23,
1690                        (unsigned short) (temp3 & 0xff));
1691}
1692
1693/* --------------------------------------------------------------------- */
1694/* Function : XGI_GETLCDVCLKPtr */
1695/* Input : */
1696/* Output : al -> VCLK Index */
1697/* Description : */
1698/* --------------------------------------------------------------------- */
1699static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
1700                struct vb_device_info *pVBInfo)
1701{
1702        unsigned short index;
1703
1704        if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
1705                index = XGI_GetLCDCapPtr1(pVBInfo);
1706
1707                if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
1708                        *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
1709                        *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
1710                } else { /* LCDA */
1711                        *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
1712                        *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
1713                }
1714        }
1715        return;
1716}
1717
1718static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
1719                unsigned short ModeNo, unsigned short ModeIdIndex,
1720                struct vb_device_info *pVBInfo)
1721{
1722
1723        unsigned short index, modeflag;
1724        unsigned char tempal;
1725
1726        /* si+Ext_ResInfo */
1727        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1728
1729        if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
1730            (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
1731                index = XGI_GetLCDCapPtr(pVBInfo);
1732                tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
1733
1734                if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
1735                        return tempal;
1736
1737                /* {TV} */
1738                if (pVBInfo->VBType &
1739                    (VB_SIS301B |
1740                     VB_SIS302B |
1741                     VB_SIS301LV |
1742                     VB_SIS302LV |
1743                     VB_XGI301C)) {
1744                        if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
1745                                tempal = TVCLKBASE_315 + HiTVVCLKDIV2;
1746                                if (!(pVBInfo->TVInfo & RPLLDIV2XO))
1747                                        tempal = TVCLKBASE_315 + HiTVVCLK;
1748                                if (pVBInfo->TVInfo & TVSimuMode) {
1749                                        tempal = TVCLKBASE_315 + HiTVSimuVCLK;
1750                                        if (!(modeflag & Charx8Dot))
1751                                                tempal = TVCLKBASE_315 +
1752                                                                HiTVTextVCLK;
1753
1754                                }
1755                                return tempal;
1756                        }
1757
1758                        if (pVBInfo->TVInfo & TVSetYPbPr750p) {
1759                                tempal = XGI_YPbPr750pVCLK;
1760                                return tempal;
1761                        }
1762
1763                        if (pVBInfo->TVInfo & TVSetYPbPr525p) {
1764                                tempal = YPbPr525pVCLK;
1765                                return tempal;
1766                        }
1767
1768                        tempal = NTSC1024VCLK;
1769
1770                        if (!(pVBInfo->TVInfo & NTSC1024x768)) {
1771                                tempal = TVCLKBASE_315 + TVVCLKDIV2;
1772                                if (!(pVBInfo->TVInfo & RPLLDIV2XO))
1773                                        tempal = TVCLKBASE_315 + TVVCLK;
1774                        }
1775
1776                        if (pVBInfo->VBInfo & SetCRT2ToTV)
1777                                return tempal;
1778                }
1779        } /* {End of VB} */
1780
1781        inb((pVBInfo->P3ca + 0x02));
1782        tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
1783        return tempal;
1784}
1785
1786static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
1787                unsigned char *di_1, struct vb_device_info *pVBInfo)
1788{
1789        if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B
1790                        | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
1791                if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
1792                    (pVBInfo->SetFlag & ProgrammingCRT2)) {
1793                        *di_0 = XGI_VBVCLKData[tempal].Part4_A;
1794                        *di_1 = XGI_VBVCLKData[tempal].Part4_B;
1795                }
1796        } else {
1797                *di_0 = XGI_VCLKData[tempal].SR2B;
1798                *di_1 = XGI_VCLKData[tempal].SR2C;
1799        }
1800}
1801
1802static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
1803                unsigned short RefreshRateTableIndex,
1804                struct vb_device_info *pVBInfo)
1805{
1806        unsigned char di_0, di_1, tempal;
1807        int i;
1808
1809        tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
1810                        pVBInfo);
1811        XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
1812        XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
1813
1814        for (i = 0; i < 4; i++) {
1815                xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30,
1816                                (unsigned short) (0x10 * i));
1817                if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
1818                                && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
1819                        xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0);
1820                        xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1);
1821                } else {
1822                        xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0);
1823                        xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1);
1824                }
1825        }
1826}
1827
1828static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
1829                struct vb_device_info *pVBInfo)
1830{
1831        unsigned short tempcl, tempch, temp, tempbl, tempax;
1832
1833        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
1834                        | VB_SIS302LV | VB_XGI301C)) {
1835                tempcl = 0;
1836                tempch = 0;
1837                temp = xgifb_reg_get(pVBInfo->P3c4, 0x01);
1838
1839                if (!(temp & 0x20)) {
1840                        temp = xgifb_reg_get(pVBInfo->P3d4, 0x17);
1841                        if (temp & 0x80) {
1842                                temp = xgifb_reg_get(pVBInfo->P3d4, 0x53);
1843                                if (!(temp & 0x40))
1844                                        tempcl |= ActiveCRT1;
1845                        }
1846                }
1847
1848                temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e);
1849                temp &= 0x0f;
1850
1851                if (!(temp == 0x08)) {
1852                        /* Check ChannelA */
1853                        tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13);
1854                        if (tempax & 0x04)
1855                                tempcl = tempcl | ActiveLCD;
1856
1857                        temp &= 0x05;
1858
1859                        if (!(tempcl & ActiveLCD))
1860                                if (temp == 0x01)
1861                                        tempcl |= ActiveCRT2;
1862
1863                        if (temp == 0x04)
1864                                tempcl |= ActiveLCD;
1865
1866                        if (temp == 0x05) {
1867                                temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00);
1868
1869                                if (!(temp & 0x08))
1870                                        tempch |= ActiveAVideo;
1871
1872                                if (!(temp & 0x04))
1873                                        tempch |= ActiveSVideo;
1874
1875                                if (temp & 0x02)
1876                                        tempch |= ActiveSCART;
1877
1878                                if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
1879                                        if (temp & 0x01)
1880                                                tempch |= ActiveHiTV;
1881                                }
1882
1883                                if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
1884                                        temp = xgifb_reg_get(
1885                                                        pVBInfo->Part2Port,
1886                                                        0x4d);
1887
1888                                        if (temp & 0x10)
1889                                                tempch |= ActiveYPbPr;
1890                                }
1891
1892                                if (tempch != 0)
1893                                        tempcl |= ActiveTV;
1894                        }
1895                }
1896
1897                temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
1898                if (tempcl & ActiveLCD) {
1899                        if ((pVBInfo->SetFlag & ReserveTVOption)) {
1900                                if (temp & ActiveTV)
1901                                        tempcl |= ActiveTV;
1902                        }
1903                }
1904                temp = tempcl;
1905                tempbl = ~XGI_ModeSwitchStatus;
1906                xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp);
1907
1908                if (!(pVBInfo->SetFlag & ReserveTVOption))
1909                        xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch);
1910        } else {
1911                return;
1912        }
1913}
1914
1915void XGI_GetVBType(struct vb_device_info *pVBInfo)
1916{
1917        unsigned short flag, tempbx, tempah;
1918
1919        if (pVBInfo->IF_DEF_LVDS != 0)
1920                return;
1921
1922        tempbx = VB_SIS302B;
1923        flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
1924        if (flag == 0x02)
1925                goto finish;
1926
1927        tempbx = VB_SIS301;
1928        flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
1929        if (flag < 0xB0)
1930                goto finish;
1931
1932        tempbx = VB_SIS301B;
1933        if (flag < 0xC0)
1934                goto bigger_than_0xB0;
1935
1936        tempbx = VB_XGI301C;
1937        if (flag < 0xD0)
1938                goto bigger_than_0xB0;
1939
1940        tempbx = VB_SIS301LV;
1941        if (flag < 0xE0)
1942                goto bigger_than_0xB0;
1943
1944        tempbx = VB_SIS302LV;
1945        tempah = xgifb_reg_get(pVBInfo->Part4Port, 0x39);
1946        if (tempah != 0xFF)
1947                tempbx = VB_XGI301C;
1948
1949bigger_than_0xB0:
1950        if (tempbx & (VB_SIS301B | VB_SIS302B)) {
1951                flag = xgifb_reg_get(pVBInfo->Part4Port, 0x23);
1952                if (!(flag & 0x02))
1953                        tempbx = tempbx | VB_NoLCD;
1954        }
1955
1956finish:
1957        pVBInfo->VBType = tempbx;
1958}
1959
1960static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
1961                struct xgi_hw_device_info *HwDeviceExtension,
1962                struct vb_device_info *pVBInfo)
1963{
1964        unsigned short tempax, push, tempbx, temp, modeflag;
1965
1966        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1967        pVBInfo->SetFlag = 0;
1968        pVBInfo->ModeType = modeflag & ModeTypeMask;
1969        tempbx = 0;
1970
1971        if (!(pVBInfo->VBType & 0xFFFF))
1972                return;
1973
1974        /* Check Display Device */
1975        temp = xgifb_reg_get(pVBInfo->P3d4, 0x30);
1976        tempbx = tempbx | temp;
1977        temp = xgifb_reg_get(pVBInfo->P3d4, 0x31);
1978        push = temp;
1979        push = push << 8;
1980        tempax = temp << 8;
1981        tempbx = tempbx | tempax;
1982        temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA
1983                | SetInSlaveMode | DisableCRT2Display);
1984        temp = 0xFFFF ^ temp;
1985        tempbx &= temp;
1986
1987        temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
1988
1989        if (pVBInfo->VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV |
1990                               VB_XGI301C)) {
1991                if (temp & EnableDualEdge) {
1992                        tempbx |= SetCRT2ToDualEdge;
1993                        if (temp & SetToLCDA)
1994                                tempbx |= XGI_SetCRT2ToLCDA;
1995                }
1996        }
1997
1998        if (pVBInfo->IF_DEF_YPbPr == 1) {
1999                if (pVBInfo->VBType & (VB_SIS301LV|VB_SIS302LV|VB_XGI301C)) {
2000                        if (temp & SetYPbPr) {
2001                                if (pVBInfo->IF_DEF_HiVision == 1) {
2002                                        /* shampoo add for new scratch */
2003                                        temp = xgifb_reg_get(pVBInfo->P3d4,
2004                                                             0x35);
2005                                        temp &= YPbPrMode;
2006                                        tempbx |= SetCRT2ToHiVision;
2007
2008                                        if (temp != YPbPrMode1080i) {
2009                                                tempbx &= (~SetCRT2ToHiVision);
2010                                                tempbx |= SetCRT2ToYPbPr525750;
2011                                        }
2012                                }
2013                        }
2014                }
2015        }
2016
2017        tempax = push; /* restore CR31 */
2018
2019        if (pVBInfo->IF_DEF_YPbPr == 1) {
2020                if (pVBInfo->IF_DEF_HiVision == 1)
2021                        temp = 0x09FC;
2022                else
2023                        temp = 0x097C;
2024        } else if (pVBInfo->IF_DEF_HiVision == 1) {
2025                temp = 0x01FC;
2026        } else {
2027                temp = 0x017C;
2028        }
2029
2030        if (!(tempbx & temp)) {
2031                tempax |= DisableCRT2Display;
2032                tempbx = 0;
2033        }
2034
2035        if (!(pVBInfo->VBType & VB_NoLCD)) {
2036                if (tempbx & XGI_SetCRT2ToLCDA) {
2037                        if (tempbx & SetSimuScanMode)
2038                                tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC |
2039                                             SwitchCRT2));
2040                        else
2041                                tempbx &= (~(SetCRT2ToLCD | SetCRT2ToRAMDAC |
2042                                             SetCRT2ToTV | SwitchCRT2));
2043                }
2044        }
2045
2046        /* shampoo add */
2047        /* for driver abnormal */
2048        if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
2049                if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
2050                        if (tempbx & SetCRT2ToRAMDAC) {
2051                                tempbx &= (0xFF00 | SetCRT2ToRAMDAC |
2052                                           SwitchCRT2 | SetSimuScanMode);
2053                                tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2054                        }
2055                } else {
2056                        tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD |
2057                                     SetCRT2ToTV));
2058                }
2059        }
2060
2061        if (!(pVBInfo->VBType & VB_NoLCD)) {
2062                if (tempbx & SetCRT2ToLCD) {
2063                        tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchCRT2 |
2064                                   SetSimuScanMode);
2065                        tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2066                }
2067        }
2068
2069        if (tempbx & SetCRT2ToSCART) {
2070                tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchCRT2 |
2071                           SetSimuScanMode);
2072                tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
2073        }
2074
2075        if (pVBInfo->IF_DEF_YPbPr == 1) {
2076                if (tempbx & SetCRT2ToYPbPr525750)
2077                        tempbx &= (0xFF00 | SwitchCRT2 | SetSimuScanMode);
2078        }
2079
2080        if (pVBInfo->IF_DEF_HiVision == 1) {
2081                if (tempbx & SetCRT2ToHiVision)
2082                        tempbx &= (0xFF00 | SetCRT2ToHiVision | SwitchCRT2 |
2083                                   SetSimuScanMode);
2084        }
2085
2086        if (tempax & DisableCRT2Display) { /* Set Display Device Info */
2087                if (!(tempbx & (SwitchCRT2 | SetSimuScanMode)))
2088                        tempbx = DisableCRT2Display;
2089        }
2090
2091        if (!(tempbx & DisableCRT2Display)) {
2092                if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) {
2093                        if (!(tempbx & XGI_SetCRT2ToLCDA))
2094                                tempbx |= (SetInSlaveMode | SetSimuScanMode);
2095                }
2096
2097                /* LCD+TV can't support in slave mode
2098                 * (Force LCDA+TV->LCDB) */
2099                if ((tempbx & SetInSlaveMode) && (tempbx & XGI_SetCRT2ToLCDA)) {
2100                        tempbx ^= (SetCRT2ToLCD | XGI_SetCRT2ToLCDA |
2101                                   SetCRT2ToDualEdge);
2102                        pVBInfo->SetFlag |= ReserveTVOption;
2103                }
2104        }
2105
2106        pVBInfo->VBInfo = tempbx;
2107}
2108
2109static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
2110                struct vb_device_info *pVBInfo)
2111{
2112        unsigned short tempbx = 0, resinfo = 0, modeflag, index1;
2113
2114        if (pVBInfo->VBInfo & SetCRT2ToTV) {
2115                modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2116                resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2117
2118                tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2119                if (tempbx & TVSetPAL) {
2120                        tempbx &= (SetCHTVOverScan |
2121                                   TVSetPALM |
2122                                   TVSetPALN |
2123                                   TVSetPAL);
2124                        if (tempbx & TVSetPALM)
2125                                /* set to NTSC if PAL-M */
2126                                tempbx &= ~TVSetPAL;
2127                } else
2128                        tempbx &= (SetCHTVOverScan |
2129                                   TVSetNTSCJ |
2130                                   TVSetPAL);
2131
2132                if (pVBInfo->VBInfo & SetCRT2ToSCART)
2133                        tempbx |= TVSetPAL;
2134
2135                if (pVBInfo->IF_DEF_YPbPr == 1) {
2136                        if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2137                                index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35);
2138                                index1 &= YPbPrMode;
2139
2140                                if (index1 == YPbPrMode525i)
2141                                        tempbx |= TVSetYPbPr525i;
2142
2143                                if (index1 == YPbPrMode525p)
2144                                        tempbx = tempbx | TVSetYPbPr525p;
2145                                if (index1 == YPbPrMode750p)
2146                                        tempbx = tempbx | TVSetYPbPr750p;
2147                        }
2148                }
2149
2150                if (pVBInfo->IF_DEF_HiVision == 1) {
2151                        if (pVBInfo->VBInfo & SetCRT2ToHiVision)
2152                                tempbx = tempbx | TVSetHiVision | TVSetPAL;
2153                }
2154
2155                if ((pVBInfo->VBInfo & SetInSlaveMode) &&
2156                    (!(pVBInfo->VBInfo & SetNotSimuMode)))
2157                        tempbx |= TVSimuMode;
2158
2159                if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8))
2160                        /* NTSC 1024x768, */
2161                        tempbx |= NTSC1024x768;
2162
2163                tempbx |= RPLLDIV2XO;
2164
2165                if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2166                        if (pVBInfo->VBInfo & SetInSlaveMode)
2167                                tempbx &= (~RPLLDIV2XO);
2168                } else if (tempbx & (TVSetYPbPr525p | TVSetYPbPr750p)) {
2169                        tempbx &= (~RPLLDIV2XO);
2170                } else if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B |
2171                                                VB_SIS301LV | VB_SIS302LV |
2172                                                VB_XGI301C))) {
2173                        if (tempbx & TVSimuMode)
2174                                tempbx &= (~RPLLDIV2XO);
2175                }
2176        }
2177        pVBInfo->TVInfo = tempbx;
2178}
2179
2180static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
2181                unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
2182{
2183        unsigned short temp, tempax, tempbx, resinfo = 0, LCDIdIndex;
2184
2185        pVBInfo->LCDResInfo = 0;
2186        pVBInfo->LCDTypeInfo = 0;
2187        pVBInfo->LCDInfo = 0;
2188
2189        /* si+Ext_ResInfo // */
2190        resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2191        temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
2192        tempbx = temp & 0x0F;
2193
2194        if (tempbx == 0)
2195                tempbx = Panel_1024x768; /* default */
2196
2197        /* LCD75 */
2198        if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) {
2199                if (pVBInfo->VBInfo & DriverMode) {
2200                        tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33);
2201                        if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
2202                                tempax &= 0x0F;
2203                        else
2204                                tempax = tempax >> 4;
2205
2206                        if ((resinfo == 6) || (resinfo == 9)) {
2207                                if (tempax >= 3)
2208                                        tempbx |= PanelRef75Hz;
2209                        } else if ((resinfo == 7) || (resinfo == 8)) {
2210                                if (tempax >= 4)
2211                                        tempbx |= PanelRef75Hz;
2212                        }
2213                }
2214        }
2215
2216        pVBInfo->LCDResInfo = tempbx;
2217
2218        /* End of LCD75 */
2219
2220        if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
2221                return 0;
2222
2223        tempbx = 0;
2224
2225        temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
2226
2227        temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
2228
2229        tempbx |= temp;
2230
2231        LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
2232
2233        tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
2234
2235        if (((pVBInfo->VBType & VB_SIS302LV) ||
2236             (pVBInfo->VBType & VB_XGI301C)) && (tempax & XGI_LCDDualLink))
2237                tempbx |= SetLCDDualLink;
2238
2239        if ((pVBInfo->LCDResInfo == Panel_1400x1050) &&
2240            (pVBInfo->VBInfo & SetCRT2ToLCD) && (resinfo == 9) &&
2241            (!(tempbx & EnableScalingLCD)))
2242                /*
2243                 * set to center in 1280x1024 LCDB
2244                 * for Panel_1400x1050
2245                 */
2246                tempbx |= SetLCDtoNonExpanding;
2247
2248        if (pVBInfo->VBInfo & SetInSlaveMode) {
2249                if (pVBInfo->VBInfo & SetNotSimuMode)
2250                        tempbx |= XGI_LCDVESATiming;
2251        } else {
2252                tempbx |= XGI_LCDVESATiming;
2253        }
2254
2255        pVBInfo->LCDInfo = tempbx;
2256
2257        return 1;
2258}
2259
2260unsigned char XGI_SearchModeID(unsigned short ModeNo,
2261                unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo)
2262{
2263        for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
2264                if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
2265                        break;
2266                if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
2267                        return 0;
2268        }
2269
2270        return 1;
2271}
2272
2273static unsigned char XG21GPIODataTransfer(unsigned char ujDate)
2274{
2275        unsigned char ujRet = 0;
2276        unsigned char i = 0;
2277
2278        for (i = 0; i < 8; i++) {
2279                ujRet = ujRet << 1;
2280                ujRet |= (ujDate >> i) & 1;
2281        }
2282
2283        return ujRet;
2284}
2285
2286/*----------------------------------------------------------------------------*/
2287/* output                                                                     */
2288/*      bl[5] : LVDS signal                                                   */
2289/*      bl[1] : LVDS backlight                                                */
2290/*      bl[0] : LVDS VDD                                                      */
2291/*----------------------------------------------------------------------------*/
2292static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo)
2293{
2294        unsigned char CR4A, temp;
2295
2296        CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2297        xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */
2298
2299        temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2300
2301        temp = XG21GPIODataTransfer(temp);
2302        temp &= 0x23;
2303        xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
2304        return temp;
2305}
2306
2307/*----------------------------------------------------------------------------*/
2308/* output                                                                     */
2309/*      bl[5] : LVDS signal                                                   */
2310/*      bl[1] : LVDS backlight                                                */
2311/*      bl[0] : LVDS VDD                                                      */
2312/*----------------------------------------------------------------------------*/
2313static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo)
2314{
2315        unsigned char CR4A, CRB4, temp;
2316
2317        CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2318        xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */
2319
2320        temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2321
2322        temp &= 0x0C;
2323        temp >>= 2;
2324        xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
2325        CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4);
2326        temp |= ((CRB4 & 0x04) << 3);
2327        return temp;
2328}
2329
2330/*----------------------------------------------------------------------------*/
2331/* input                                                                      */
2332/*      bl[5] : 1;LVDS signal on                                              */
2333/*      bl[1] : 1;LVDS backlight on                                           */
2334/*      bl[0] : 1:LVDS VDD on                                                 */
2335/*      bh: 100000b : clear bit 5, to set bit5                                */
2336/*          000010b : clear bit 1, to set bit1                                */
2337/*          000001b : clear bit 0, to set bit0                                */
2338/*----------------------------------------------------------------------------*/
2339static void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
2340                struct vb_device_info *pVBInfo)
2341{
2342        unsigned char CR4A, temp;
2343
2344        CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2345        tempbh &= 0x23;
2346        tempbl &= 0x23;
2347        xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
2348
2349        if (tempbh & 0x20) {
2350                temp = (tempbl >> 4) & 0x02;
2351
2352                /* CR B4[1] */
2353                xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
2354
2355        }
2356
2357        temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
2358
2359        temp = XG21GPIODataTransfer(temp);
2360        temp &= ~tempbh;
2361        temp |= tempbl;
2362        xgifb_reg_set(pVBInfo->P3d4, 0x48, temp);
2363}
2364
2365static void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl,
2366                struct vb_device_info *pVBInfo)
2367{
2368        unsigned char CR4A, temp;
2369        unsigned short tempbh0, tempbl0;
2370
2371        tempbh0 = tempbh;
2372        tempbl0 = tempbl;
2373        tempbh0 &= 0x20;
2374        tempbl0 &= 0x20;
2375        tempbh0 >>= 3;
2376        tempbl0 >>= 3;
2377
2378        if (tempbh & 0x20) {
2379                temp = (tempbl >> 4) & 0x02;
2380
2381                /* CR B4[1] */
2382                xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
2383
2384        }
2385        xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
2386
2387        CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
2388        tempbh &= 0x03;
2389        tempbl &= 0x03;
2390        tempbh <<= 2;
2391        tempbl <<= 2; /* GPIOC,GPIOD */
2392        xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */
2393        xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl);
2394}
2395
2396static void XGI_DisplayOn(struct xgifb_video_info *xgifb_info,
2397                struct xgi_hw_device_info *pXGIHWDE,
2398                struct vb_device_info *pVBInfo)
2399{
2400
2401        xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00);
2402        if (pXGIHWDE->jChipType == XG21) {
2403                if (pVBInfo->IF_DEF_LVDS == 1) {
2404                        if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
2405                                /* LVDS VDD on */
2406                                XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo);
2407                                mdelay(xgifb_info->lvds_data.PSC_S2);
2408                        }
2409                        if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
2410                                /* LVDS signal on */
2411                                XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
2412                        mdelay(xgifb_info->lvds_data.PSC_S3);
2413                        /* LVDS backlight on */
2414                        XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo);
2415                } else {
2416                        /* DVO/DVI signal on */
2417                        XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
2418                }
2419
2420        }
2421
2422        if (pXGIHWDE->jChipType == XG27) {
2423                if (pVBInfo->IF_DEF_LVDS == 1) {
2424                        if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
2425                                /* LVDS VDD on */
2426                                XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo);
2427                                mdelay(xgifb_info->lvds_data.PSC_S2);
2428                        }
2429                        if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
2430                                /* LVDS signal on */
2431                                XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
2432                        mdelay(xgifb_info->lvds_data.PSC_S3);
2433                        /* LVDS backlight on */
2434                        XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo);
2435                } else {
2436                        /* DVO/DVI signal on */
2437                        XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
2438                }
2439
2440        }
2441}
2442
2443void XGI_DisplayOff(struct xgifb_video_info *xgifb_info,
2444                struct xgi_hw_device_info *pXGIHWDE,
2445                struct vb_device_info *pVBInfo)
2446{
2447
2448        if (pXGIHWDE->jChipType == XG21) {
2449                if (pVBInfo->IF_DEF_LVDS == 1) {
2450                        /* LVDS backlight off */
2451                        XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo);
2452                        mdelay(xgifb_info->lvds_data.PSC_S3);
2453                } else {
2454                        /* DVO/DVI signal off */
2455                        XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo);
2456                }
2457        }
2458
2459        if (pXGIHWDE->jChipType == XG27) {
2460                if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
2461                        /* LVDS backlight off */
2462                        XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo);
2463                        mdelay(xgifb_info->lvds_data.PSC_S3);
2464                }
2465
2466                if (pVBInfo->IF_DEF_LVDS == 0)
2467                        /* DVO/DVI signal off */
2468                        XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo);
2469        }
2470
2471        xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
2472}
2473
2474static void XGI_WaitDisply(struct vb_device_info *pVBInfo)
2475{
2476        while ((inb(pVBInfo->P3da) & 0x01))
2477                break;
2478
2479        while (!(inb(pVBInfo->P3da) & 0x01))
2480                break;
2481}
2482
2483static void XGI_AutoThreshold(struct vb_device_info *pVBInfo)
2484{
2485        xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40);
2486}
2487
2488static void XGI_SaveCRT2Info(unsigned short ModeNo,
2489                             struct vb_device_info *pVBInfo)
2490{
2491        unsigned short temp1, temp2;
2492
2493        /* reserve CR34 for CRT1 Mode No */
2494        xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo);
2495        temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
2496        temp2 = ~(SetInSlaveMode >> 8);
2497        xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1);
2498}
2499
2500static void XGI_GetCRT2ResInfo(unsigned short ModeNo,
2501                               unsigned short ModeIdIndex,
2502                               struct vb_device_info *pVBInfo)
2503{
2504        unsigned short xres, yres, modeflag, resindex;
2505
2506        resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2507        xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
2508        yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
2509        /* si+St_ModeFlag */
2510        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2511
2512        if (modeflag & HalfDCLK)
2513                xres *= 2;
2514
2515        if (modeflag & DoubleScanMode)
2516                yres *= 2;
2517
2518        if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
2519                goto exit;
2520
2521        if (pVBInfo->LCDResInfo == Panel_1600x1200) {
2522                if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2523                        if (yres == 1024)
2524                                yres = 1056;
2525                }
2526        }
2527
2528        if (pVBInfo->LCDResInfo == Panel_1280x1024) {
2529                if (yres == 400)
2530                        yres = 405;
2531                else if (yres == 350)
2532                        yres = 360;
2533
2534                if (pVBInfo->LCDInfo & XGI_LCDVESATiming) {
2535                        if (yres == 360)
2536                                yres = 375;
2537                }
2538        }
2539
2540        if (pVBInfo->LCDResInfo == Panel_1024x768) {
2541                if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2542                        if (!(pVBInfo->LCDInfo & LCDNonExpanding)) {
2543                                if (yres == 350)
2544                                        yres = 357;
2545                                else if (yres == 400)
2546                                        yres = 420;
2547                                else if (yres == 480)
2548                                        yres = 525;
2549                        }
2550                }
2551        }
2552
2553        if (xres == 720)
2554                xres = 640;
2555
2556exit:
2557        pVBInfo->VGAHDE = xres;
2558        pVBInfo->HDE = xres;
2559        pVBInfo->VGAVDE = yres;
2560        pVBInfo->VDE = yres;
2561}
2562
2563static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
2564{
2565
2566        if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) &&
2567                        (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
2568                return 1;
2569
2570        return 0;
2571}
2572
2573static void XGI_GetRAMDAC2DATA(unsigned short ModeNo,
2574                               unsigned short ModeIdIndex,
2575                               unsigned short RefreshRateTableIndex,
2576                               struct vb_device_info *pVBInfo)
2577{
2578        unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
2579                        CRT1Index;
2580
2581        pVBInfo->RVBHCMAX = 1;
2582        pVBInfo->RVBHCFACT = 1;
2583        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2584        CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2585        CRT1Index &= IndexMask;
2586        temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[0];
2587        temp2 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[5];
2588        tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
2589        tempbx = (unsigned short) XGI_CRT1Table[CRT1Index].CR[8];
2590        tempcx = (unsigned short)
2591                        XGI_CRT1Table[CRT1Index].CR[14] << 8;
2592        tempcx &= 0x0100;
2593        tempcx = tempcx << 2;
2594        tempbx |= tempcx;
2595        temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[9];
2596
2597        if (temp1 & 0x01)
2598                tempbx |= 0x0100;
2599
2600        if (temp1 & 0x20)
2601                tempbx |= 0x0200;
2602        tempax += 5;
2603
2604        if (modeflag & Charx8Dot)
2605                tempax *= 8;
2606        else
2607                tempax *= 9;
2608
2609        pVBInfo->VGAHT = tempax;
2610        pVBInfo->HT = tempax;
2611        tempbx++;
2612        pVBInfo->VGAVT = tempbx;
2613        pVBInfo->VT = tempbx;
2614}
2615
2616static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
2617                unsigned short RefreshRateTableIndex,
2618                struct vb_device_info *pVBInfo)
2619{
2620        unsigned short tempax = 0, tempbx = 0, modeflag, resinfo;
2621
2622        struct SiS_LCDData const *LCDPtr = NULL;
2623
2624        /* si+Ext_ResInfo */
2625        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2626        resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
2627        pVBInfo->NewFlickerMode = 0;
2628        pVBInfo->RVBHRS = 50;
2629
2630        if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
2631                XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
2632                                pVBInfo);
2633                return;
2634        }
2635
2636        if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
2637                LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeNo, ModeIdIndex,
2638                                       RefreshRateTableIndex, pVBInfo);
2639
2640                pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
2641                pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
2642                pVBInfo->VGAHT = LCDPtr->VGAHT;
2643                pVBInfo->VGAVT = LCDPtr->VGAVT;
2644                pVBInfo->HT = LCDPtr->LCDHT;
2645                pVBInfo->VT = LCDPtr->LCDVT;
2646
2647                if (pVBInfo->LCDResInfo == Panel_1024x768) {
2648                        tempax = 1024;
2649                        tempbx = 768;
2650
2651                        if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2652                                if (pVBInfo->VGAVDE == 357)
2653                                        tempbx = 527;
2654                                else if (pVBInfo->VGAVDE == 420)
2655                                        tempbx = 620;
2656                                else if (pVBInfo->VGAVDE == 525)
2657                                        tempbx = 775;
2658                                else if (pVBInfo->VGAVDE == 600)
2659                                        tempbx = 775;
2660                                else
2661                                        tempbx = 768;
2662                        } else
2663                                tempbx = 768;
2664                } else if (pVBInfo->LCDResInfo == Panel_1024x768x75) {
2665                        tempax = 1024;
2666                        tempbx = 768;
2667                } else if (pVBInfo->LCDResInfo == Panel_1280x1024) {
2668                        tempax = 1280;
2669                        if (pVBInfo->VGAVDE == 360)
2670                                tempbx = 768;
2671                        else if (pVBInfo->VGAVDE == 375)
2672                                tempbx = 800;
2673                        else if (pVBInfo->VGAVDE == 405)
2674                                tempbx = 864;
2675                        else
2676                                tempbx = 1024;
2677                } else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) {
2678                        tempax = 1280;
2679                        tempbx = 1024;
2680                } else if (pVBInfo->LCDResInfo == Panel_1280x960) {
2681                        tempax = 1280;
2682                        if (pVBInfo->VGAVDE == 350)
2683                                tempbx = 700;
2684                        else if (pVBInfo->VGAVDE == 400)
2685                                tempbx = 800;
2686                        else if (pVBInfo->VGAVDE == 1024)
2687                                tempbx = 960;
2688                        else
2689                                tempbx = 960;
2690                } else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
2691                        tempax = 1400;
2692                        tempbx = 1050;
2693
2694                        if (pVBInfo->VGAVDE == 1024) {
2695                                tempax = 1280;
2696                                tempbx = 1024;
2697                        }
2698                } else if (pVBInfo->LCDResInfo == Panel_1600x1200) {
2699                        tempax = 1600;
2700                        tempbx = 1200; /* alan 10/14/2003 */
2701                        if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
2702                                if (pVBInfo->VGAVDE == 350)
2703                                        tempbx = 875;
2704                                else if (pVBInfo->VGAVDE == 400)
2705                                        tempbx = 1000;
2706                        }
2707                }
2708
2709                if (pVBInfo->LCDInfo & LCDNonExpanding) {
2710                        tempax = pVBInfo->VGAHDE;
2711                        tempbx = pVBInfo->VGAVDE;
2712                }
2713
2714                pVBInfo->HDE = tempax;
2715                pVBInfo->VDE = tempbx;
2716                return;
2717        }
2718
2719        if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
2720                struct SiS_TVData const *TVPtr;
2721
2722                TVPtr = XGI_GetTVPtr(ModeNo, ModeIdIndex, RefreshRateTableIndex,
2723                                     pVBInfo);
2724
2725                pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
2726                pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
2727                pVBInfo->VGAHT = TVPtr->VGAHT;
2728                pVBInfo->VGAVT = TVPtr->VGAVT;
2729                pVBInfo->HDE = TVPtr->TVHDE;
2730                pVBInfo->VDE = TVPtr->TVVDE;
2731                pVBInfo->RVBHRS = TVPtr->RVBHRS;
2732                pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
2733
2734                if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
2735                        if (resinfo == 0x08)
2736                                pVBInfo->NewFlickerMode = 0x40;
2737                        else if (resinfo == 0x09)
2738                                pVBInfo->NewFlickerMode = 0x40;
2739                        else if (resinfo == 0x12)
2740                                pVBInfo->NewFlickerMode = 0x40;
2741
2742                        if (pVBInfo->VGAVDE == 350)
2743                                pVBInfo->TVInfo |= TVSimuMode;
2744
2745                        tempax = ExtHiTVHT;
2746                        tempbx = ExtHiTVVT;
2747
2748                        if (pVBInfo->VBInfo & SetInSlaveMode) {
2749                                if (pVBInfo->TVInfo & TVSimuMode) {
2750                                        tempax = StHiTVHT;
2751                                        tempbx = StHiTVVT;
2752
2753                                        if (!(modeflag & Charx8Dot)) {
2754                                                tempax = StHiTextTVHT;
2755                                                tempbx = StHiTextTVVT;
2756                                        }
2757                                }
2758                        }
2759                } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
2760                        if (pVBInfo->TVInfo & TVSetYPbPr750p) {
2761                                tempax = YPbPrTV750pHT; /* Ext750pTVHT */
2762                                tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
2763                        }
2764
2765                        if (pVBInfo->TVInfo & TVSetYPbPr525p) {
2766                                tempax = YPbPrTV525pHT; /* Ext525pTVHT */
2767                                tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
2768                        } else if (pVBInfo->TVInfo & TVSetYPbPr525i) {
2769                                tempax = YPbPrTV525iHT; /* Ext525iTVHT */
2770                                tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
2771                                if (pVBInfo->TVInfo & NTSC1024x768)
2772                                        tempax = NTSC1024x768HT;
2773                        }
2774                } else {
2775                        tempax = PALHT;
2776                        tempbx = PALVT;
2777                        if (!(pVBInfo->TVInfo & TVSetPAL)) {
2778                                tempax = NTSCHT;
2779                                tempbx = NTSCVT;
2780                                if (pVBInfo->TVInfo & NTSC1024x768)
2781                                        tempax = NTSC1024x768HT;
2782                        }
2783                }
2784
2785                pVBInfo->HT = tempax;
2786                pVBInfo->VT = tempbx;
2787                return;
2788        }
2789}
2790
2791static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
2792                unsigned short RefreshRateTableIndex,
2793                struct vb_device_info *pVBInfo)
2794{
2795        unsigned char di_0, di_1, tempal;
2796
2797        tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex,
2798                        pVBInfo);
2799        XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
2800        XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
2801
2802        if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */
2803                /* 301 */
2804                xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10);
2805                xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
2806                xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
2807        } else { /* 301b/302b/301lv/302lv */
2808                xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0);
2809                xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
2810        }
2811
2812        xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12);
2813
2814        if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
2815                xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28);
2816        else
2817                xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08);
2818}
2819
2820static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
2821                unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
2822{
2823        unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
2824        short index;
2825        unsigned short modeflag;
2826
2827        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2828        index = (modeflag & ModeTypeMask) - ModeEGA;
2829
2830        if (index < 0)
2831                index = 0;
2832
2833        return ColorDepth[index];
2834}
2835
2836static unsigned short XGI_GetOffset(unsigned short ModeNo,
2837                                    unsigned short ModeIdIndex,
2838                unsigned short RefreshRateTableIndex,
2839                struct xgi_hw_device_info *HwDeviceExtension,
2840                struct vb_device_info *pVBInfo)
2841{
2842        unsigned short temp, colordepth, modeinfo, index, infoflag,
2843                        ColorDepth[] = { 0x01, 0x02, 0x04 };
2844
2845        modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
2846        infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
2847
2848        index = (modeinfo >> 8) & 0xFF;
2849
2850        temp = XGI330_ScreenOffset[index];
2851
2852        if (infoflag & InterlaceMode)
2853                temp = temp << 1;
2854
2855        colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
2856
2857        if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) {
2858                temp = ModeNo - 0x7C;
2859                colordepth = ColorDepth[temp];
2860                temp = 0x6B;
2861                if (infoflag & InterlaceMode)
2862                        temp = temp << 1;
2863        }
2864        return temp * colordepth;
2865}
2866
2867static void XGI_SetCRT2Offset(unsigned short ModeNo,
2868                unsigned short ModeIdIndex,
2869                unsigned short RefreshRateTableIndex,
2870                struct xgi_hw_device_info *HwDeviceExtension,
2871                struct vb_device_info *pVBInfo)
2872{
2873        unsigned short offset;
2874        unsigned char temp;
2875
2876        if (pVBInfo->VBInfo & SetInSlaveMode)
2877                return;
2878
2879        offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
2880                        HwDeviceExtension, pVBInfo);
2881        temp = (unsigned char) (offset & 0xFF);
2882        xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
2883        temp = (unsigned char) ((offset & 0xFF00) >> 8);
2884        xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp);
2885        temp = (unsigned char) (((offset >> 3) & 0xFF) + 1);
2886        xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
2887}
2888
2889static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
2890{
2891        /* threshold high ,disable auto threshold */
2892        xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B);
2893        /* threshold low default 04h */
2894        xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04);
2895}
2896
2897static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
2898                struct xgi_hw_device_info *HwDeviceExtension,
2899                unsigned short RefreshRateTableIndex,
2900                struct vb_device_info *pVBInfo)
2901{
2902        u8 tempcx;
2903
2904        XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
2905                        HwDeviceExtension, pVBInfo);
2906        XGI_SetCRT2FIFO(pVBInfo);
2907
2908        for (tempcx = 4; tempcx < 7; tempcx++)
2909                xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0);
2910
2911        xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00);
2912        xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
2913}
2914
2915static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
2916                struct xgi_hw_device_info *HwDeviceExtension,
2917                unsigned short RefreshRateTableIndex,
2918                struct vb_device_info *pVBInfo)
2919{
2920        unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0,
2921                        pushbx = 0, CRT1Index, modeflag;
2922
2923        CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
2924        CRT1Index &= IndexMask;
2925        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
2926
2927        /* bainy change table name */
2928        if (modeflag & HalfDCLK) {
2929                /* BTVGA2HT 0x08,0x09 */
2930                temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF;
2931                xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
2932                temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
2933                xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
2934                /* BTVGA2HDEE 0x0A,0x0C */
2935                temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF;
2936                xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
2937                tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
2938                pushbx = pVBInfo->VGAHDE / 2 + 16;
2939                tempcx = tempcx >> 1;
2940                tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
2941                tempcx += tempbx;
2942
2943                if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
2944                        tempbx = XGI_CRT1Table[CRT1Index].CR[4];
2945                        tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] &
2946                                                0xC0) << 2);
2947                        tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
2948                        tempcx = XGI_CRT1Table[CRT1Index].CR[5];
2949                        tempcx &= 0x1F;
2950                        temp = XGI_CRT1Table[CRT1Index].CR[15];
2951                        temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
2952                        tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
2953                }
2954
2955                tempbx += 4;
2956                tempcx += 4;
2957
2958                if (tempcx > (pVBInfo->VGAHT / 2))
2959                        tempcx = pVBInfo->VGAHT / 2;
2960
2961                temp = tempbx & 0x00FF;
2962
2963                xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
2964        } else {
2965                temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
2966                xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
2967                temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
2968                xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
2969                /* BTVGA2HDEE 0x0A,0x0C */
2970                temp = (pVBInfo->VGAHDE + 16) & 0x0FF;
2971                xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
2972                tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
2973                pushbx = pVBInfo->VGAHDE + 16;
2974                tempcx = tempcx >> 1;
2975                tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
2976                tempcx += tempbx;
2977
2978                if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
2979                        tempbx = XGI_CRT1Table[CRT1Index].CR[3];
2980                        tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] &
2981                                                0xC0) << 2);
2982                        tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
2983                        tempcx = XGI_CRT1Table[CRT1Index].CR[4];
2984                        tempcx &= 0x1F;
2985                        temp = XGI_CRT1Table[CRT1Index].CR[6];
2986                        temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
2987                        tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
2988                        tempbx += 16;
2989                        tempcx += 16;
2990                }
2991
2992                if (tempcx > pVBInfo->VGAHT)
2993                        tempcx = pVBInfo->VGAHT;
2994
2995                temp = tempbx & 0x00FF;
2996                xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
2997        }
2998
2999        tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
3000        tempbx = pushbx;
3001        tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
3002        tempax |= (tempbx & 0xFF00);
3003        temp = (tempax & 0xFF00) >> 8;
3004        xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
3005        temp = tempcx & 0x00FF;
3006        xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
3007        tempcx = (pVBInfo->VGAVT - 1);
3008        temp = tempcx & 0x00FF;
3009
3010        xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
3011        tempbx = pVBInfo->VGAVDE - 1;
3012        temp = tempbx & 0x00FF;
3013        xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp);
3014        temp = ((tempbx & 0xFF00) << 3) >> 8;
3015        temp |= ((tempcx & 0xFF00) >> 8);
3016        xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp);
3017
3018        tempax = pVBInfo->VGAVDE;
3019        tempbx = pVBInfo->VGAVDE;
3020        tempcx = pVBInfo->VGAVT;
3021        /* BTVGA2VRS 0x10,0x11 */
3022        tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1;
3023        /* BTVGA2VRE 0x11 */
3024        tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1;
3025
3026        if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
3027                tempbx = XGI_CRT1Table[CRT1Index].CR[10];
3028                temp = XGI_CRT1Table[CRT1Index].CR[9];
3029
3030                if (temp & 0x04)
3031                        tempbx |= 0x0100;
3032
3033                if (temp & 0x080)
3034                        tempbx |= 0x0200;
3035
3036                temp = XGI_CRT1Table[CRT1Index].CR[14];
3037
3038                if (temp & 0x08)
3039                        tempbx |= 0x0400;
3040
3041                temp = XGI_CRT1Table[CRT1Index].CR[11];
3042                tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
3043        }
3044
3045        temp = tempbx & 0x00FF;
3046        xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3047        temp = ((tempbx & 0xFF00) >> 8) << 4;
3048        temp = ((tempcx & 0x000F) | (temp));
3049        xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp);
3050        tempax = 0;
3051
3052        if (modeflag & DoubleScanMode)
3053                tempax |= 0x80;
3054
3055        if (modeflag & HalfDCLK)
3056                tempax |= 0x40;
3057
3058        xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
3059}
3060
3061static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo)
3062{
3063        unsigned long tempax, tempbx;
3064
3065        tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX)
3066                        & 0xFFFF;
3067        tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
3068        tempax = (tempax * pVBInfo->HT) / tempbx;
3069
3070        return (unsigned short) tempax;
3071}
3072
3073static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
3074                struct xgi_hw_device_info *HwDeviceExtension,
3075                unsigned short RefreshRateTableIndex,
3076                struct vb_device_info *pVBInfo)
3077{
3078        unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo,
3079                        modeflag;
3080
3081        /* si+Ext_ResInfo */
3082        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3083        resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
3084
3085        if (!(pVBInfo->VBInfo & SetInSlaveMode))
3086                return;
3087
3088        temp = 0xFF; /* set MAX HT */
3089        xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
3090        tempcx = 0x08;
3091
3092        if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
3093                modeflag |= Charx8Dot;
3094
3095        tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
3096
3097        if (modeflag & HalfDCLK)
3098                tempax = tempax >> 1;
3099
3100        tempax = (tempax / tempcx) - 1;
3101        tempbx |= ((tempax & 0x00FF) << 8);
3102        temp = tempax & 0x00FF;
3103        xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp);
3104
3105        temp = (tempbx & 0xFF00) >> 8;
3106
3107        if (pVBInfo->VBInfo & SetCRT2ToTV) {
3108                if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3109                                | VB_SIS302LV | VB_XGI301C)))
3110                        temp += 2;
3111
3112                if ((pVBInfo->VBInfo & SetCRT2ToHiVision) &&
3113                    !(pVBInfo->VBType & VB_SIS301LV) && (resinfo == 7))
3114                                temp -= 2;
3115        }
3116
3117        /* 0x05 Horizontal Display Start */
3118        xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp);
3119        /* 0x06 Horizontal Blank end */
3120        xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03);
3121
3122        if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
3123                if (pVBInfo->VBInfo & SetCRT2ToTV)
3124                        tempax = pVBInfo->VGAHT;
3125                else
3126                        tempax = XGI_GetVGAHT2(pVBInfo);
3127        }
3128
3129        if (tempax >= pVBInfo->VGAHT)
3130                tempax = pVBInfo->VGAHT;
3131
3132        if (modeflag & HalfDCLK)
3133                tempax = tempax >> 1;
3134
3135        tempax = (tempax / tempcx) - 5;
3136        tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
3137        if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3138                temp = (tempbx & 0x00FF) - 1;
3139                if (!(modeflag & HalfDCLK)) {
3140                        temp -= 6;
3141                        if (pVBInfo->TVInfo & TVSimuMode) {
3142                                temp -= 4;
3143                                temp -= 10;
3144                        }
3145                }
3146        } else {
3147                tempbx = (tempbx & 0xFF00) >> 8;
3148                tempcx = (tempcx + tempbx) >> 1;
3149                temp = (tempcx & 0x00FF) + 2;
3150
3151                if (pVBInfo->VBInfo & SetCRT2ToTV) {
3152                        temp -= 1;
3153                        if (!(modeflag & HalfDCLK)) {
3154                                if ((modeflag & Charx8Dot)) {
3155                                        temp += 4;
3156                                        if (pVBInfo->VGAHDE >= 800)
3157                                                temp -= 6;
3158                                }
3159                        }
3160                } else if (!(modeflag & HalfDCLK)) {
3161                        temp -= 4;
3162                        if (pVBInfo->LCDResInfo != Panel_1280x960 &&
3163                            pVBInfo->VGAHDE >= 800) {
3164                                temp -= 7;
3165                                if (pVBInfo->VGAHDE >= 1280 &&
3166                                    pVBInfo->LCDResInfo != Panel_1280x960 &&
3167                                    (pVBInfo->LCDInfo & LCDNonExpanding))
3168                                        temp += 28;
3169                        }
3170                }
3171        }
3172
3173        /* 0x07 Horizontal Retrace Start */
3174        xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
3175        /* 0x08 Horizontal Retrace End */
3176        xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0);
3177
3178        if (pVBInfo->VBInfo & SetCRT2ToTV) {
3179                if (pVBInfo->TVInfo & TVSimuMode) {
3180                        if (ModeNo == 0x50) {
3181                                if (pVBInfo->TVInfo & SetNTSCTV) {
3182                                        xgifb_reg_set(pVBInfo->Part1Port,
3183                                                        0x07, 0x30);
3184                                        xgifb_reg_set(pVBInfo->Part1Port,
3185                                                        0x08, 0x03);
3186                                } else {
3187                                        xgifb_reg_set(pVBInfo->Part1Port,
3188                                                        0x07, 0x2f);
3189                                        xgifb_reg_set(pVBInfo->Part1Port,
3190                                                        0x08, 0x02);
3191                                }
3192                        }
3193                }
3194        }
3195
3196        xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
3197        xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
3198        xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
3199
3200        tempbx = pVBInfo->VGAVT;
3201        push1 = tempbx;
3202        tempcx = 0x121;
3203        tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
3204
3205        if (tempbx == 357)
3206                tempbx = 350;
3207        if (tempbx == 360)
3208                tempbx = 350;
3209        if (tempbx == 375)
3210                tempbx = 350;
3211        if (tempbx == 405)
3212                tempbx = 400;
3213        if (tempbx == 525)
3214                tempbx = 480;
3215
3216        push2 = tempbx;
3217
3218        if (pVBInfo->VBInfo & SetCRT2ToLCD) {
3219                if (pVBInfo->LCDResInfo == Panel_1024x768) {
3220                        if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3221                                if (tempbx == 350)
3222                                        tempbx += 5;
3223                                if (tempbx == 480)
3224                                        tempbx += 5;
3225                        }
3226                }
3227        }
3228        tempbx--;
3229        temp = tempbx & 0x00FF;
3230        tempbx--;
3231        temp = tempbx & 0x00FF;
3232        /* 0x10 vertical Blank Start */
3233        xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3234        tempbx = push2;
3235        tempbx--;
3236        temp = tempbx & 0x00FF;
3237        xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp);
3238
3239        if (tempbx & 0x0100)
3240                tempcx |= 0x0002;
3241
3242        tempax = 0x000B;
3243
3244        if (modeflag & DoubleScanMode)
3245                tempax |= 0x08000;
3246
3247        if (tempbx & 0x0200)
3248                tempcx |= 0x0040;
3249
3250        temp = (tempax & 0xFF00) >> 8;
3251        xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp);
3252
3253        if (tempbx & 0x0400)
3254                tempcx |= 0x0600;
3255
3256        /* 0x11 Vertival Blank End */
3257        xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00);
3258
3259        tempax = push1;
3260        tempax -= tempbx; /* 0x0C Vertical Retrace Start */
3261        tempax = tempax >> 2;
3262        push1 = tempax; /* push ax */
3263
3264        if (resinfo != 0x09) {
3265                tempax = tempax << 1;
3266                tempbx += tempax;
3267        }
3268
3269        if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3270                if ((pVBInfo->VBType & VB_SIS301LV) &&
3271                    !(pVBInfo->TVInfo & TVSetHiVision)) {
3272                        if ((pVBInfo->TVInfo & TVSimuMode) &&
3273                            (pVBInfo->TVInfo & TVSetPAL)) {
3274                                if (!(pVBInfo->VBType & VB_SIS301LV) ||
3275                                    !(pVBInfo->TVInfo &
3276                                      (TVSetYPbPr525p |
3277                                       TVSetYPbPr750p |
3278                                       TVSetHiVision)))
3279                                        tempbx += 40;
3280                        }
3281                } else {
3282                        tempbx -= 10;
3283                }
3284        } else if (pVBInfo->TVInfo & TVSimuMode) {
3285                if (pVBInfo->TVInfo & TVSetPAL) {
3286                        if (pVBInfo->VBType & VB_SIS301LV) {
3287                                if (!(pVBInfo->TVInfo &
3288                                    (TVSetYPbPr525p |
3289                                     TVSetYPbPr750p |
3290                                     TVSetHiVision)))
3291                                        tempbx += 40;
3292                        } else {
3293                                tempbx += 40;
3294                        }
3295                }
3296        }
3297        tempax = push1;
3298        tempax = tempax >> 2;
3299        tempax++;
3300        tempax += tempbx;
3301        push1 = tempax; /* push ax */
3302
3303        if ((pVBInfo->TVInfo & TVSetPAL)) {
3304                if (tempbx <= 513) {
3305                        if (tempax >= 513)
3306                                tempbx = 513;
3307                }
3308        }
3309
3310        temp = tempbx & 0x00FF;
3311        xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp);
3312        tempbx--;
3313        temp = tempbx & 0x00FF;
3314        xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
3315
3316        if (tempbx & 0x0100)
3317                tempcx |= 0x0008;
3318
3319        if (tempbx & 0x0200)
3320                xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
3321
3322        tempbx++;
3323
3324        if (tempbx & 0x0100)
3325                tempcx |= 0x0004;
3326
3327        if (tempbx & 0x0200)
3328                tempcx |= 0x0080;
3329
3330        if (tempbx & 0x0400)
3331                tempcx |= 0x0C00;
3332
3333        tempbx = push1; /* pop ax */
3334        temp = tempbx & 0x00FF;
3335        temp &= 0x0F;
3336        /* 0x0D vertical Retrace End */
3337        xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
3338
3339        if (tempbx & 0x0010)
3340                tempcx |= 0x2000;
3341
3342        temp = tempcx & 0x00FF;
3343        xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
3344        temp = (tempcx & 0x0FF00) >> 8;
3345        xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
3346        tempax = modeflag;
3347        temp = (tempax & 0xFF00) >> 8;
3348
3349        temp = (temp >> 1) & 0x09;
3350
3351        if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
3352                temp |= 0x01;
3353
3354        xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
3355        xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
3356        xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
3357
3358        if (pVBInfo->LCDInfo & LCDRGB18Bit)
3359                temp = 0x80;
3360        else
3361                temp = 0x00;
3362
3363        xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
3364
3365        return;
3366}
3367
3368static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
3369                unsigned short RefreshRateTableIndex,
3370                struct xgi_hw_device_info *HwDeviceExtension,
3371                struct vb_device_info *pVBInfo)
3372{
3373        unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2,
3374                        modeflag;
3375        unsigned char const *TimingPoint;
3376
3377        unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
3378
3379        /* si+Ext_ResInfo */
3380        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
3381
3382        tempax = 0;
3383
3384        if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
3385                tempax |= 0x0800;
3386
3387        if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3388                tempax |= 0x0400;
3389
3390        if (pVBInfo->VBInfo & SetCRT2ToSCART)
3391                tempax |= 0x0200;
3392
3393        if (!(pVBInfo->TVInfo & TVSetPAL))
3394                tempax |= 0x1000;
3395
3396        if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3397                tempax |= 0x0100;
3398
3399        if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
3400                tempax &= 0xfe00;
3401
3402        tempax = (tempax & 0xff00) >> 8;
3403
3404        xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax);
3405        TimingPoint = XGI330_NTSCTiming;
3406
3407        if (pVBInfo->TVInfo & TVSetPAL)
3408                TimingPoint = XGI330_PALTiming;
3409
3410        if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3411                TimingPoint = XGI330_HiTVExtTiming;
3412
3413                if (pVBInfo->VBInfo & SetInSlaveMode)
3414                        TimingPoint = XGI330_HiTVSt2Timing;
3415
3416                if (pVBInfo->SetFlag & TVSimuMode)
3417                        TimingPoint = XGI330_HiTVSt1Timing;
3418
3419                if (!(modeflag & Charx8Dot))
3420                        TimingPoint = XGI330_HiTVTextTiming;
3421        }
3422
3423        if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3424                if (pVBInfo->TVInfo & TVSetYPbPr525i)
3425                        TimingPoint = XGI330_YPbPr525iTiming;
3426
3427                if (pVBInfo->TVInfo & TVSetYPbPr525p)
3428                        TimingPoint = XGI330_YPbPr525pTiming;
3429
3430                if (pVBInfo->TVInfo & TVSetYPbPr750p)
3431                        TimingPoint = XGI330_YPbPr750pTiming;
3432        }
3433
3434        for (i = 0x01, j = 0; i <= 0x2D; i++, j++)
3435                xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
3436
3437        for (i = 0x39; i <= 0x45; i++, j++)
3438                /* di->temp2[j] */
3439                xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
3440
3441        if (pVBInfo->VBInfo & SetCRT2ToTV)
3442                xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
3443
3444        temp = pVBInfo->NewFlickerMode;
3445        temp &= 0x80;
3446        xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
3447
3448        if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3449                tempax = 950;
3450
3451        if (pVBInfo->TVInfo & TVSetPAL)
3452                tempax = 520;
3453        else
3454                tempax = 440;
3455
3456        if (pVBInfo->VDE <= tempax) {
3457                tempax -= pVBInfo->VDE;
3458                tempax = tempax >> 2;
3459                tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
3460                push1 = tempax;
3461                temp = (tempax & 0xFF00) >> 8;
3462                temp += (unsigned short) TimingPoint[0];
3463
3464                if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3465                                | VB_SIS302LV | VB_XGI301C)) {
3466                        if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
3467                                        | SetCRT2ToSVIDEO | SetCRT2ToSCART
3468                                        | SetCRT2ToYPbPr525750)) {
3469                                tempcx = pVBInfo->VGAHDE;
3470                                if (tempcx >= 1024) {
3471                                        temp = 0x17; /* NTSC */
3472                                        if (pVBInfo->TVInfo & TVSetPAL)
3473                                                temp = 0x19; /* PAL */
3474                                }
3475                        }
3476                }
3477
3478                xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
3479                tempax = push1;
3480                temp = (tempax & 0xFF00) >> 8;
3481                temp += TimingPoint[1];
3482
3483                if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3484                                | VB_SIS302LV | VB_XGI301C)) {
3485                        if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
3486                                        | SetCRT2ToSVIDEO | SetCRT2ToSCART
3487                                        | SetCRT2ToYPbPr525750))) {
3488                                tempcx = pVBInfo->VGAHDE;
3489                                if (tempcx >= 1024) {
3490                                        temp = 0x1D; /* NTSC */
3491                                        if (pVBInfo->TVInfo & TVSetPAL)
3492                                                temp = 0x52; /* PAL */
3493                                }
3494                        }
3495                }
3496                xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp);
3497        }
3498
3499        /* 301b */
3500        tempcx = pVBInfo->HT;
3501
3502        if (XGI_IsLCDDualLink(pVBInfo))
3503                tempcx = tempcx >> 1;
3504
3505        tempcx -= 2;
3506        temp = tempcx & 0x00FF;
3507        xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp);
3508
3509        temp = (tempcx & 0xFF00) >> 8;
3510        xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
3511
3512        tempcx = pVBInfo->HT >> 1;
3513        push1 = tempcx; /* push cx */
3514        tempcx += 7;
3515
3516        if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3517                tempcx -= 4;
3518
3519        temp = tempcx & 0x00FF;
3520        temp = temp << 4;
3521        xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp);
3522
3523        tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
3524        tempbx += tempcx;
3525        push2 = tempbx;
3526        temp = tempbx & 0x00FF;
3527        xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp);
3528        temp = (tempbx & 0xFF00) >> 8;
3529        temp = temp << 4;
3530        xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp);
3531
3532        tempbx = push2;
3533        tempbx = tempbx + 8;
3534        if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3535                tempbx = tempbx - 4;
3536                tempcx = tempbx;
3537        }
3538
3539        temp = (tempbx & 0x00FF) << 4;
3540        xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp);
3541
3542        j += 2;
3543        tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
3544        temp = tempcx & 0x00FF;
3545        xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp);
3546        temp = ((tempcx & 0xFF00) >> 8) << 4;
3547        xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp);
3548
3549        tempcx += 8;
3550        if (pVBInfo->VBInfo & SetCRT2ToHiVision)
3551                tempcx -= 4;
3552
3553        temp = tempcx & 0xFF;
3554        temp = temp << 4;
3555        xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp);
3556
3557        tempcx = push1; /* pop cx */
3558        j += 2;
3559        temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
3560        tempcx -= temp;
3561        temp = tempcx & 0x00FF;
3562        temp = temp << 4;
3563        xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp);
3564
3565        tempcx -= 11;
3566
3567        if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
3568                tempax = XGI_GetVGAHT2(pVBInfo);
3569                tempcx = tempax - 1;
3570        }
3571        temp = tempcx & 0x00FF;
3572        xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp);
3573
3574        tempbx = pVBInfo->VDE;
3575
3576        if (pVBInfo->VGAVDE == 360)
3577                tempbx = 746;
3578        if (pVBInfo->VGAVDE == 375)
3579                tempbx = 746;
3580        if (pVBInfo->VGAVDE == 405)
3581                tempbx = 853;
3582
3583        if (pVBInfo->VBInfo & SetCRT2ToTV) {
3584                if (pVBInfo->VBType &
3585                    (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
3586                        if (!(pVBInfo->TVInfo &
3587                            (TVSetYPbPr525p | TVSetYPbPr750p)))
3588                                tempbx = tempbx >> 1;
3589                } else
3590                        tempbx = tempbx >> 1;
3591        }
3592
3593        tempbx -= 2;
3594        temp = tempbx & 0x00FF;
3595
3596        if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3597                if (pVBInfo->VBType & VB_SIS301LV) {
3598                        if (pVBInfo->TVInfo & TVSetHiVision) {
3599                                if (pVBInfo->VBInfo & SetInSlaveMode) {
3600                                        if (ModeNo == 0x2f)
3601                                                temp += 1;
3602                                }
3603                        }
3604                } else if (pVBInfo->VBInfo & SetInSlaveMode) {
3605                        if (ModeNo == 0x2f)
3606                                temp += 1;
3607                }
3608        }
3609
3610        xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp);
3611
3612        temp = (tempcx & 0xFF00) >> 8;
3613        temp |= ((tempbx & 0xFF00) >> 8) << 6;
3614
3615        if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
3616                if (pVBInfo->VBType & VB_SIS301LV) {
3617                        if (pVBInfo->TVInfo & TVSetHiVision) {
3618                                temp |= 0x10;
3619
3620                                if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3621                                        temp |= 0x20;
3622                        }
3623                } else {
3624                        temp |= 0x10;
3625                        if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
3626                                temp |= 0x20;
3627                }
3628        }
3629
3630        xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp);
3631
3632        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3633                        | VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */
3634                tempbx = pVBInfo->VDE;
3635                tempcx = tempbx - 2;
3636
3637                if (pVBInfo->VBInfo & SetCRT2ToTV) {
3638                        if (!(pVBInfo->TVInfo & (TVSetYPbPr525p
3639                                        | TVSetYPbPr750p)))
3640                                tempbx = tempbx >> 1;
3641                }
3642
3643                if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
3644                        temp = 0;
3645                        if (tempcx & 0x0400)
3646                                temp |= 0x20;
3647
3648                        if (tempbx & 0x0400)
3649                                temp |= 0x40;
3650
3651                        xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp);
3652                }
3653
3654                temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
3655                xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp);
3656                temp = (tempbx - 3) & 0x00FF;
3657                xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp);
3658        }
3659
3660        tempbx = tempbx & 0x00FF;
3661
3662        if (!(modeflag & HalfDCLK)) {
3663                tempcx = pVBInfo->VGAHDE;
3664                if (tempcx >= pVBInfo->HDE) {
3665                        tempbx |= 0x2000;
3666                        tempax &= 0x00FF;
3667                }
3668        }
3669
3670        tempcx = 0x0101;
3671
3672        if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/
3673                if (pVBInfo->VGAHDE >= 1024) {
3674                        tempcx = 0x1920;
3675                        if (pVBInfo->VGAHDE >= 1280) {
3676                                tempcx = 0x1420;
3677                                tempbx = tempbx & 0xDFFF;
3678                        }
3679                }
3680        }
3681
3682        if (!(tempbx & 0x2000)) {
3683                if (modeflag & HalfDCLK)
3684                        tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
3685
3686                push1 = tempbx;
3687                tempeax = pVBInfo->VGAHDE;
3688                tempebx = (tempcx & 0xFF00) >> 8;
3689                longtemp = tempeax * tempebx;
3690                tempecx = tempcx & 0x00FF;
3691                longtemp = longtemp / tempecx;
3692
3693                /* 301b */
3694                tempecx = 8 * 1024;
3695
3696                if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3697                                | VB_SIS302LV | VB_XGI301C)) {
3698                        tempecx = tempecx * 8;
3699                }
3700
3701                longtemp = longtemp * tempecx;
3702                tempecx = pVBInfo->HDE;
3703                temp2 = longtemp % tempecx;
3704                tempeax = longtemp / tempecx;
3705                if (temp2 != 0)
3706                        tempeax += 1;
3707
3708                tempax = (unsigned short) tempeax;
3709
3710                /* 301b */
3711                if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
3712                                | VB_SIS302LV | VB_XGI301C)) {
3713                        tempcx = ((tempax & 0xFF00) >> 5) >> 8;
3714                }
3715                /* end 301b */
3716
3717                tempbx = push1;
3718                tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00)
3719                                | (tempbx & 0x00FF));
3720                tempax = (unsigned short) (((tempeax & 0x000000FF) << 8)
3721                                | (tempax & 0x00FF));
3722                temp = (tempax & 0xFF00) >> 8;
3723        } else {
3724                temp = (tempax & 0x00FF) >> 8;
3725        }
3726
3727        xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp);
3728        temp = (tempbx & 0xFF00) >> 8;
3729        xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp);
3730        temp = tempcx & 0x00FF;
3731
3732        if (tempbx & 0x2000)
3733                temp = 0;
3734
3735        if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
3736                temp |= 0x18;
3737
3738        xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
3739        if (pVBInfo->TVInfo & TVSetPAL) {
3740                tempbx = 0x0382;
3741                tempcx = 0x007e;
3742        } else {
3743                tempbx = 0x0369;
3744                tempcx = 0x0061;
3745        }
3746
3747        temp = tempbx & 0x00FF;
3748        xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp);
3749        temp = tempcx & 0x00FF;
3750        xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp);
3751
3752        temp = ((tempcx & 0xFF00) >> 8) & 0x03;
3753        temp = temp << 2;
3754        temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
3755
3756        if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
3757                temp |= 0x10;
3758
3759                if (pVBInfo->TVInfo & TVSetYPbPr525p)
3760                        temp |= 0x20;
3761
3762                if (pVBInfo->TVInfo & TVSetYPbPr750p)
3763                        temp |= 0x60;
3764        }
3765
3766        xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp);
3767        temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */
3768        xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
3769
3770        if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) {
3771                if (pVBInfo->TVInfo & NTSC1024x768) {
3772                        TimingPoint = XGI_NTSC1024AdjTime;
3773                        for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
3774                                xgifb_reg_set(pVBInfo->Part2Port, i,
3775                                                TimingPoint[j]);
3776                        }
3777                        xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72);
3778                }
3779        }
3780
3781        /* Modify for 301C PALM Support */
3782        if (pVBInfo->VBType & VB_XGI301C) {
3783                if (pVBInfo->TVInfo & TVSetPALM)
3784                        xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08,
3785                                        0x08); /* PALM Mode */
3786        }
3787
3788        if (pVBInfo->TVInfo & TVSetPALM) {
3789                tempax = xgifb_reg_get(pVBInfo->Part2Port, 0x01);
3790                tempax--;
3791                xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax);
3792
3793                xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF);
3794        }
3795
3796        if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
3797                if (!(pVBInfo->VBInfo & SetInSlaveMode))
3798                        xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00);
3799        }
3800
3801        if (pVBInfo->VBInfo & SetCRT2ToTV)
3802                return;
3803}
3804
3805static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
3806                struct xgi_hw_device_info *HwDeviceExtension,
3807                unsigned short RefreshRateTableIndex,
3808                struct vb_device_info *pVBInfo)
3809{
3810        unsigned short pushbx, tempax, tempbx, tempcx, temp, tempah,
3811                        tempbh, tempch;
3812
3813        struct XGI_LCDDesStruct const *LCDBDesPtr = NULL;
3814
3815        /* si+Ext_ResInfo */
3816        if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
3817                return;
3818
3819        tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
3820
3821        if (XGI_IsLCDDualLink(pVBInfo))
3822                tempbx = tempbx >> 1;
3823
3824        tempbx -= 1;
3825        temp = tempbx & 0x00FF;
3826        xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp);
3827        temp = (tempbx & 0xFF00) >> 8;
3828        temp = temp << 4;
3829        xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
3830        temp = 0x01;
3831
3832        xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp);
3833        tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
3834        tempbx--;
3835        temp = tempbx & 0x00FF;
3836        xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp);
3837        temp = ((tempbx & 0xFF00) >> 8) & 0x07;
3838        xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp);
3839
3840        tempcx = pVBInfo->VT - 1;
3841        temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
3842        xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp);
3843        temp = (tempcx & 0xFF00) >> 8;
3844        temp = temp << 5;
3845        xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp);
3846        xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
3847        xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
3848        xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
3849        xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
3850
3851        /* Customized LCDB Does not add */
3852        if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
3853                LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeNo, ModeIdIndex,
3854                                           RefreshRateTableIndex, pVBInfo);
3855        else
3856                LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeNo,
3857                                           ModeIdIndex, RefreshRateTableIndex,
3858                                           pVBInfo);
3859
3860        tempah = pVBInfo->LCDResInfo;
3861        tempah &= PanelResInfo;
3862
3863        if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) {
3864                tempbx = 1024;
3865                tempcx = 768;
3866        } else if ((tempah == Panel_1280x1024) ||
3867                   (tempah == Panel_1280x1024x75)) {
3868                tempbx = 1280;
3869                tempcx = 1024;
3870        } else if (tempah == Panel_1400x1050) {
3871                tempbx = 1400;
3872                tempcx = 1050;
3873        } else {
3874                tempbx = 1600;
3875                tempcx = 1200;
3876        }
3877
3878        if (pVBInfo->LCDInfo & EnableScalingLCD) {
3879                tempbx = pVBInfo->HDE;
3880                tempcx = pVBInfo->VDE;
3881        }
3882
3883        pushbx = tempbx;
3884        tempax = pVBInfo->VT;
3885        pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
3886        pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
3887        pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
3888        pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
3889        tempbx = pVBInfo->LCDVDES;
3890        tempcx += tempbx;
3891
3892        if (tempcx >= tempax)
3893                tempcx -= tempax; /* lcdvdes */
3894
3895        temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
3896        xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp);
3897        temp = tempcx & 0x00FF;
3898        xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp);
3899        tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
3900        tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
3901        tempah = tempch;
3902        tempah = tempah << 3;
3903        tempah |= tempbh;
3904        xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah);
3905
3906        /* getlcdsync() */
3907        XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
3908        tempcx = tempbx;
3909        tempax = pVBInfo->VT;
3910        tempbx = pVBInfo->LCDVRS;
3911
3912        tempcx += tempbx;
3913        if (tempcx >= tempax)
3914                tempcx -= tempax;
3915
3916        temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
3917        xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp);
3918        temp = (tempbx & 0xFF00) >> 8;
3919        temp = temp << 4;
3920        temp |= (tempcx & 0x000F);
3921        xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp);
3922        tempcx = pushbx;
3923        tempax = pVBInfo->HT;
3924        tempbx = pVBInfo->LCDHDES;
3925        tempbx &= 0x0FFF;
3926
3927        if (XGI_IsLCDDualLink(pVBInfo)) {
3928                tempax = tempax >> 1;
3929                tempbx = tempbx >> 1;
3930                tempcx = tempcx >> 1;
3931        }
3932
3933        if (pVBInfo->VBType & VB_SIS302LV)
3934                tempbx += 1;
3935
3936        if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
3937                tempbx += 1;
3938
3939        tempcx += tempbx;
3940
3941        if (tempcx >= tempax)
3942                tempcx -= tempax;
3943
3944        temp = tempbx & 0x00FF;
3945        xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
3946        temp = ((tempbx & 0xFF00) >> 8) << 4;
3947        xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp);
3948        temp = tempcx & 0x00FF;
3949        xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
3950        temp = (tempcx & 0xFF00) >> 8;
3951        xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp);
3952
3953        XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
3954        tempcx = tempax;
3955        tempax = pVBInfo->HT;
3956        tempbx = pVBInfo->LCDHRS;
3957        if (XGI_IsLCDDualLink(pVBInfo)) {
3958                tempax = tempax >> 1;
3959                tempbx = tempbx >> 1;
3960                tempcx = tempcx >> 1;
3961        }
3962
3963        if (pVBInfo->VBType & VB_SIS302LV)
3964                tempbx += 1;
3965
3966        tempcx += tempbx;
3967
3968        if (tempcx >= tempax)
3969                tempcx -= tempax;
3970
3971        temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
3972        xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp);
3973
3974        temp = (tempbx & 0xFF00) >> 8;
3975        temp = temp << 4;
3976        xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
3977        temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
3978        xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp);
3979
3980        if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
3981                if (pVBInfo->VGAVDE == 525) {
3982                        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
3983                                        | VB_SIS301LV | VB_SIS302LV
3984                                        | VB_XGI301C)) {
3985                                temp = 0xC6;
3986                        } else
3987                                temp = 0xC4;
3988
3989                        xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
3990                        xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3);
3991                }
3992
3993                if (pVBInfo->VGAVDE == 420) {
3994                        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
3995                                        | VB_SIS301LV | VB_SIS302LV
3996                                        | VB_XGI301C)) {
3997                                temp = 0x4F;
3998                        } else
3999                                temp = 0x4E;
4000                        xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp);
4001                }
4002        }
4003}
4004
4005/* --------------------------------------------------------------------- */
4006/* Function : XGI_GetTap4Ptr */
4007/* Input : */
4008/* Output : di -> Tap4 Reg. Setting Pointer */
4009/* Description : */
4010/* --------------------------------------------------------------------- */
4011static struct XGI301C_Tap4TimingStruct const
4012*XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo)
4013{
4014        unsigned short tempax, tempbx, i;
4015        struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
4016
4017        if (tempcx == 0) {
4018                tempax = pVBInfo->VGAHDE;
4019                tempbx = pVBInfo->HDE;
4020        } else {
4021                tempax = pVBInfo->VGAVDE;
4022                tempbx = pVBInfo->VDE;
4023        }
4024
4025        if (tempax <= tempbx)
4026                return &xgifb_tap4_timing[0];
4027        else
4028                Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */
4029
4030        if (pVBInfo->TVInfo & TVSetPAL)
4031                Tap4TimingPtr = PALTap4Timing;
4032
4033        if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
4034                if ((pVBInfo->TVInfo & TVSetYPbPr525i) ||
4035                        (pVBInfo->TVInfo & TVSetYPbPr525p))
4036                        Tap4TimingPtr = xgifb_ntsc_525_tap4_timing;
4037                if (pVBInfo->TVInfo & TVSetYPbPr750p)
4038                        Tap4TimingPtr = YPbPr750pTap4Timing;
4039        }
4040
4041        if (pVBInfo->VBInfo & SetCRT2ToHiVision)
4042                Tap4TimingPtr = xgifb_tap4_timing;
4043
4044        i = 0;
4045        while (Tap4TimingPtr[i].DE != 0xFFFF) {
4046                if (Tap4TimingPtr[i].DE == tempax)
4047                        break;
4048                i++;
4049        }
4050        return &Tap4TimingPtr[i];
4051}
4052
4053static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
4054{
4055        unsigned short i, j;
4056        struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr;
4057
4058        if (!(pVBInfo->VBType & VB_XGI301C))
4059                return;
4060
4061        Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
4062        for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
4063                xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
4064
4065        if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
4066            (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) {
4067                /* Set Vertical Scaling */
4068                Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
4069                for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
4070                        xgifb_reg_set(pVBInfo->Part2Port,
4071                                      i,
4072                                      Tap4TimingPtr->Reg[j]);
4073        }
4074
4075        if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
4076            (!(pVBInfo->VBInfo & SetCRT2ToHiVision)))
4077                /* Enable V.Scaling */
4078                xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
4079        else
4080                /* Enable H.Scaling */
4081                xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10);
4082}
4083
4084static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
4085                struct vb_device_info *pVBInfo)
4086{
4087        unsigned short i;
4088        unsigned char const *tempdi;
4089        unsigned short modeflag;
4090
4091        /* si+Ext_ResInfo */
4092        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4093
4094        xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
4095        if (pVBInfo->TVInfo & TVSetPAL) {
4096                xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
4097                xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
4098        } else {
4099                xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5);
4100                xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7);
4101        }
4102
4103        if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4104                return;
4105
4106        if (pVBInfo->TVInfo & TVSetPALM) {
4107                xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
4108                xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
4109                xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8);
4110        }
4111
4112        if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo
4113                        & SetCRT2ToYPbPr525750)) {
4114                if (pVBInfo->TVInfo & TVSetYPbPr525i)
4115                        return;
4116
4117                tempdi = XGI330_HiTVGroup3Data;
4118                if (pVBInfo->SetFlag & TVSimuMode) {
4119                        tempdi = XGI330_HiTVGroup3Simu;
4120                        if (!(modeflag & Charx8Dot))
4121                                tempdi = XGI330_HiTVGroup3Text;
4122                }
4123
4124                if (pVBInfo->TVInfo & TVSetYPbPr525p)
4125                        tempdi = XGI330_Ren525pGroup3;
4126
4127                if (pVBInfo->TVInfo & TVSetYPbPr750p)
4128                        tempdi = XGI330_Ren750pGroup3;
4129
4130                for (i = 0; i <= 0x3E; i++)
4131                        xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]);
4132
4133                if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
4134                        if (pVBInfo->TVInfo & TVSetYPbPr525p)
4135                                xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f);
4136                }
4137        }
4138        return;
4139} /* {end of XGI_SetGroup3} */
4140
4141static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
4142                unsigned short RefreshRateTableIndex,
4143                struct xgi_hw_device_info *HwDeviceExtension,
4144                struct vb_device_info *pVBInfo)
4145{
4146        unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2;
4147
4148        unsigned long tempebx, tempeax, templong;
4149
4150        /* si+Ext_ResInfo */
4151        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4152        temp = pVBInfo->RVBHCFACT;
4153        xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp);
4154
4155        tempbx = pVBInfo->RVBHCMAX;
4156        temp = tempbx & 0x00FF;
4157        xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp);
4158        temp2 = ((tempbx & 0xFF00) >> 8) << 7;
4159        tempcx = pVBInfo->VGAHT - 1;
4160        temp = tempcx & 0x00FF;
4161        xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp);
4162
4163        temp = ((tempcx & 0xFF00) >> 8) << 3;
4164        temp2 |= temp;
4165
4166        tempcx = pVBInfo->VGAVT - 1;
4167        if (!(pVBInfo->VBInfo & SetCRT2ToTV))
4168                tempcx -= 5;
4169
4170        temp = tempcx & 0x00FF;
4171        xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp);
4172        temp = temp2 | ((tempcx & 0xFF00) >> 8);
4173        xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp);
4174        xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08);
4175        tempcx = pVBInfo->VBInfo;
4176        tempbx = pVBInfo->VGAHDE;
4177
4178        if (modeflag & HalfDCLK)
4179                tempbx = tempbx >> 1;
4180
4181        if (XGI_IsLCDDualLink(pVBInfo))
4182                tempbx = tempbx >> 1;
4183
4184        if (tempcx & SetCRT2ToHiVision) {
4185                temp = 0;
4186                if (tempbx <= 1024)
4187                        temp = 0xA0;
4188                if (tempbx == 1280)
4189                        temp = 0xC0;
4190        } else if (tempcx & SetCRT2ToTV) {
4191                temp = 0xA0;
4192                if (tempbx <= 800)
4193                        temp = 0x80;
4194        } else {
4195                temp = 0x80;
4196                if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4197                        temp = 0;
4198                        if (tempbx > 800)
4199                                temp = 0x60;
4200                }
4201        }
4202
4203        if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) {
4204                temp = 0x00;
4205                if (pVBInfo->VGAHDE == 1280)
4206                        temp = 0x40;
4207                if (pVBInfo->VGAHDE == 1024)
4208                        temp = 0x20;
4209        }
4210        xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
4211
4212        tempebx = pVBInfo->VDE;
4213
4214        if (tempcx & SetCRT2ToHiVision) {
4215                if (!(temp & 0xE000))
4216                        tempbx = tempbx >> 1;
4217        }
4218
4219        tempcx = pVBInfo->RVBHRS;
4220        temp = tempcx & 0x00FF;
4221        xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp);
4222
4223        tempeax = pVBInfo->VGAVDE;
4224        tempcx |= 0x04000;
4225
4226        if (tempeax <= tempebx) {
4227                tempcx = (tempcx & (~0x4000));
4228                tempeax = pVBInfo->VGAVDE;
4229        } else {
4230                tempeax -= tempebx;
4231        }
4232
4233        templong = (tempeax * 256 * 1024) % tempebx;
4234        tempeax = (tempeax * 256 * 1024) / tempebx;
4235        tempebx = tempeax;
4236
4237        if (templong != 0)
4238                tempebx++;
4239
4240        temp = (unsigned short) (tempebx & 0x000000FF);
4241        xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp);
4242
4243        temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8);
4244        xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp);
4245        tempbx = (unsigned short) (tempebx >> 16);
4246        temp = tempbx & 0x00FF;
4247        temp = temp << 4;
4248        temp |= ((tempcx & 0xFF00) >> 8);
4249        xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp);
4250
4251        /* 301b */
4252        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4253                        | VB_SIS302LV | VB_XGI301C)) {
4254                temp = 0x0028;
4255                xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp);
4256                tempax = pVBInfo->VGAHDE;
4257                if (modeflag & HalfDCLK)
4258                        tempax = tempax >> 1;
4259
4260                if (XGI_IsLCDDualLink(pVBInfo))
4261                        tempax = tempax >> 1;
4262
4263                if (pVBInfo->VBInfo & SetCRT2ToLCD) {
4264                        if (tempax > 800)
4265                                tempax -= 800;
4266                } else if (pVBInfo->VGAHDE > 800) {
4267                        if (pVBInfo->VGAHDE == 1024)
4268                                tempax = (tempax * 25 / 32) - 1;
4269                        else
4270                                tempax = (tempax * 20 / 32) - 1;
4271                }
4272                tempax -= 1;
4273
4274                temp = (tempax & 0xFF00) >> 8;
4275                temp = ((temp & 0x0003) << 4);
4276                xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp);
4277                temp = (tempax & 0x00FF);
4278                xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp);
4279
4280                if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) {
4281                        if (pVBInfo->VGAHDE > 800)
4282                                xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08);
4283
4284                }
4285                temp = 0x0036;
4286
4287                if (pVBInfo->VBInfo & SetCRT2ToTV) {
4288                        if (!(pVBInfo->TVInfo & (NTSC1024x768
4289                                        | TVSetYPbPr525p | TVSetYPbPr750p
4290                                        | TVSetHiVision))) {
4291                                temp |= 0x0001;
4292                                if ((pVBInfo->VBInfo & SetInSlaveMode)
4293                                                && (!(pVBInfo->TVInfo
4294                                                                & TVSimuMode)))
4295                                        temp &= (~0x0001);
4296                        }
4297                }
4298
4299                xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp);
4300                tempbx = pVBInfo->HT;
4301                if (XGI_IsLCDDualLink(pVBInfo))
4302                        tempbx = tempbx >> 1;
4303                tempbx = (tempbx >> 1) - 2;
4304                temp = ((tempbx & 0x0700) >> 8) << 3;
4305                xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp);
4306                temp = tempbx & 0x00FF;
4307                xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp);
4308        }
4309        /* end 301b */
4310
4311        XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
4312}
4313
4314static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo)
4315{
4316        xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20);
4317}
4318
4319static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
4320                struct vb_device_info *pVBInfo)
4321{
4322        if (pVBInfo->ModeType == ModeVGA) {
4323                if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
4324                                | DisableCRT2Display))) {
4325                        XGINew_EnableCRT2(pVBInfo);
4326                }
4327        }
4328        return;
4329}
4330
4331static void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
4332                struct vb_device_info *pVBInfo)
4333{
4334        xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x40);
4335}
4336
4337static void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension,
4338                struct vb_device_info *pVBInfo)
4339{
4340
4341        xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00);
4342}
4343
4344static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info,
4345                unsigned short ModeNo, unsigned short ModeIdIndex,
4346                struct vb_device_info *pVBInfo)
4347{
4348        unsigned short xres, yres, colordepth, modeflag, resindex;
4349
4350        resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
4351        xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
4352        yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
4353        /* si+St_ModeFlag */
4354        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4355
4356        if (!(modeflag & Charx8Dot)) {
4357                xres /= 9;
4358                xres *= 8;
4359        }
4360
4361        if ((ModeNo > 0x13) && (modeflag & HalfDCLK))
4362                xres *= 2;
4363
4364        if ((ModeNo > 0x13) && (modeflag & DoubleScanMode))
4365                yres *= 2;
4366
4367        if (xres > xgifb_info->lvds_data.LVDSHDE)
4368                return 0;
4369
4370        if (yres > xgifb_info->lvds_data.LVDSVDE)
4371                return 0;
4372
4373        if (xres != xgifb_info->lvds_data.LVDSHDE ||
4374            yres != xgifb_info->lvds_data.LVDSVDE) {
4375                colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
4376                if (colordepth > 2)
4377                        return 0;
4378        }
4379        return 1;
4380}
4381
4382static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info,
4383                           int chip_id,
4384                           unsigned short ModeNo,
4385                           unsigned short ModeIdIndex,
4386                           struct vb_device_info *pVBInfo)
4387{
4388        unsigned char temp, Miscdata;
4389        unsigned short xres, yres, modeflag, resindex;
4390        unsigned short LVDSHT, LVDSHBS, LVDSHRS, LVDSHRE, LVDSHBE;
4391        unsigned short LVDSVT, LVDSVBS, LVDSVRS, LVDSVRE, LVDSVBE;
4392        unsigned short value;
4393
4394        temp = (unsigned char) ((xgifb_info->lvds_data.LVDS_Capability &
4395                                (LCDPolarity << 8)) >> 8);
4396        temp &= LCDPolarity;
4397        Miscdata = inb(pVBInfo->P3cc);
4398
4399        outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
4400
4401        temp = xgifb_info->lvds_data.LVDS_Capability & LCDPolarity;
4402        /* SR35[7] FP VSync polarity */
4403        xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
4404        /* SR30[5] FP HSync polarity */
4405        xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1);
4406
4407        if (chip_id == XG27)
4408                XGI_SetXG27FPBits(pVBInfo);
4409        else
4410                XGI_SetXG21FPBits(pVBInfo);
4411
4412        resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO;
4413        xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */
4414        yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */
4415        /* si+St_ModeFlag */
4416        modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
4417
4418        if (!(modeflag & Charx8Dot))
4419                xres = xres * 8 / 9;
4420
4421        LVDSHT = xgifb_info->lvds_data.LVDSHT;
4422
4423        LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2;
4424
4425        if (LVDSHBS > LVDSHT)
4426                LVDSHBS -= LVDSHT;
4427
4428        LVDSHRS = LVDSHBS + xgifb_info->lvds_data.LVDSHFP;
4429        if (LVDSHRS > LVDSHT)
4430                LVDSHRS -= LVDSHT;
4431
4432        LVDSHRE = LVDSHRS + xgifb_info->lvds_data.LVDSHSYNC;
4433        if (LVDSHRE > LVDSHT)
4434                LVDSHRE -= LVDSHT;
4435
4436        LVDSHBE = LVDSHBS + LVDSHT - xgifb_info->lvds_data.LVDSHDE;
4437
4438        LVDSVT = xgifb_info->lvds_data.LVDSVT;
4439
4440        LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2;
4441        if (modeflag & DoubleScanMode)
4442                LVDSVBS += yres / 2;
4443
4444        if (LVDSVBS > LVDSVT)
4445                LVDSVBS -= LVDSVT;
4446
4447        LVDSVRS = LVDSVBS + xgifb_info->lvds_data.LVDSVFP;
4448        if (LVDSVRS > LVDSVT)
4449                LVDSVRS -= LVDSVT;
4450
4451        LVDSVRE = LVDSVRS + xgifb_info->lvds_data.LVDSVSYNC;
4452        if (LVDSVRE > LVDSVT)
4453                LVDSVRE -= LVDSVT;
4454
4455        LVDSVBE = LVDSVBS + LVDSVT - xgifb_info->lvds_data.LVDSVDE;
4456
4457        temp = xgifb_reg_get(pVBInfo->P3d4, 0x11);
4458        xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */
4459
4460        if (!(modeflag & Charx8Dot))
4461                xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1);
4462
4463        /* HT SR0B[1:0] CR00 */
4464        value = (LVDSHT >> 3) - 5;
4465        xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8);
4466        xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF));
4467
4468        /* HBS SR0B[5:4] CR02 */
4469        value = (LVDSHBS >> 3) - 1;
4470        xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4);
4471        xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF));
4472
4473        /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
4474        value = (LVDSHBE >> 3) - 1;
4475        xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6);
4476        xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2);
4477        xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F);
4478
4479        /* HRS SR0B[7:6] CR04 */
4480        value = (LVDSHRS >> 3) + 2;
4481        xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2);
4482        xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF));
4483
4484        /* Panel HRS SR2F[1:0] SR2E[7:0]  */
4485        value--;
4486        xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8);
4487        xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF));
4488
4489        /* HRE SR0C[2] CR05[4:0] */
4490        value = (LVDSHRE >> 3) + 2;
4491        xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3);
4492        xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F);
4493
4494        /* Panel HRE SR2F[7:2]  */
4495        value--;
4496        xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2);
4497
4498        /* VT SR0A[0] CR07[5][0] CR06 */
4499        value = LVDSVT - 2;
4500        xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10);
4501        xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4);
4502        xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8);
4503        xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF));
4504
4505        /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
4506        value = LVDSVBS - 1;
4507        xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8);
4508        xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4);
4509        xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5);
4510        xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF));
4511
4512        /* VBE SR0A[4] CR16 */
4513        value = LVDSVBE - 1;
4514        xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4);
4515        xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF));
4516
4517        /* VRS SR0A[3] CR7[7][2] CR10 */
4518        value = LVDSVRS - 1;
4519        xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7);
4520        xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2);
4521        xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6);
4522        xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF));
4523
4524        if (chip_id == XG27) {
4525                /* Panel VRS SR35[2:0] SR34[7:0] */
4526                xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07,
4527                                        (value & 0x700) >> 8);
4528                xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF);
4529        } else {
4530                /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
4531                xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03,
4532                                        (value & 0x600) >> 9);
4533                xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF);
4534                xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01);
4535        }
4536
4537        /* VRE SR0A[5] CR11[3:0] */
4538        value = LVDSVRE - 1;
4539        xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1);
4540        xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F);
4541
4542        /* Panel VRE SR3F[7:2] */
4543        if (chip_id == XG27)
4544                xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
4545                                        (value << 2) & 0xFC);
4546        else
4547                /* SR3F[7] has to be 0, h/w bug */
4548                xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC,
4549                                        (value << 2) & 0x7C);
4550
4551        for (temp = 0, value = 0; temp < 3; temp++) {
4552
4553                xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
4554                xgifb_reg_set(pVBInfo->P3c4,
4555                              0x2B, xgifb_info->lvds_data.VCLKData1);
4556                xgifb_reg_set(pVBInfo->P3c4,
4557                              0x2C, xgifb_info->lvds_data.VCLKData2);
4558                value += 0x10;
4559        }
4560
4561        if (!(modeflag & Charx8Dot)) {
4562                inb(pVBInfo->P3da); /* reset 3da */
4563                outb(0x13, pVBInfo->P3c0); /* set index */
4564                /* set data, panning = 0, shift left 1 dot*/
4565                outb(0x00, pVBInfo->P3c0);
4566
4567                inb(pVBInfo->P3da); /* Enable Attribute */
4568                outb(0x20, pVBInfo->P3c0);
4569
4570                inb(pVBInfo->P3da); /* reset 3da */
4571        }
4572
4573}
4574
4575/* --------------------------------------------------------------------- */
4576/* Function : XGI_IsLCDON */
4577/* Input : */
4578/* Output : 0 : Skip PSC Control */
4579/* 1: Disable PSC */
4580/* Description : */
4581/* --------------------------------------------------------------------- */
4582static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
4583{
4584        unsigned short tempax;
4585
4586        tempax = pVBInfo->VBInfo;
4587        if (tempax & SetCRT2ToDualEdge)
4588                return 0;
4589        else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode))
4590                return 1;
4591
4592        return 0;
4593}
4594
4595/* --------------------------------------------------------------------- */
4596/* Function : XGI_EnableChISLCD */
4597/* Input : */
4598/* Output : 0 -> Not LCD mode */
4599/* Description : if bool enable = true -> enable, else disable  */
4600/* --------------------------------------------------------------------- */
4601static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo,
4602        bool enable)
4603{
4604        unsigned short tempbx, tempah;
4605
4606        if (enable)
4607                tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
4608        else
4609                tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
4610
4611        tempah = ~((unsigned short) xgifb_reg_get(pVBInfo->Part1Port, 0x2E));
4612
4613        if (tempbx & (EnableChA | DisableChA)) {
4614                if (!(tempah & 0x08)) /* Chk LCDA Mode */
4615                        return 0;
4616        }
4617
4618        if (!(tempbx & (EnableChB | DisableChB)))
4619                return 0;
4620
4621        if (tempah & 0x01) /* Chk LCDB Mode */
4622                return 1;
4623
4624        return 0;
4625}
4626
4627static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
4628                struct xgi_hw_device_info *HwDeviceExtension,
4629                struct vb_device_info *pVBInfo)
4630{
4631        unsigned short tempah = 0;
4632
4633        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4634                        | VB_SIS302LV | VB_XGI301C)) {
4635                tempah = 0x3F;
4636                if (!(pVBInfo->VBInfo &
4637                    (DisableCRT2Display | SetSimuScanMode))) {
4638                        if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
4639                                if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
4640                                        tempah = 0x7F; /* Disable Channel A */
4641                                        if (!(pVBInfo->VBInfo &
4642                                              XGI_SetCRT2ToLCDA))
4643                                                /* Disable Channel B */
4644                                                tempah = 0xBF;
4645
4646                                        if (pVBInfo->SetFlag & DisableChB)
4647                                                /* force to disable Cahnnel */
4648                                                tempah &= 0xBF;
4649
4650                                        if (pVBInfo->SetFlag & DisableChA)
4651                                                /* Force to disable Channel B */
4652                                                tempah &= 0x7F;
4653                                }
4654                        }
4655                }
4656
4657                /* disable part4_1f */
4658                xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah);
4659
4660                if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
4661                        if (((pVBInfo->VBInfo &
4662                              (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) ||
4663                                (XGI_EnableChISLCD(pVBInfo, false)) ||
4664                                (XGI_IsLCDON(pVBInfo)))
4665                                /* LVDS Driver power down */
4666                                xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80);
4667                }
4668
4669                if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
4670                                & (DisableCRT2Display | XGI_SetCRT2ToLCDA
4671                                                | SetSimuScanMode))) {
4672                        if (pVBInfo->SetFlag & GatingCRT)
4673                                XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
4674                        XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
4675                }
4676
4677                if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
4678                        if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
4679                                        & XGI_SetCRT2ToLCDA))
4680                                /* Power down */
4681                                xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf);
4682                }
4683
4684                /* disable TV as primary VGA swap */
4685                xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf);
4686
4687                if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
4688                        xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf);
4689
4690                if ((pVBInfo->SetFlag & DisableChB) ||
4691                    (pVBInfo->VBInfo &
4692                        (DisableCRT2Display | SetSimuScanMode)) ||
4693                    ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
4694                    (pVBInfo->VBInfo &
4695                        (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
4696                        xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
4697
4698                if ((pVBInfo->SetFlag & DisableChB) ||
4699                    (pVBInfo->VBInfo &
4700                        (DisableCRT2Display | SetSimuScanMode)) ||
4701                    (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) ||
4702                    (pVBInfo->VBInfo &
4703                        (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
4704                        /* save Part1 index 0 */
4705                        tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
4706                        /* BTDAC = 1, avoid VB reset */
4707                        xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10);
4708                        /* disable CRT2 */
4709                        xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
4710                        /* restore Part1 index 0 */
4711                        xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
4712                }
4713        } else { /* {301} */
4714                if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
4715                        xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
4716                        /* Disable CRT2 */
4717                        xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
4718                        /* Disable TV asPrimary VGA swap */
4719                        xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF);
4720                }
4721
4722                if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA
4723                                | SetSimuScanMode))
4724                        XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
4725        }
4726}
4727
4728/* --------------------------------------------------------------------- */
4729/* Function : XGI_GetTVPtrIndex */
4730/* Input : */
4731/* Output : */
4732/* Description : bx 0 : ExtNTSC */
4733/* 1 : StNTSC */
4734/* 2 : ExtPAL */
4735/* 3 : StPAL */
4736/* 4 : ExtHiTV */
4737/* 5 : StHiTV */
4738/* 6 : Ext525i */
4739/* 7 : St525i */
4740/* 8 : Ext525p */
4741/* 9 : St525p */
4742/* A : Ext750p */
4743/* B : St750p */
4744/* --------------------------------------------------------------------- */
4745static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
4746{
4747        unsigned short tempbx = 0;
4748
4749        if (pVBInfo->TVInfo & TVSetPAL)
4750                tempbx = 2;
4751        if (pVBInfo->TVInfo & TVSetHiVision)
4752                tempbx = 4;
4753        if (pVBInfo->TVInfo & TVSetYPbPr525i)
4754                tempbx = 6;
4755        if (pVBInfo->TVInfo & TVSetYPbPr525p)
4756                tempbx = 8;
4757        if (pVBInfo->TVInfo & TVSetYPbPr750p)
4758                tempbx = 10;
4759        if (pVBInfo->TVInfo & TVSimuMode)
4760                tempbx++;
4761
4762        return tempbx;
4763}
4764
4765/* --------------------------------------------------------------------- */
4766/* Function : XGI_GetTVPtrIndex2 */
4767/* Input : */
4768/* Output : bx 0 : NTSC */
4769/* 1 : PAL */
4770/* 2 : PALM */
4771/* 3 : PALN */
4772/* 4 : NTSC1024x768 */
4773/* 5 : PAL-M 1024x768 */
4774/* 6-7: reserved */
4775/* cl 0 : YFilter1 */
4776/* 1 : YFilter2 */
4777/* ch 0 : 301A */
4778/* 1 : 301B/302B/301LV/302LV */
4779/* Description : */
4780/* --------------------------------------------------------------------- */
4781static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
4782                unsigned char *tempch, struct vb_device_info *pVBInfo)
4783{
4784        *tempbx = 0;
4785        *tempcl = 0;
4786        *tempch = 0;
4787
4788        if (pVBInfo->TVInfo & TVSetPAL)
4789                *tempbx = 1;
4790
4791        if (pVBInfo->TVInfo & TVSetPALM)
4792                *tempbx = 2;
4793
4794        if (pVBInfo->TVInfo & TVSetPALN)
4795                *tempbx = 3;
4796
4797        if (pVBInfo->TVInfo & NTSC1024x768) {
4798                *tempbx = 4;
4799                if (pVBInfo->TVInfo & TVSetPALM)
4800                        *tempbx = 5;
4801        }
4802
4803        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4804                        | VB_SIS302LV | VB_XGI301C)) {
4805                if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
4806                                & TVSimuMode)) {
4807                        *tempbx += 8;
4808                        *tempcl += 1;
4809                }
4810        }
4811
4812        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4813                        | VB_SIS302LV | VB_XGI301C))
4814                (*tempch)++;
4815}
4816
4817static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
4818{
4819        unsigned char tempah, tempbl, tempbh;
4820
4821        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
4822                        | VB_SIS302LV | VB_XGI301C)) {
4823                if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA
4824                                | SetCRT2ToTV | SetCRT2ToRAMDAC)) {
4825                        tempbh = 0;
4826                        tempbl = XGI301TVDelay;
4827
4828                        if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
4829                                tempbl = tempbl >> 4;
4830                        if (pVBInfo->VBInfo &
4831                            (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
4832                                tempbh = XGI301LCDDelay;
4833
4834                                if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
4835                                        tempbl = tempbh;
4836                        }
4837
4838                        tempbl &= 0x0F;
4839                        tempbh &= 0xF0;
4840                        tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D);
4841
4842                        if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD
4843                                        | SetCRT2ToTV)) { /* Channel B */
4844                                tempah &= 0xF0;
4845                                tempah |= tempbl;
4846                        }
4847
4848                        if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
4849                                /* Channel A */
4850                                tempah &= 0x0F;
4851                                tempah |= tempbh;
4852                        }
4853                        xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah);
4854                }
4855        }
4856}
4857
4858static void XGI_SetLCDCap_A(unsigned short tempcx,
4859                            struct vb_device_info *pVBInfo)
4860{
4861        unsigned short temp;
4862
4863        temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
4864
4865        if (temp & LCDRGB18Bit) {
4866                xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
4867                                /* Enable Dither */
4868                                (unsigned short) (0x20 | (tempcx & 0x00C0)));
4869                xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
4870        } else {
4871                xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
4872                                (unsigned short) (0x30 | (tempcx & 0x00C0)));
4873                xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
4874        }
4875}
4876
4877/* --------------------------------------------------------------------- */
4878/* Function : XGI_SetLCDCap_B */
4879/* Input : cx -> LCD Capability */
4880/* Output : */
4881/* Description : */
4882/* --------------------------------------------------------------------- */
4883static void XGI_SetLCDCap_B(unsigned short tempcx,
4884                            struct vb_device_info *pVBInfo)
4885{
4886        if (tempcx & EnableLCD24bpp) /* 24bits */
4887                xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
4888                                (unsigned short) (((tempcx & 0x00ff) >> 6)
4889                                                | 0x0c));
4890        else
4891                xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
4892                                (unsigned short) (((tempcx & 0x00ff) >> 6)
4893                                                | 0x18)); /* Enable Dither */
4894}
4895
4896static void XGI_LongWait(struct vb_device_info *pVBInfo)
4897{
4898        unsigned short i;
4899
4900        i = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
4901
4902        if (!(i & 0xC0)) {
4903                for (i = 0; i < 0xFFFF; i++) {
4904                        if (!(inb(pVBInfo->P3da) & 0x08))
4905                                break;
4906                }
4907
4908                for (i = 0; i < 0xFFFF; i++) {
4909                        if ((inb(pVBInfo->P3da) & 0x08))
4910                                break;
4911                }
4912        }
4913}
4914
4915static void SetSpectrum(struct vb_device_info *pVBInfo)
4916{
4917        unsigned short index;
4918
4919        index = XGI_GetLCDCapPtr(pVBInfo);
4920
4921        /* disable down spectrum D[4] */
4922        xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F);
4923        XGI_LongWait(pVBInfo);
4924        xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
4925        XGI_LongWait(pVBInfo);
4926
4927        xgifb_reg_set(pVBInfo->Part4Port, 0x31,
4928                        pVBInfo->LCDCapList[index].Spectrum_31);
4929        xgifb_reg_set(pVBInfo->Part4Port, 0x32,
4930                        pVBInfo->LCDCapList[index].Spectrum_32);
4931        xgifb_reg_set(pVBInfo->Part4Port, 0x33,
4932                        pVBInfo->LCDCapList[index].Spectrum_33);
4933        xgifb_reg_set(pVBInfo->Part4Port, 0x34,
4934                        pVBInfo->LCDCapList[index].Spectrum_34);
4935        XGI_LongWait(pVBInfo);
4936        xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
4937}
4938
4939static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
4940{
4941        unsigned short tempcx;
4942
4943        tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
4944
4945        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV |
4946                VB_SIS302LV | VB_XGI301C)) {
4947                if (pVBInfo->VBType &
4948                    (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
4949                        /* Set 301LV Capability */
4950                        xgifb_reg_set(pVBInfo->Part4Port, 0x24,
4951                                        (unsigned char) (tempcx & 0x1F));
4952                }
4953                /* VB Driving */
4954                xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D,
4955                                ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
4956                                (unsigned short) ((tempcx & (EnableVBCLKDRVLOW
4957                                                | EnablePLLSPLOW)) >> 8));
4958
4959                if (pVBInfo->VBInfo & SetCRT2ToLCD)
4960                        XGI_SetLCDCap_B(tempcx, pVBInfo);
4961                else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
4962                        XGI_SetLCDCap_A(tempcx, pVBInfo);
4963
4964                if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
4965                        if (tempcx & EnableSpectrum)
4966                                SetSpectrum(pVBInfo);
4967                }
4968        } else {
4969                /* LVDS,CH7017 */
4970                XGI_SetLCDCap_A(tempcx, pVBInfo);
4971        }
4972}
4973
4974/* --------------------------------------------------------------------- */
4975/* Function : XGI_SetAntiFlicker */
4976/* Input : */
4977/* Output : */
4978/* Description : Set TV Customized Param. */
4979/* --------------------------------------------------------------------- */
4980static void XGI_SetAntiFlicker(unsigned short ModeNo,
4981                               unsigned short ModeIdIndex,
4982                               struct vb_device_info *pVBInfo)
4983{
4984        unsigned short tempbx;
4985
4986        unsigned char tempah;
4987
4988        if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
4989                return;
4990
4991        tempbx = XGI_GetTVPtrIndex(pVBInfo);
4992        tempbx &= 0xFE;
4993        tempah = TVAntiFlickList[tempbx];
4994        tempah = tempah << 4;
4995
4996        xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
4997}
4998
4999static void XGI_SetEdgeEnhance(unsigned short ModeNo,
5000                               unsigned short ModeIdIndex,
5001                               struct vb_device_info *pVBInfo)
5002{
5003        unsigned short tempbx;
5004
5005        unsigned char tempah;
5006
5007        tempbx = XGI_GetTVPtrIndex(pVBInfo);
5008        tempbx &= 0xFE;
5009        tempah = TVEdgeList[tempbx];
5010        tempah = tempah << 5;
5011
5012        xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
5013}
5014
5015static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo)
5016{
5017        unsigned short tempbx;
5018
5019        unsigned char tempcl, tempch;
5020
5021        unsigned long tempData;
5022
5023        XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
5024        tempData = TVPhaseList[tempbx];
5025
5026        xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData
5027                        & 0x000000FF));
5028        xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData
5029                        & 0x0000FF00) >> 8));
5030        xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData
5031                        & 0x00FF0000) >> 16));
5032        xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData
5033                        & 0xFF000000) >> 24));
5034}
5035
5036static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
5037                struct vb_device_info *pVBInfo)
5038{
5039        unsigned short tempbx, index;
5040        unsigned char const *filterPtr;
5041        unsigned char tempcl, tempch, tempal;
5042
5043        XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
5044
5045        switch (tempbx) {
5046        case 0x00:
5047        case 0x04:
5048                filterPtr = NTSCYFilter1;
5049                break;
5050
5051        case 0x01:
5052                filterPtr = PALYFilter1;
5053                break;
5054
5055        case 0x02:
5056        case 0x05:
5057        case 0x0D:
5058        case 0x03:
5059                filterPtr = xgifb_palmn_yfilter1;
5060                break;
5061
5062        case 0x08:
5063        case 0x0C:
5064        case 0x0A:
5065        case 0x0B:
5066        case 0x09:
5067                filterPtr = xgifb_yfilter2;
5068                break;
5069
5070        default:
5071                return;
5072        }
5073
5074        tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
5075        if (tempcl == 0)
5076                index = tempal * 4;
5077        else
5078                index = tempal * 7;
5079
5080        if ((tempcl == 0) && (tempch == 1)) {
5081                xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0);
5082                xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0);
5083                xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0);
5084                xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
5085        } else {
5086                xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]);
5087                xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]);
5088                xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]);
5089                xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
5090        }
5091
5092        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5093                        | VB_SIS302LV | VB_XGI301C)) {
5094                xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
5095                xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
5096                xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
5097        }
5098}
5099
5100/* --------------------------------------------------------------------- */
5101/* Function : XGI_OEM310Setting */
5102/* Input : */
5103/* Output : */
5104/* Description : Customized Param. for 301 */
5105/* --------------------------------------------------------------------- */
5106static void XGI_OEM310Setting(unsigned short ModeNo,
5107                              unsigned short ModeIdIndex,
5108                              struct vb_device_info *pVBInfo)
5109{
5110        XGI_SetDelayComp(pVBInfo);
5111
5112        if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
5113                XGI_SetLCDCap(pVBInfo);
5114
5115        if (pVBInfo->VBInfo & SetCRT2ToTV) {
5116                XGI_SetPhaseIncr(pVBInfo);
5117                XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
5118                XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
5119
5120                if (pVBInfo->VBType & VB_SIS301)
5121                        XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
5122        }
5123}
5124
5125/* --------------------------------------------------------------------- */
5126/* Function : XGI_SetCRT2ModeRegs */
5127/* Input : */
5128/* Output : */
5129/* Description : Origin code for crt2group */
5130/* --------------------------------------------------------------------- */
5131static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
5132                struct xgi_hw_device_info *HwDeviceExtension,
5133                struct vb_device_info *pVBInfo)
5134{
5135        unsigned short tempbl;
5136        short tempcl;
5137
5138        unsigned char tempah;
5139
5140        tempah = 0;
5141        if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5142                tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
5143                tempah &= ~0x10; /* BTRAMDAC */
5144                tempah |= 0x40; /* BTRAM */
5145
5146                if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
5147                                | SetCRT2ToLCD)) {
5148                        tempah = 0x40; /* BTDRAM */
5149                        tempcl = pVBInfo->ModeType;
5150                        tempcl -= ModeVGA;
5151                        if (tempcl >= 0) {
5152                                /* BT Color */
5153                                tempah = (0x008 >> tempcl);
5154                                if (tempah == 0)
5155                                        tempah = 1;
5156                                tempah |= 0x040;
5157                        }
5158                        if (pVBInfo->VBInfo & SetInSlaveMode)
5159                                tempah ^= 0x50; /* BTDAC */
5160                }
5161        }
5162
5163        xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
5164        tempah = 0x08;
5165        tempbl = 0xf0;
5166
5167        if (pVBInfo->VBInfo & DisableCRT2Display)
5168                goto reg_and_or;
5169
5170        tempah = 0x00;
5171        tempbl = 0xff;
5172
5173        if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV |
5174                                 SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
5175                goto reg_and_or;
5176
5177        if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
5178            (!(pVBInfo->VBInfo & SetSimuScanMode))) {
5179                tempbl &= 0xf7;
5180                tempah |= 0x01;
5181                goto reg_and_or;
5182        }
5183
5184        if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5185                tempbl &= 0xf7;
5186                tempah |= 0x01;
5187        }
5188
5189        if (!(pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)))
5190                goto reg_and_or;
5191
5192        tempbl &= 0xf8;
5193        tempah = 0x01;
5194
5195        if (!(pVBInfo->VBInfo & SetInSlaveMode))
5196                tempah |= 0x02;
5197
5198        if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
5199                tempah = tempah ^ 0x05;
5200                if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
5201                        tempah = tempah ^ 0x01;
5202        }
5203
5204        if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
5205                tempah |= 0x08;
5206
5207reg_and_or:
5208        xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah);
5209
5210        if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
5211                        | XGI_SetCRT2ToLCDA)) {
5212                tempah &= (~0x08);
5213                if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
5214                                & SetInSlaveMode))) {
5215                        tempah |= 0x010;
5216                }
5217                tempah |= 0x080;
5218
5219                if (pVBInfo->VBInfo & SetCRT2ToTV) {
5220                        tempah |= 0x020;
5221                        if (pVBInfo->VBInfo & DriverMode)
5222                                tempah = tempah ^ 0x20;
5223                }
5224
5225                xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah);
5226                tempah = 0;
5227
5228                if (pVBInfo->LCDInfo & SetLCDDualLink)
5229                        tempah |= 0x40;
5230
5231                if (pVBInfo->VBInfo & SetCRT2ToTV) {
5232                        if (pVBInfo->TVInfo & RPLLDIV2XO)
5233                                tempah |= 0x40;
5234                }
5235
5236                if ((pVBInfo->LCDResInfo == Panel_1280x1024)
5237                                || (pVBInfo->LCDResInfo == Panel_1280x1024x75))
5238                        tempah |= 0x80;
5239
5240                if (pVBInfo->LCDResInfo == Panel_1280x960)
5241                        tempah |= 0x80;
5242
5243                xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah);
5244        }
5245
5246        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5247                        | VB_SIS302LV | VB_XGI301C)) {
5248                tempah = 0;
5249                tempbl = 0xfb;
5250
5251                if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
5252                        tempbl = 0xff;
5253                        if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
5254                                tempah |= 0x04; /* shampoo 0129 */
5255                }
5256
5257                xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah);
5258                tempah = 0x00;
5259                tempbl = 0xcf;
5260                if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5261                        if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5262                                tempah |= 0x30;
5263                }
5264
5265                xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah);
5266                tempah = 0;
5267                tempbl = 0x3f;
5268
5269                if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5270                        if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
5271                                tempah |= 0xc0;
5272                }
5273                xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah);
5274        }
5275
5276        tempah = 0;
5277        tempbl = 0x7f;
5278        if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) {
5279                tempbl = 0xff;
5280                if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
5281                        tempah |= 0x80;
5282        }
5283
5284        xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah);
5285
5286        if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5287                if (pVBInfo->LCDInfo & SetLCDDualLink) {
5288                        xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20);
5289                        xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10);
5290                }
5291        }
5292}
5293
5294
5295void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
5296                struct vb_device_info *pVBInfo)
5297{
5298
5299        xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
5300
5301}
5302
5303void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
5304                struct vb_device_info *pVBInfo)
5305{
5306
5307        xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
5308
5309}
5310
5311unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo)
5312{
5313        unsigned short flag;
5314
5315        if (pVBInfo->IF_DEF_LVDS == 1) {
5316                return 1;
5317        } else {
5318                flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
5319                if ((flag == 1) || (flag == 2))
5320                        return 1; /* 301b */
5321                else
5322                        return 0;
5323        }
5324}
5325
5326unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
5327                unsigned short ModeNo, unsigned short ModeIdIndex,
5328                struct vb_device_info *pVBInfo)
5329{
5330        const u8 LCDARefreshIndex[] = {
5331                0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x00 };
5332
5333        unsigned short RefreshRateTableIndex, i, index, temp;
5334
5335        index = xgifb_reg_get(pVBInfo->P3d4, 0x33);
5336        index = index >> pVBInfo->SelectCRT2Rate;
5337        index &= 0x0F;
5338
5339        if (pVBInfo->LCDInfo & LCDNonExpanding)
5340                index = 0;
5341
5342        if (index > 0)
5343                index--;
5344
5345        if (pVBInfo->SetFlag & ProgrammingCRT2) {
5346                if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
5347                        if (pVBInfo->IF_DEF_LVDS == 0) {
5348                                temp = LCDARefreshIndex[
5349                                        pVBInfo->LCDResInfo & 0x07];
5350
5351                                if (index > temp)
5352                                        index = temp;
5353                        } else {
5354                                index = 0;
5355                        }
5356                }
5357        }
5358
5359        RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex;
5360        ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID;
5361        if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
5362                if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) &&
5363                    (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) {
5364                        index++;
5365                }
5366                /* do the similar adjustment like XGISearchCRT1Rate() */
5367                if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) &&
5368                    (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) {
5369                        index++;
5370                }
5371                if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
5372                    (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) {
5373                        index++;
5374                }
5375        }
5376
5377        i = 0;
5378        do {
5379                if (XGI330_RefIndex[RefreshRateTableIndex + i].
5380                        ModeID != ModeNo)
5381                        break;
5382                temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
5383                temp &= ModeTypeMask;
5384                if (temp < pVBInfo->ModeType)
5385                        break;
5386                i++;
5387                index--;
5388
5389        } while (index != 0xFFFF);
5390        if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
5391                if (pVBInfo->VBInfo & SetInSlaveMode) {
5392                        temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1].
5393                                Ext_InfoFlag;
5394                        if (temp & InterlaceMode)
5395                                i++;
5396                }
5397        }
5398        i--;
5399        if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
5400                temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex,
5401                                RefreshRateTableIndex, &i, pVBInfo);
5402        }
5403        return RefreshRateTableIndex + i;
5404}
5405
5406static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex,
5407                struct xgi_hw_device_info *HwDeviceExtension,
5408                struct vb_device_info *pVBInfo)
5409{
5410        unsigned short RefreshRateTableIndex;
5411
5412        pVBInfo->SetFlag |= ProgrammingCRT2;
5413        RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5414                        ModeIdIndex, pVBInfo);
5415        XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
5416        XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5417        XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5418                        HwDeviceExtension, pVBInfo);
5419        XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5420        XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5421}
5422
5423static unsigned char XGI_SetCRT2Group301(unsigned short ModeNo,
5424                struct xgi_hw_device_info *HwDeviceExtension,
5425                struct vb_device_info *pVBInfo)
5426{
5427        unsigned short ModeIdIndex, RefreshRateTableIndex;
5428
5429        pVBInfo->SetFlag |= ProgrammingCRT2;
5430        XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
5431        pVBInfo->SelectCRT2Rate = 4;
5432        RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5433                        ModeIdIndex, pVBInfo);
5434        XGI_SaveCRT2Info(ModeNo, pVBInfo);
5435        XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
5436        XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5437        XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
5438                        RefreshRateTableIndex, pVBInfo);
5439        XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
5440                        RefreshRateTableIndex, pVBInfo);
5441        XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
5442                        RefreshRateTableIndex, pVBInfo);
5443        XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5444                        HwDeviceExtension, pVBInfo);
5445        XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
5446                        RefreshRateTableIndex, pVBInfo);
5447        XGI_SetTap4Regs(pVBInfo);
5448        XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
5449        XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5450                        HwDeviceExtension, pVBInfo);
5451        XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
5452        XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
5453        XGI_AutoThreshold(pVBInfo);
5454        return 1;
5455}
5456
5457void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
5458{
5459        unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
5460                        0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00,
5461                        0x05, 0x00 };
5462
5463        unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
5464
5465        unsigned char CR17, CR63, SR31;
5466        unsigned short temp;
5467
5468        int i;
5469        xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
5470
5471        /* to fix XG42 single LCD sense to CRT+LCD */
5472        xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A);
5473        xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get(
5474                        pVBInfo->P3d4, 0x53) | 0x02));
5475
5476        SR31 = xgifb_reg_get(pVBInfo->P3c4, 0x31);
5477        CR63 = xgifb_reg_get(pVBInfo->P3d4, 0x63);
5478        SR01 = xgifb_reg_get(pVBInfo->P3c4, 0x01);
5479
5480        xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF));
5481        xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF));
5482
5483        CR17 = xgifb_reg_get(pVBInfo->P3d4, 0x17);
5484        xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80));
5485
5486        SR1F = xgifb_reg_get(pVBInfo->P3c4, 0x1F);
5487        xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04));
5488
5489        SR07 = xgifb_reg_get(pVBInfo->P3c4, 0x07);
5490        xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB));
5491        SR06 = xgifb_reg_get(pVBInfo->P3c4, 0x06);
5492        xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3));
5493
5494        xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00);
5495
5496        for (i = 0; i < 8; i++)
5497                xgifb_reg_set(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]);
5498
5499        for (i = 8; i < 11; i++)
5500                xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 8),
5501                                CRTCData[i]);
5502
5503        for (i = 11; i < 13; i++)
5504                xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 4),
5505                                CRTCData[i]);
5506
5507        for (i = 13; i < 16; i++)
5508                xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i - 3),
5509                                CRTCData[i]);
5510
5511        xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16]
5512                        & 0xE0));
5513
5514        xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00);
5515        xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B);
5516        xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1);
5517
5518        outb(0x00, pVBInfo->P3c8);
5519
5520        for (i = 0; i < 256 * 3; i++) {
5521                outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */
5522        }
5523
5524        mdelay(1);
5525
5526        XGI_WaitDisply(pVBInfo);
5527        temp = inb(pVBInfo->P3c2);
5528
5529        if (temp & 0x10)
5530                xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20);
5531        else
5532                xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00);
5533
5534        /* avoid display something, set BLACK DAC if not restore DAC */
5535        outb(0x00, pVBInfo->P3c8);
5536
5537        for (i = 0; i < 256 * 3; i++) {
5538                outb(0, (pVBInfo->P3c8 + 1));
5539        }
5540
5541        xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01);
5542        xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63);
5543        xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31);
5544
5545        xgifb_reg_set(pVBInfo->P3d4, 0x53, (xgifb_reg_get(
5546                        pVBInfo->P3d4, 0x53) & 0xFD));
5547        xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F);
5548}
5549
5550static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
5551                struct xgi_hw_device_info *HwDeviceExtension,
5552                struct vb_device_info *pVBInfo)
5553{
5554        unsigned short tempah;
5555
5556        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5557                        | VB_SIS302LV | VB_XGI301C)) {
5558                if (!(pVBInfo->SetFlag & DisableChA)) {
5559                        if ((pVBInfo->SetFlag & EnableChA) ||
5560                            (pVBInfo->VBInfo & SetCRT2ToDualEdge)) {
5561                                /* Power on */
5562                                xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20);
5563                        }
5564                }
5565
5566                if (!(pVBInfo->SetFlag & DisableChB)) {
5567                        if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo
5568                                        & (SetCRT2ToLCD | SetCRT2ToTV
5569                                                        | SetCRT2ToRAMDAC))) {
5570                                tempah = xgifb_reg_get(pVBInfo->P3c4, 0x32);
5571                                tempah &= 0xDF;
5572                                if (pVBInfo->VBInfo & SetInSlaveMode) {
5573                                        if (!(pVBInfo->VBInfo &
5574                                              SetCRT2ToRAMDAC))
5575                                                tempah |= 0x20;
5576                                }
5577                                xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah);
5578                                xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20);
5579
5580                                tempah = xgifb_reg_get(pVBInfo->Part1Port,
5581                                                       0x2E);
5582
5583                                if (!(tempah & 0x80))
5584                                        xgifb_reg_or(pVBInfo->Part1Port,
5585                                                        0x2E, 0x80);
5586                                xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
5587                        }
5588                }
5589
5590                if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
5591                                || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
5592                        xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0,
5593                                        0x20); /* shampoo 0129 */
5594                        if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
5595                                if (!XGI_EnableChISLCD(pVBInfo, false)) {
5596                                        if (XGI_EnableChISLCD(pVBInfo, true) ||
5597                                            (pVBInfo->VBInfo &
5598                                            (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
5599                                                /* LVDS PLL power on */
5600                                                xgifb_reg_and(
5601                                                        pVBInfo->Part4Port,
5602                                                        0x2A,
5603                                                        0x7F);
5604                                }
5605                                /* LVDS Driver power on */
5606                                xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F);
5607                        }
5608                }
5609
5610                tempah = 0x00;
5611
5612                if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
5613                        tempah = 0xc0;
5614
5615                        if (!(pVBInfo->VBInfo & SetSimuScanMode) &&
5616                            (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
5617                            (pVBInfo->VBInfo & SetCRT2ToDualEdge)) {
5618                                tempah = tempah & 0x40;
5619                                if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
5620                                        tempah = tempah ^ 0xC0;
5621
5622                                if (pVBInfo->SetFlag & DisableChB)
5623                                        tempah &= 0xBF;
5624
5625                                if (pVBInfo->SetFlag &  DisableChA)
5626                                        tempah &= 0x7F;
5627
5628                                if (pVBInfo->SetFlag &  EnableChB)
5629                                        tempah |= 0x40;
5630
5631                                if (pVBInfo->SetFlag &  EnableChA)
5632                                        tempah |= 0x80;
5633                        }
5634                }
5635
5636                /* EnablePart4_1F */
5637                xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah);
5638
5639                if (!(pVBInfo->SetFlag & DisableChA)) {
5640                        if (!(pVBInfo->SetFlag & GatingCRT)) {
5641                                XGI_DisableGatingCRT(HwDeviceExtension,
5642                                                     pVBInfo);
5643                                XGI_DisplayOn(xgifb_info, HwDeviceExtension,
5644                                                pVBInfo);
5645                        }
5646                }
5647        } /* 301 */
5648        else { /* LVDS */
5649                if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
5650                                | XGI_SetCRT2ToLCDA))
5651                        /* enable CRT2 */
5652                        xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20);
5653
5654                tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2E);
5655                if (!(tempah & 0x80))
5656                        xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
5657
5658                xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
5659                XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
5660        } /* End of VB */
5661}
5662
5663static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
5664                struct xgi_hw_device_info *HwDeviceExtension,
5665                unsigned short ModeNo, unsigned short ModeIdIndex,
5666                struct vb_device_info *pVBInfo)
5667{
5668        unsigned short RefreshRateTableIndex, temp;
5669
5670        XGI_SetSeqRegs(ModeNo, ModeIdIndex, pVBInfo);
5671        outb(XGI330_StandTable.MISC, pVBInfo->P3c2);
5672        XGI_SetCRTCRegs(HwDeviceExtension, pVBInfo);
5673        XGI_SetATTRegs(ModeNo, ModeIdIndex, pVBInfo);
5674        XGI_SetGRCRegs(pVBInfo);
5675        XGI_ClearExt1Regs(pVBInfo);
5676
5677        if (HwDeviceExtension->jChipType == XG27) {
5678                if (pVBInfo->IF_DEF_LVDS == 0)
5679                        XGI_SetDefaultVCLK(pVBInfo);
5680        }
5681
5682        temp = ~ProgrammingCRT2;
5683        pVBInfo->SetFlag &= temp;
5684        pVBInfo->SelectCRT2Rate = 0;
5685
5686        if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
5687                        | VB_SIS302LV | VB_XGI301C)) {
5688                if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA
5689                                | SetInSlaveMode)) {
5690                        pVBInfo->SetFlag |= ProgrammingCRT2;
5691                }
5692        }
5693
5694        RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
5695                        ModeIdIndex, pVBInfo);
5696        if (RefreshRateTableIndex != 0xFFFF) {
5697                XGI_SetSync(RefreshRateTableIndex, pVBInfo);
5698                XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5699                                pVBInfo, HwDeviceExtension);
5700                XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
5701                                RefreshRateTableIndex, pVBInfo);
5702                XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
5703                                HwDeviceExtension, pVBInfo);
5704                XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
5705                                RefreshRateTableIndex, pVBInfo);
5706        }
5707
5708        if (HwDeviceExtension->jChipType >= XG21) {
5709                temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
5710                if (temp & 0xA0) {
5711
5712                        if (HwDeviceExtension->jChipType == XG27)
5713                                XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
5714                                                RefreshRateTableIndex, pVBInfo);
5715                        else
5716                                XGI_SetXG21CRTC(ModeNo, ModeIdIndex,
5717                                                RefreshRateTableIndex, pVBInfo);
5718
5719                        XGI_UpdateXG21CRTC(ModeNo, pVBInfo,
5720                                        RefreshRateTableIndex);
5721
5722                        xgifb_set_lcd(HwDeviceExtension->jChipType,
5723                                        pVBInfo, RefreshRateTableIndex, ModeNo);
5724
5725                        if (pVBInfo->IF_DEF_LVDS == 1)
5726                                xgifb_set_lvds(xgifb_info,
5727                                                HwDeviceExtension->jChipType,
5728                                                ModeNo, ModeIdIndex, pVBInfo);
5729                }
5730        }
5731
5732        pVBInfo->SetFlag &= (~ProgrammingCRT2);
5733        XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
5734        XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
5735                        RefreshRateTableIndex, pVBInfo);
5736        XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
5737}
5738
5739unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
5740                        struct xgi_hw_device_info *HwDeviceExtension,
5741                        unsigned short ModeNo)
5742{
5743        unsigned short ModeIdIndex;
5744        struct vb_device_info VBINF;
5745        struct vb_device_info *pVBInfo = &VBINF;
5746        pVBInfo->IF_DEF_LVDS = 0;
5747
5748        if (HwDeviceExtension->jChipType >= XG20) {
5749                pVBInfo->IF_DEF_YPbPr = 0;
5750                pVBInfo->IF_DEF_HiVision = 0;
5751                pVBInfo->IF_DEF_CRT2Monitor = 0;
5752                pVBInfo->VBType = 0; /*set VBType default 0*/
5753        } else {
5754                pVBInfo->IF_DEF_YPbPr = 1;
5755                pVBInfo->IF_DEF_HiVision = 1;
5756                pVBInfo->IF_DEF_CRT2Monitor = 1;
5757        }
5758
5759        XGIRegInit(pVBInfo, xgifb_info->vga_base);
5760
5761        /* for x86 Linux, XG21 LVDS */
5762        if (HwDeviceExtension->jChipType == XG21) {
5763                if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
5764                        pVBInfo->IF_DEF_LVDS = 1;
5765        }
5766        if (HwDeviceExtension->jChipType == XG27) {
5767                if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
5768                        if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20)
5769                                pVBInfo->IF_DEF_LVDS = 1;
5770                }
5771        }
5772
5773        if (HwDeviceExtension->jChipType < XG20)
5774                XGI_GetVBType(pVBInfo);
5775
5776        InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
5777        if (ModeNo & 0x80)
5778                ModeNo = ModeNo & 0x7F;
5779        xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
5780
5781        if (HwDeviceExtension->jChipType < XG20)
5782                XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
5783
5784        XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
5785
5786        if (HwDeviceExtension->jChipType < XG20) {
5787                XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
5788                XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
5789                XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
5790                XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
5791
5792                if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA) ||
5793                        (!(pVBInfo->VBInfo & SwitchCRT2))) {
5794                        XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
5795                                        ModeIdIndex, pVBInfo);
5796
5797                        if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
5798                                XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
5799                                                HwDeviceExtension, pVBInfo);
5800                        }
5801                }
5802
5803                if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) {
5804                        switch (HwDeviceExtension->ujVBChipID) {
5805                        case VB_CHIP_301: /* fall through */
5806                        case VB_CHIP_302:
5807                                XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
5808                                                pVBInfo); /*add for CRT2 */
5809                                break;
5810
5811                        default:
5812                                break;
5813                        }
5814                }
5815
5816                XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
5817                XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/
5818                XGI_EnableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
5819        } /* !XG20 */
5820        else {
5821                if (pVBInfo->IF_DEF_LVDS == 1)
5822                        if (!XGI_XG21CheckLVDSMode(xgifb_info, ModeNo,
5823                                                   ModeIdIndex,
5824                                                   pVBInfo))
5825                                return 0;
5826
5827                pVBInfo->ModeType = XGI330_EModeIDTable[ModeIdIndex].
5828                                                Ext_ModeFlag & ModeTypeMask;
5829
5830                pVBInfo->SetFlag = 0;
5831                pVBInfo->VBInfo = DisableCRT2Display;
5832
5833                XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
5834
5835                XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
5836                                ModeIdIndex, pVBInfo);
5837
5838                XGI_DisplayOn(xgifb_info, HwDeviceExtension, pVBInfo);
5839        }
5840
5841        XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
5842
5843        if (HwDeviceExtension->jChipType < XG20)
5844                XGI_LockCRT2(HwDeviceExtension, pVBInfo);
5845
5846        return 1;
5847}
5848