linux/drivers/staging/xgifb/vb_ext.c
<<
>>
Prefs
   1#include <linux/version.h>
   2#include <asm/io.h>
   3#include <linux/types.h>
   4#include "XGIfb.h"
   5
   6#include "vb_def.h"
   7#include "vgatypes.h"
   8#include "vb_struct.h"
   9#include "vb_util.h"
  10#include "vb_setmode.h"
  11#include "vb_ext.h"
  12extern unsigned char XGI330_SoftSetting;
  13extern unsigned char XGI330_OutputSelect;
  14extern unsigned short XGI330_RGBSenseData2;
  15extern unsigned short XGI330_YCSenseData2;
  16extern unsigned short XGI330_VideoSenseData2;
  17void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
  18                struct vb_device_info *pVBInfo);
  19unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo);
  20unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *,
  21                struct vb_device_info *pVBInfo);
  22unsigned char XGINew_GetLCDDDCInfo(
  23                struct xgi_hw_device_info *HwDeviceExtension,
  24                struct vb_device_info *pVBInfo);
  25void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE,
  26                unsigned long VESA_POWER_STATE);
  27unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *,
  28                struct vb_device_info *pVBInfo);
  29unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx,
  30                struct vb_device_info *pVBInfo);
  31unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension,
  32                struct vb_device_info *pVBInfo);
  33
  34/**************************************************************
  35 *********************** Dynamic Sense ************************
  36 *************************************************************/
  37
  38void XGI_WaitDisplay(void);
  39unsigned char XGI_Is301C(struct vb_device_info *);
  40unsigned char XGI_Is301LV(struct vb_device_info *);
  41
  42static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo)
  43{
  44        unsigned short flag;
  45
  46        flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01);
  47
  48        if (flag > 0x0B0)
  49                return 0; /* 301b */
  50        else
  51                return 1;
  52}
  53
  54unsigned char XGI_Is301C(struct vb_device_info *pVBInfo)
  55{
  56        if ((XGINew_GetReg1(pVBInfo->Part4Port, 0x01) & 0xF0) == 0xC0)
  57                return 1;
  58
  59        if (XGINew_GetReg1(pVBInfo->Part4Port, 0x01) >= 0xD0) {
  60                if (XGINew_GetReg1(pVBInfo->Part4Port, 0x39) == 0xE0)
  61                        return 1;
  62        }
  63
  64        return 0;
  65}
  66
  67unsigned char XGI_Is301LV(struct vb_device_info *pVBInfo)
  68{
  69        if (XGINew_GetReg1(pVBInfo->Part4Port, 0x01) >= 0xD0) {
  70                if (XGINew_GetReg1(pVBInfo->Part4Port, 0x39) == 0xFF)
  71                        return 1;
  72        }
  73        return 0;
  74}
  75
  76unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, struct vb_device_info *pVBInfo)
  77{
  78        unsigned short temp, i, tempch;
  79
  80        temp = tempbx & 0xFF;
  81        XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp);
  82        temp = (tempbx & 0xFF00) >> 8;
  83        temp |= (tempcx & 0x00FF);
  84        XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
  85
  86        for (i = 0; i < 10; i++)
  87                XGI_LongWait(pVBInfo);
  88
  89        tempch = (tempcx & 0x7F00) >> 8;
  90        temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03);
  91        temp = temp ^ (0x0E);
  92        temp &= tempch;
  93
  94        if (temp > 0)
  95                return 1;
  96        else
  97                return 0;
  98}
  99
 100void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE, unsigned long VESA_POWER_STATE)
 101{
 102        unsigned short ModeNo, ModeIdIndex;
 103        unsigned char temp;
 104        struct vb_device_info VBINF;
 105        struct vb_device_info *pVBInfo = &VBINF;
 106        pVBInfo->BaseAddr = (unsigned long) pXGIHWDE->pjIOAddress;
 107        pVBInfo->ROMAddr = pXGIHWDE->pjVirtualRomBase;
 108
 109        pVBInfo->IF_DEF_LVDS = 0;
 110        pVBInfo->IF_DEF_CH7005 = 0;
 111        pVBInfo->IF_DEF_HiVision = 1;
 112        pVBInfo->IF_DEF_LCDA = 1;
 113        pVBInfo->IF_DEF_CH7017 = 0;
 114        pVBInfo->IF_DEF_YPbPr = 1;
 115        pVBInfo->IF_DEF_CRT2Monitor = 0;
 116        pVBInfo->IF_DEF_VideoCapture = 0;
 117        pVBInfo->IF_DEF_ScaleLCD = 0;
 118        pVBInfo->IF_DEF_OEMUtil = 0;
 119        pVBInfo->IF_DEF_PWD = 0;
 120
 121        InitTo330Pointer(pXGIHWDE->jChipType, pVBInfo);
 122        ReadVBIOSTablData(pXGIHWDE->jChipType, pVBInfo);
 123
 124        pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
 125        pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
 126        pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
 127        pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
 128        pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
 129        pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
 130        pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
 131        pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
 132        pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
 133        pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
 134        pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
 135        pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
 136        pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
 137        pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
 138        pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
 139        pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
 140        pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
 141
 142        if (pXGIHWDE->jChipType == XG27) {
 143                if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) {
 144                        if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20)
 145                                pVBInfo->IF_DEF_LVDS = 1;
 146                }
 147        }
 148
 149        if (pVBInfo->IF_DEF_CH7007 == 0)
 150                XGINew_SetModeScratch(pXGIHWDE, pVBInfo);
 151
 152        XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); /* 1.Openkey */
 153        XGI_UnLockCRT2(pXGIHWDE, pVBInfo);
 154        ModeNo = XGINew_GetReg1(pVBInfo->P3d4, 0x34);
 155        XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
 156        XGI_GetVGAType(pXGIHWDE, pVBInfo);
 157
 158        if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302) || (pVBInfo->IF_DEF_CH7007 == 1)) {
 159                XGI_GetVBType(pVBInfo);
 160                XGI_GetVBInfo(ModeNo, ModeIdIndex, pXGIHWDE, pVBInfo);
 161                XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
 162                XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
 163        }
 164
 165        if (VESA_POWER_STATE == 0x00000400)
 166                XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char) (XGINew_GetReg1(pVBInfo->Part4Port, 0x31) & 0xFE));
 167        else
 168                XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char) (XGINew_GetReg1(pVBInfo->Part4Port, 0x31) | 0x01));
 169
 170        temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1f);
 171        temp &= 0x3f;
 172        switch (VESA_POWER_STATE) {
 173        case 0x00000000: /* on */
 174                if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302)) {
 175                        XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x00));
 176                        XGI_EnableBridge(pXGIHWDE, pVBInfo);
 177                } else {
 178                        if (pXGIHWDE->jChipType == XG21) {
 179                                if (pVBInfo->IF_DEF_LVDS == 1) {
 180                                        XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
 181                                        XGI_XG21SetPanelDelay(2, pVBInfo);
 182                                }
 183                        }
 184                        if (pXGIHWDE->jChipType == XG27) {
 185                                if (pVBInfo->IF_DEF_LVDS == 1) {
 186                                        XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
 187                                        XGI_XG21SetPanelDelay(2, pVBInfo);
 188                                }
 189                        }
 190                        XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, ~0xC0, 0x00);
 191                        XGINew_SetRegAND(pVBInfo->P3c4, 0x01, ~0x20); /* CRT on */
 192
 193                        if (pXGIHWDE->jChipType == XG21) {
 194                                temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
 195                                if (temp & 0xE0) {
 196                                        XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); /* DVO ON */
 197                                        XGI_SetXG21FPBits(pVBInfo);
 198                                        XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */
 199                                        /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~0x20, 0x20); *//* LCD Display ON */
 200                                }
 201                                XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
 202                                XGI_DisplayOn(pXGIHWDE, pVBInfo);
 203                        }
 204                        if (pXGIHWDE->jChipType == XG27) {
 205                                temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
 206                                if (temp & 0xE0) {
 207                                        XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); /* DVO ON */
 208                                        XGI_SetXG27FPBits(pVBInfo);
 209                                        XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */
 210                                        /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~0x20, 0x20); *//* LCD Display ON */
 211                                }
 212                                XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
 213                                XGI_DisplayOn(pXGIHWDE, pVBInfo);
 214                        }
 215                }
 216                break;
 217
 218        case 0x00000100: /* standby */
 219                if (pXGIHWDE->jChipType >= XG21)
 220                        XGI_DisplayOff(pXGIHWDE, pVBInfo);
 221                XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x40));
 222                break;
 223
 224        case 0x00000200: /* suspend */
 225                if (pXGIHWDE->jChipType == XG21) {
 226                        XGI_DisplayOff(pXGIHWDE, pVBInfo);
 227                        XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */
 228                }
 229                if (pXGIHWDE->jChipType == XG27) {
 230                        XGI_DisplayOff(pXGIHWDE, pVBInfo);
 231                        XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */
 232                }
 233                XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x80));
 234                break;
 235
 236        case 0x00000400: /* off */
 237                if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302)) {
 238                        XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0xc0));
 239                        XGI_DisableBridge(pXGIHWDE, pVBInfo);
 240                } else {
 241                        if (pXGIHWDE->jChipType == XG21) {
 242                                XGI_DisplayOff(pXGIHWDE, pVBInfo);
 243
 244                                XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */
 245
 246                                temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
 247                                if (temp & 0xE0) {
 248                                        XGINew_SetRegAND(pVBInfo->P3c4, 0x09, ~0x80); /* DVO Off */
 249                                        XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */
 250                                        /* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* LCD Display OFF */
 251                                }
 252                        }
 253                        if (pXGIHWDE->jChipType == XG27) {
 254                                XGI_DisplayOff(pXGIHWDE, pVBInfo);
 255
 256                                XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */
 257
 258                                temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
 259                                if (temp & 0xE0)
 260                                        XGINew_SetRegAND(pVBInfo->P3c4, 0x09, ~0x80); /* DVO Off */
 261                        }
 262                        XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, ~0xC0, 0xC0);
 263                        XGINew_SetRegOR(pVBInfo->P3c4, 0x01, 0x20); /* CRT Off */
 264
 265                        if ((pXGIHWDE->jChipType == XG21) && (pVBInfo->IF_DEF_LVDS == 1)) {
 266                                XGI_XG21SetPanelDelay(4, pVBInfo);
 267                                XGI_XG21BLSignalVDD(0x01, 0x00, pVBInfo); /* LVDS VDD off */
 268                                XGI_XG21SetPanelDelay(5, pVBInfo);
 269                        }
 270                        if ((pXGIHWDE->jChipType == XG27) && (pVBInfo->IF_DEF_LVDS == 1)) {
 271                                XGI_XG21SetPanelDelay(4, pVBInfo);
 272                                XGI_XG27BLSignalVDD(0x01, 0x00, pVBInfo); /* LVDS VDD off */
 273                                XGI_XG21SetPanelDelay(5, pVBInfo);
 274                        }
 275                }
 276                break;
 277
 278        default:
 279                break;
 280        }
 281        XGI_LockCRT2(pXGIHWDE, pVBInfo);
 282}
 283
 284void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 285{
 286        unsigned short tempax = 0, tempbx, tempcx, temp, P2reg0 = 0, SenseModeNo = 0,
 287                        OutputSelect = *pVBInfo->pOutputSelect, ModeIdIndex, i;
 288        pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
 289
 290        if (pVBInfo->IF_DEF_LVDS == 1) {
 291                tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); /* ynlai 02/27/2002 */
 292                tempbx = XGINew_GetReg1(pVBInfo->P3c4, 0x1B);
 293                tempax = ((tempax & 0xFE) >> 1) | (tempbx << 8);
 294                if (tempax == 0x00) { /* Get Panel id from DDC */
 295                        temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
 296                        if (temp == 1) { /* LCD connect */
 297                                XGINew_SetRegANDOR(pVBInfo->P3d4, 0x39, 0xFF, 0x01); /* set CR39 bit0="1" */
 298                                XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, 0xEF, 0x00); /* clean CR37 bit4="0" */
 299                                temp = LCDSense;
 300                        } else { /* LCD don't connect */
 301                                temp = 0;
 302                        }
 303                } else {
 304                        XGINew_GetPanelID(pVBInfo);
 305                        temp = LCDSense;
 306                }
 307
 308                tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense);
 309                XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, tempbx, temp);
 310        } else { /* for 301 */
 311                if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiVision */
 312                        tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x38);
 313                        temp = tempax & 0x01;
 314                        tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x3A);
 315                        temp = temp | (tempax & 0x02);
 316                        XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xA0, temp);
 317                } else {
 318                        if (XGI_BridgeIsOn(pVBInfo)) {
 319                                P2reg0 = XGINew_GetReg1(pVBInfo->Part2Port, 0x00);
 320                                if (!XGINew_BridgeIsEnable(HwDeviceExtension, pVBInfo)) {
 321                                        SenseModeNo = 0x2e;
 322                                        /* XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x41); */
 323                                        /* XGISetModeNew(HwDeviceExtension, 0x2e); // ynlai InitMode */
 324
 325                                        temp = XGI_SearchModeID(SenseModeNo, &ModeIdIndex, pVBInfo);
 326                                        XGI_GetVGAType(HwDeviceExtension, pVBInfo);
 327                                        XGI_GetVBType(pVBInfo);
 328                                        pVBInfo->SetFlag = 0x00;
 329                                        pVBInfo->ModeType = ModeVGA;
 330                                        pVBInfo->VBInfo = SetCRT2ToRAMDAC | LoadDACFlag | SetInSlaveMode;
 331                                        XGI_GetLCDInfo(0x2e, ModeIdIndex, pVBInfo);
 332                                        XGI_GetTVInfo(0x2e, ModeIdIndex, pVBInfo);
 333                                        XGI_EnableBridge(HwDeviceExtension, pVBInfo);
 334                                        XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo);
 335                                        XGI_SetCRT2ModeRegs(0x2e, HwDeviceExtension, pVBInfo);
 336                                        /* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */
 337                                        XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); /* Display Off 0212 */
 338                                        for (i = 0; i < 20; i++)
 339                                                XGI_LongWait(pVBInfo);
 340                                }
 341                                XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1c);
 342                                tempax = 0;
 343                                tempbx = *pVBInfo->pRGBSenseData;
 344
 345                                if (!(XGINew_Is301B(pVBInfo)))
 346                                        tempbx = *pVBInfo->pRGBSenseData2;
 347
 348                                tempcx = 0x0E08;
 349                                if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
 350                                        if (XGINew_Sense(tempbx, tempcx, pVBInfo))
 351                                                tempax |= Monitor2Sense;
 352                                }
 353
 354                                if (pVBInfo->VBType & VB_XGI301C)
 355                                        XGINew_SetRegOR(pVBInfo->Part4Port, 0x0d, 0x04);
 356
 357                                if (XGINew_SenseHiTV(HwDeviceExtension, pVBInfo)) { /* add by kuku for Multi-adapter sense HiTV */
 358                                        tempax |= HiTVSense;
 359                                        if ((pVBInfo->VBType & VB_XGI301C))
 360                                                tempax ^= (HiTVSense | YPbPrSense);
 361                                }
 362
 363                                if (!(tempax & (HiTVSense | YPbPrSense))) { /* start */
 364
 365                                        tempbx = *pVBInfo->pYCSenseData;
 366
 367                                        if (!(XGINew_Is301B(pVBInfo)))
 368                                                tempbx = *pVBInfo->pYCSenseData2;
 369
 370                                        tempcx = 0x0604;
 371                                        if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
 372                                                if (XGINew_Sense(tempbx, tempcx, pVBInfo))
 373                                                        tempax |= SVIDEOSense;
 374                                        }
 375
 376                                        if (OutputSelect & BoardTVType) {
 377                                                tempbx = *pVBInfo->pVideoSenseData;
 378
 379                                                if (!(XGINew_Is301B(pVBInfo)))
 380                                                        tempbx = *pVBInfo->pVideoSenseData2;
 381
 382                                                tempcx = 0x0804;
 383                                                if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
 384                                                        if (XGINew_Sense(tempbx, tempcx, pVBInfo))
 385                                                                tempax |= AVIDEOSense;
 386                                                }
 387                                        } else {
 388                                                if (!(tempax & SVIDEOSense)) {
 389                                                        tempbx = *pVBInfo->pVideoSenseData;
 390
 391                                                        if (!(XGINew_Is301B(pVBInfo)))
 392                                                                tempbx = *pVBInfo->pVideoSenseData2;
 393
 394                                                        tempcx = 0x0804;
 395                                                        if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
 396                                                                if (XGINew_Sense(tempbx, tempcx, pVBInfo))
 397                                                                        tempax |= AVIDEOSense;
 398                                                        }
 399                                                }
 400                                        }
 401                                }
 402                        } /* end */
 403                        if (!(tempax & Monitor2Sense)) {
 404                                if (XGINew_SenseLCD(HwDeviceExtension, pVBInfo))
 405                                        tempax |= LCDSense;
 406                        }
 407                        tempbx = 0;
 408                        tempcx = 0;
 409                        XGINew_Sense(tempbx, tempcx, pVBInfo);
 410
 411                        XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~0xDF, tempax);
 412                        XGINew_SetReg1(pVBInfo->Part2Port, 0x00, P2reg0);
 413
 414                        if (!(P2reg0 & 0x20)) {
 415                                pVBInfo->VBInfo = DisableCRT2Display;
 416                                /* XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); */
 417                        }
 418                }
 419        }
 420        XGI_DisableBridge(HwDeviceExtension, pVBInfo); /* shampoo 0226 */
 421
 422}
 423
 424unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 425{
 426        /* unsigned short SoftSetting ; */
 427        unsigned short temp;
 428
 429        if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40))
 430                temp = 0;
 431        else
 432                temp = XGINew_GetPanelID(pVBInfo);
 433
 434        if (!temp)
 435                temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
 436
 437        return temp;
 438}
 439
 440unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 441{
 442        unsigned short temp;
 443
 444        /* add lcd sense */
 445        if (HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN) {
 446                return 0;
 447        } else {
 448                temp = (unsigned short) HwDeviceExtension->ulCRT2LCDType;
 449                switch (HwDeviceExtension->ulCRT2LCDType) {
 450                case LCD_INVALID:
 451                case LCD_800x600:
 452                case LCD_1024x768:
 453                case LCD_1280x1024:
 454                        break;
 455
 456                case LCD_640x480:
 457                case LCD_1024x600:
 458                case LCD_1152x864:
 459                case LCD_1280x960:
 460                case LCD_1152x768:
 461                        temp = 0;
 462                        break;
 463
 464                case LCD_1400x1050:
 465                case LCD_1280x768:
 466                case LCD_1600x1200:
 467                        break;
 468
 469                case LCD_1920x1440:
 470                case LCD_2048x1536:
 471                        temp = 0;
 472                        break;
 473
 474                default:
 475                        break;
 476                }
 477                XGINew_SetRegANDOR(pVBInfo->P3d4, 0x36, 0xF0, temp);
 478                return 1;
 479        }
 480}
 481
 482unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo)
 483{
 484        unsigned short PanelTypeTable[16] = { SyncNN | PanelRGB18Bit
 485                        | Panel800x600  | _PanelType00, SyncNN | PanelRGB18Bit
 486                        | Panel1024x768 | _PanelType01, SyncNN | PanelRGB18Bit
 487                        | Panel800x600  | _PanelType02, SyncNN | PanelRGB18Bit
 488                        | Panel640x480  | _PanelType03, SyncNN | PanelRGB18Bit
 489                        | Panel1024x768 | _PanelType04, SyncNN | PanelRGB18Bit
 490                        | Panel1024x768 | _PanelType05, SyncNN | PanelRGB18Bit
 491                        | Panel1024x768 | _PanelType06, SyncNN | PanelRGB24Bit
 492                        | Panel1024x768 | _PanelType07, SyncNN | PanelRGB18Bit
 493                        | Panel800x600  | _PanelType08, SyncNN | PanelRGB18Bit
 494                        | Panel1024x768 | _PanelType09, SyncNN | PanelRGB18Bit
 495                        | Panel800x600  | _PanelType0A, SyncNN | PanelRGB18Bit
 496                        | Panel1024x768 | _PanelType0B, SyncNN | PanelRGB18Bit
 497                        | Panel1024x768 | _PanelType0C, SyncNN | PanelRGB24Bit
 498                        | Panel1024x768 | _PanelType0D, SyncNN | PanelRGB18Bit
 499                        | Panel1024x768 | _PanelType0E, SyncNN | PanelRGB18Bit
 500                        | Panel1024x768 | _PanelType0F };
 501        unsigned short tempax, tempbx, temp;
 502        /* unsigned short return_flag; */
 503
 504        tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x1A);
 505        tempbx = tempax & 0x1E;
 506
 507        if (tempax == 0)
 508                return 0;
 509        else {
 510                /*
 511                if (!(tempax & 0x10)) {
 512                        if (pVBInfo->IF_DEF_LVDS == 1) {
 513                                tempbx = 0;
 514                                temp = XGINew_GetReg1(pVBInfo->P3c4, 0x38);
 515                                if (temp & 0x40)
 516                                        tempbx |= 0x08;
 517                                if (temp & 0x20)
 518                                        tempbx |= 0x02;
 519                                if (temp & 0x01)
 520                                        tempbx |= 0x01;
 521
 522                                temp = XGINew_GetReg1(pVBInfo->P3c4, 0x39);
 523                                if (temp & 0x80)
 524                                        tempbx |= 0x04;
 525                         } else {
 526                                return(0);
 527                         }
 528                }
 529                */
 530
 531                tempbx = tempbx >> 1;
 532                temp = tempbx & 0x00F;
 533                XGINew_SetReg1(pVBInfo->P3d4, 0x36, temp);
 534                tempbx--;
 535                tempbx = PanelTypeTable[tempbx];
 536
 537                temp = (tempbx & 0xFF00) >> 8;
 538                XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~(LCDSyncBit
 539                                | LCDRGB18Bit), temp);
 540                return 1;
 541        }
 542}
 543
 544unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 545{
 546        unsigned short flag;
 547
 548        if (XGI_BridgeIsOn(pVBInfo) == 0) {
 549                flag = XGINew_GetReg1(pVBInfo->Part1Port, 0x0);
 550
 551                if (flag & 0x050)
 552                        return 1;
 553                else
 554                        return 0;
 555
 556        }
 557        return 0;
 558}
 559
 560unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
 561{
 562        unsigned short tempbx, tempcx, temp, i, tempch;
 563
 564        tempbx = *pVBInfo->pYCSenseData2;
 565
 566        tempcx = 0x0604;
 567
 568        temp = tempbx & 0xFF;
 569        XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp);
 570        temp = (tempbx & 0xFF00) >> 8;
 571        temp |= (tempcx & 0x00FF);
 572        XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
 573
 574        for (i = 0; i < 10; i++)
 575                XGI_LongWait(pVBInfo);
 576
 577        tempch = (tempcx & 0xFF00) >> 8;
 578        temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03);
 579        temp = temp ^ (0x0E);
 580        temp &= tempch;
 581
 582        if (temp != tempch)
 583                return 0;
 584
 585        tempbx = *pVBInfo->pVideoSenseData2;
 586
 587        tempcx = 0x0804;
 588        temp = tempbx & 0xFF;
 589        XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp);
 590        temp = (tempbx & 0xFF00) >> 8;
 591        temp |= (tempcx & 0x00FF);
 592        XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
 593
 594        for (i = 0; i < 10; i++)
 595                XGI_LongWait(pVBInfo);
 596
 597        tempch = (tempcx & 0xFF00) >> 8;
 598        temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03);
 599        temp = temp ^ (0x0E);
 600        temp &= tempch;
 601
 602        if (temp != tempch) {
 603                return 0;
 604        } else {
 605                tempbx = 0x3FF;
 606                tempcx = 0x0804;
 607                temp = tempbx & 0xFF;
 608                XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp);
 609                temp = (tempbx & 0xFF00) >> 8;
 610                temp |= (tempcx & 0x00FF);
 611                XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
 612
 613                for (i = 0; i < 10; i++)
 614                        XGI_LongWait(pVBInfo);
 615
 616                tempch = (tempcx & 0xFF00) >> 8;
 617                temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03);
 618                temp = temp ^ (0x0E);
 619                temp &= tempch;
 620
 621                if (temp != tempch)
 622                        return 1;
 623                else
 624                        return 0;
 625        }
 626}
 627
 628/* ----------------------------------------------------------------------------
 629 *       Description: Get Panel support
 630 *      O/P        :
 631 *            BL: Panel ID=81h for no scaler LVDS
 632 *                   BH: Panel enhanced Mode Count
 633 *                   CX: Panel H. resolution
 634 *                   DX: PAnel V. resolution
 635 * ----------------------------------------------------------------------------
 636 */
 637static void XGI_XG21Fun14Sub70(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
 638{
 639        unsigned short ModeIdIndex;
 640        unsigned short ModeNo;
 641
 642        unsigned short EModeCount;
 643        unsigned short lvdstableindex;
 644
 645        lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
 646        pBiosArguments->h.bl = 0x81;
 647        pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE;
 648        pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE;
 649        EModeCount = 0;
 650
 651        pBiosArguments->x.ax = 0x0014;
 652        for (ModeIdIndex = 0;; ModeIdIndex++) {
 653                ModeNo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID;
 654                if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID == 0xFF) {
 655                        pBiosArguments->h.bh = (unsigned char) EModeCount;
 656                        return;
 657                }
 658                if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
 659                        continue;
 660
 661                EModeCount++;
 662        }
 663}
 664
 665/* ----------------------------------------------------------------------------
 666 *
 667 *       Description: Get Panel mode ID for enhanced mode
 668 *      I/P        : BH: EModeIndex ( which < Panel enhanced Mode Count )
 669 *      O/P        :
 670 *            BL: Mode ID
 671 *                   CX: H. resolution of the assigned by the index
 672 *                   DX: V. resolution of the assigned by the index
 673 *
 674 * ----------------------------------------------------------------------------
 675 */
 676
 677static void XGI_XG21Fun14Sub71(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
 678{
 679
 680        unsigned short EModeCount;
 681        unsigned short ModeIdIndex, resindex;
 682        unsigned short ModeNo;
 683        unsigned short EModeIndex = pBiosArguments->h.bh;
 684
 685        EModeCount = 0;
 686        for (ModeIdIndex = 0;; ModeIdIndex++) {
 687                ModeNo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID;
 688                if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID == 0xFF) {
 689                        pBiosArguments->x.ax = 0x0114;
 690                        return;
 691                }
 692                if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
 693                        continue;
 694
 695                if (EModeCount == EModeIndex) {
 696                        resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
 697                        pBiosArguments->h.bl = (unsigned char) ModeNo;
 698                        pBiosArguments->x.cx = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
 699                        pBiosArguments->x.dx = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
 700                        pBiosArguments->x.ax = 0x0014;
 701                }
 702                EModeCount++;
 703
 704        }
 705
 706}
 707
 708/* ----------------------------------------------------------------------------
 709 *
 710 *       Description: Validate Panel modes ID support
 711 *      I/P        :
 712 *            BL: ModeID
 713 *      O/P        :
 714 *                   CX: H. resolution of the assigned by the index
 715 *                   DX: V. resolution of the assigned by the index
 716 *
 717 * ----------------------------------------------------------------------------
 718 */
 719static void XGI_XG21Fun14Sub72(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
 720{
 721        unsigned short ModeIdIndex, resindex;
 722        unsigned short ModeNo;
 723
 724        ModeNo = pBiosArguments->h.bl;
 725        XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo);
 726        if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo)) {
 727                pBiosArguments->x.cx = 0;
 728                pBiosArguments->x.dx = 0;
 729                pBiosArguments->x.ax = 0x0114;
 730                return;
 731        }
 732        resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
 733        if (ModeNo <= 0x13) {
 734                pBiosArguments->x.cx = pVBInfo->StResInfo[resindex].HTotal;
 735                pBiosArguments->x.dx = pVBInfo->StResInfo[resindex].VTotal;
 736        } else {
 737                pBiosArguments->x.cx = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
 738                pBiosArguments->x.dx = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
 739        }
 740
 741        pBiosArguments->x.ax = 0x0014;
 742
 743}
 744
 745/* ----------------------------------------------------------------------------
 746 *
 747 *      Description: Get Customized Panel misc. information support
 748 *      I/P        : Select
 749 *                   to get panel horizontal timing
 750 *                       to get panel vertical timing
 751 *                       to get channel clock parameter
 752 *            to get panel misc information
 753 *
 754 *      O/P        :
 755 *                   BL: for input Select = 0 ;
 756 *                       BX: *Value1 = Horizontal total
 757 *                       CX: *Value2 = Horizontal front porch
 758 *                       DX: *Value2 = Horizontal sync width
 759 *                   BL: for input Select = 1 ;
 760 *                       BX: *Value1 = Vertical total
 761 *                       CX: *Value2 = Vertical front porch
 762 *                       DX: *Value2 = Vertical sync width
 763 *            BL: for input Select = 2 ;
 764 *                       BX: Value1 = The first CLK parameter
 765 *                       CX: Value2 = The second CLK parameter
 766 *                   BL: for input Select = 4 ;
 767 *                       BX[15]: *Value1 D[15] VESA V. Polarity
 768 *                       BX[14]: *Value1 D[14] VESA H. Polarity
 769 *                       BX[7]: *Value1 D[7] Panel V. Polarity
 770 *                       BX[6]: *Value1 D[6] Panel H. Polarity
 771 * ----------------------------------------------------------------------------
 772 */
 773static void XGI_XG21Fun14Sub73(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments)
 774{
 775        unsigned char Select;
 776
 777        unsigned short lvdstableindex;
 778
 779        lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
 780        Select = pBiosArguments->h.bl;
 781
 782        switch (Select) {
 783        case 0:
 784                pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
 785                pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP;
 786                pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC;
 787                break;
 788        case 1:
 789                pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
 790                pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP;
 791                pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
 792                break;
 793        case 2:
 794                pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1;
 795                pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2;
 796                break;
 797        case 4:
 798                pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability;
 799                break;
 800        }
 801
 802        pBiosArguments->x.ax = 0x0014;
 803}
 804
 805void XGI_XG21Fun14(struct xgi_hw_device_info *pXGIHWDE, PX86_REGS pBiosArguments)
 806{
 807        struct vb_device_info VBINF;
 808        struct vb_device_info *pVBInfo = &VBINF;
 809
 810        pVBInfo->IF_DEF_LVDS = 0;
 811        pVBInfo->IF_DEF_CH7005 = 0;
 812        pVBInfo->IF_DEF_HiVision = 1;
 813        pVBInfo->IF_DEF_LCDA = 1;
 814        pVBInfo->IF_DEF_CH7017 = 0;
 815        pVBInfo->IF_DEF_YPbPr = 1;
 816        pVBInfo->IF_DEF_CRT2Monitor = 0;
 817        pVBInfo->IF_DEF_VideoCapture = 0;
 818        pVBInfo->IF_DEF_ScaleLCD = 0;
 819        pVBInfo->IF_DEF_OEMUtil = 0;
 820        pVBInfo->IF_DEF_PWD = 0;
 821
 822        InitTo330Pointer(pXGIHWDE->jChipType, pVBInfo);
 823        ReadVBIOSTablData(pXGIHWDE->jChipType, pVBInfo);
 824
 825        pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
 826        pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
 827        pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
 828        pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
 829        pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
 830        pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
 831        pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
 832        pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
 833        pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
 834        pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
 835        pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
 836        pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
 837        pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
 838        pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
 839        pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
 840        pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
 841        pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
 842
 843        switch (pBiosArguments->x.ax) {
 844        case 0x1470:
 845                XGI_XG21Fun14Sub70(pVBInfo, pBiosArguments);
 846                break;
 847        case 0x1471:
 848                XGI_XG21Fun14Sub71(pVBInfo, pBiosArguments);
 849                break;
 850        case 0x1472:
 851                XGI_XG21Fun14Sub72(pVBInfo, pBiosArguments);
 852                break;
 853        case 0x1473:
 854                XGI_XG21Fun14Sub73(pVBInfo, pBiosArguments);
 855                break;
 856        }
 857}
 858