linux/drivers/staging/xgifb/XGI_main_26.c
<<
>>
Prefs
   1/*
   2 * XG20, XG21, XG40, XG42 frame buffer device
   3 * for Linux kernels  2.5.x, 2.6.x
   4 * Base on TW's sis fbdev code.
   5 */
   6
   7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   8
   9#include <linux/sizes.h>
  10#include <linux/module.h>
  11#include <linux/pci.h>
  12
  13#include "XGI_main.h"
  14#include "vb_init.h"
  15#include "vb_util.h"
  16#include "vb_setmode.h"
  17
  18#define Index_CR_GPIO_Reg1 0x48
  19#define Index_CR_GPIO_Reg3 0x4a
  20
  21#define GPIOG_EN    BIT(6)
  22#define GPIOG_READ  BIT(1)
  23
  24static char *forcecrt2type;
  25static char *mode;
  26static int vesa = -1;
  27static unsigned int refresh_rate;
  28
  29/* -------------------- Macro definitions ---------------------------- */
  30
  31#ifdef DEBUG
  32static void dumpVGAReg(struct xgifb_video_info *xgifb_info)
  33{
  34        u8 i, reg;
  35
  36        xgifb_reg_set(XGISR, 0x05, 0x86);
  37
  38        for (i = 0; i < 0x4f; i++) {
  39                reg = xgifb_reg_get(XGISR, i);
  40                pr_debug("o 3c4 %x\n", i);
  41                pr_debug("i 3c5 => %x\n", reg);
  42        }
  43
  44        for (i = 0; i < 0xF0; i++) {
  45                reg = xgifb_reg_get(XGICR, i);
  46                pr_debug("o 3d4 %x\n", i);
  47                pr_debug("i 3d5 => %x\n", reg);
  48        }
  49}
  50#else
  51static inline void dumpVGAReg(struct xgifb_video_info *xgifb_info)
  52{
  53}
  54#endif
  55
  56/* --------------- Hardware Access Routines -------------------------- */
  57
  58static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
  59                                     struct xgi_hw_device_info *HwDeviceExtension,
  60                                     unsigned char modeno)
  61{
  62        unsigned short ModeNo = modeno;
  63        unsigned short ModeIdIndex = 0, ClockIndex = 0;
  64        unsigned short RefreshRateTableIndex = 0;
  65
  66        InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
  67
  68        XGI_SearchModeID(ModeNo, &ModeIdIndex);
  69
  70        RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
  71                                                   ModeIdIndex, XGI_Pr);
  72
  73        ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  74
  75        return XGI_VCLKData[ClockIndex].CLOCK * 1000;
  76}
  77
  78static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
  79                                    struct xgi_hw_device_info *HwDeviceExtension,
  80                                    unsigned char modeno, u32 *left_margin,
  81                                    u32 *right_margin, u32 *upper_margin,
  82                                    u32 *lower_margin, u32 *hsync_len,
  83                                    u32 *vsync_len, u32 *sync, u32 *vmode)
  84{
  85        unsigned short ModeNo = modeno;
  86        unsigned short ModeIdIndex, index = 0;
  87        unsigned short RefreshRateTableIndex = 0;
  88
  89        unsigned short VRE, VBE, VRS, VDE;
  90        unsigned short HRE, HBE, HRS, HDE;
  91        unsigned char sr_data, cr_data, cr_data2;
  92        int B, C, D, F, temp, j;
  93
  94        InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
  95        if (!XGI_SearchModeID(ModeNo, &ModeIdIndex))
  96                return 0;
  97        RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
  98                                                   ModeIdIndex, XGI_Pr);
  99        index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 100
 101        sr_data = XGI_CRT1Table[index].CR[5];
 102
 103        HDE = XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3;
 104
 105        cr_data = XGI_CRT1Table[index].CR[3];
 106
 107        /* Horizontal retrace (=sync) start */
 108        HRS = (cr_data & 0xff) | ((unsigned short)(sr_data & 0xC0) << 2);
 109        F = HRS - HDE - 3;
 110
 111        sr_data = XGI_CRT1Table[index].CR[6];
 112
 113        cr_data = XGI_CRT1Table[index].CR[2];
 114
 115        cr_data2 = XGI_CRT1Table[index].CR[4];
 116
 117        /* Horizontal blank end */
 118        HBE = (cr_data & 0x1f) | ((unsigned short)(cr_data2 & 0x80) >> 2)
 119                        | ((unsigned short)(sr_data & 0x03) << 6);
 120
 121        /* Horizontal retrace (=sync) end */
 122        HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
 123
 124        temp = HBE - ((HDE - 1) & 255);
 125        B = (temp > 0) ? temp : (temp + 256);
 126
 127        temp = HRE - ((HDE + F + 3) & 63);
 128        C = (temp > 0) ? temp : (temp + 64);
 129
 130        D = B - F - C;
 131
 132        *left_margin = D * 8;
 133        *right_margin = F * 8;
 134        *hsync_len = C * 8;
 135
 136        sr_data = XGI_CRT1Table[index].CR[14];
 137
 138        cr_data2 = XGI_CRT1Table[index].CR[9];
 139
 140        VDE = XGI330_RefIndex[RefreshRateTableIndex].YRes;
 141
 142        cr_data = XGI_CRT1Table[index].CR[10];
 143
 144        /* Vertical retrace (=sync) start */
 145        VRS = (cr_data & 0xff) | ((unsigned short)(cr_data2 & 0x04) << 6)
 146                        | ((unsigned short)(cr_data2 & 0x80) << 2)
 147                        | ((unsigned short)(sr_data & 0x08) << 7);
 148        F = VRS + 1 - VDE;
 149
 150        cr_data = XGI_CRT1Table[index].CR[13];
 151
 152        /* Vertical blank end */
 153        VBE = (cr_data & 0xff) | ((unsigned short)(sr_data & 0x10) << 4);
 154        temp = VBE - ((VDE - 1) & 511);
 155        B = (temp > 0) ? temp : (temp + 512);
 156
 157        cr_data = XGI_CRT1Table[index].CR[11];
 158
 159        /* Vertical retrace (=sync) end */
 160        VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
 161        temp = VRE - ((VDE + F - 1) & 31);
 162        C = (temp > 0) ? temp : (temp + 32);
 163
 164        D = B - F - C;
 165
 166        *upper_margin = D;
 167        *lower_margin = F;
 168        *vsync_len = C;
 169
 170        if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
 171                *sync &= ~FB_SYNC_VERT_HIGH_ACT;
 172        else
 173                *sync |= FB_SYNC_VERT_HIGH_ACT;
 174
 175        if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
 176                *sync &= ~FB_SYNC_HOR_HIGH_ACT;
 177        else
 178                *sync |= FB_SYNC_HOR_HIGH_ACT;
 179
 180        *vmode = FB_VMODE_NONINTERLACED;
 181        if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
 182                *vmode = FB_VMODE_INTERLACED;
 183        else {
 184                j = 0;
 185                while (XGI330_EModeIDTable[j].Ext_ModeID != 0xff) {
 186                        if (XGI330_EModeIDTable[j].Ext_ModeID ==
 187                            XGI330_RefIndex[RefreshRateTableIndex].ModeID) {
 188                                if (XGI330_EModeIDTable[j].Ext_ModeFlag &
 189                                    DoubleScanMode) {
 190                                        *vmode = FB_VMODE_DOUBLE;
 191                                }
 192                                break;
 193                        }
 194                        j++;
 195                }
 196        }
 197
 198        return 1;
 199}
 200
 201void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
 202{
 203        XGI_Pr->P3c4 = BaseAddr + 0x14;
 204        XGI_Pr->P3d4 = BaseAddr + 0x24;
 205        XGI_Pr->P3c0 = BaseAddr + 0x10;
 206        XGI_Pr->P3ce = BaseAddr + 0x1e;
 207        XGI_Pr->P3c2 = BaseAddr + 0x12;
 208        XGI_Pr->P3cc = BaseAddr + 0x1c;
 209        XGI_Pr->P3ca = BaseAddr + 0x1a;
 210        XGI_Pr->P3c6 = BaseAddr + 0x16;
 211        XGI_Pr->P3c7 = BaseAddr + 0x17;
 212        XGI_Pr->P3c8 = BaseAddr + 0x18;
 213        XGI_Pr->P3c9 = BaseAddr + 0x19;
 214        XGI_Pr->P3da = BaseAddr + 0x2A;
 215        XGI_Pr->Part0Port = BaseAddr + XGI_CRT2_PORT_00;
 216        /* Digital video interface registers (LCD) */
 217        XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04;
 218        /* 301 TV Encoder registers */
 219        XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10;
 220        /* 301 Macrovision registers */
 221        XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12;
 222        /* 301 VGA2 (and LCD) registers */
 223        XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14;
 224        /* 301 palette address port registers */
 225        XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
 226}
 227
 228/* ------------------ Internal helper routines ----------------- */
 229
 230static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info)
 231{
 232        int i = 0;
 233
 234        while ((XGIbios_mode[i].mode_no != 0) &&
 235               (XGIbios_mode[i].xres <= xgifb_info->lvds_data.LVDSHDE)) {
 236                if ((XGIbios_mode[i].xres == xgifb_info->lvds_data.LVDSHDE) &&
 237                    (XGIbios_mode[i].yres == xgifb_info->lvds_data.LVDSVDE) &&
 238                    (XGIbios_mode[i].bpp == 8)) {
 239                        return i;
 240                }
 241                i++;
 242        }
 243
 244        return -1;
 245}
 246
 247static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info,
 248                              const char *name)
 249{
 250        unsigned int xres;
 251        unsigned int yres;
 252        unsigned int bpp;
 253        int i;
 254
 255        if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3)
 256                goto invalid_mode;
 257
 258        if (bpp == 24)
 259                bpp = 32; /* That's for people who mix up color and fb depth. */
 260
 261        for (i = 0; XGIbios_mode[i].mode_no != 0; i++)
 262                if (XGIbios_mode[i].xres == xres &&
 263                    XGIbios_mode[i].yres == yres &&
 264                    XGIbios_mode[i].bpp == bpp) {
 265                        xgifb_info->mode_idx = i;
 266                        return;
 267                }
 268invalid_mode:
 269        pr_info("Invalid mode '%s'\n", name);
 270}
 271
 272static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info,
 273                                  unsigned int vesamode)
 274{
 275        int i = 0;
 276
 277        if (vesamode == 0)
 278                goto invalid;
 279
 280        vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
 281
 282        while (XGIbios_mode[i].mode_no != 0) {
 283                if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
 284                    (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
 285                        xgifb_info->mode_idx = i;
 286                        return;
 287                }
 288                i++;
 289        }
 290
 291invalid:
 292        pr_info("Invalid VESA mode 0x%x'\n", vesamode);
 293}
 294
 295static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
 296{
 297        u16 xres, yres;
 298        struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
 299        unsigned long required_mem;
 300
 301        if (xgifb_info->chip == XG21) {
 302                if (xgifb_info->display2 == XGIFB_DISP_LCD) {
 303                        xres = xgifb_info->lvds_data.LVDSHDE;
 304                        yres = xgifb_info->lvds_data.LVDSVDE;
 305                        if (XGIbios_mode[myindex].xres > xres)
 306                                return -1;
 307                        if (XGIbios_mode[myindex].yres > yres)
 308                                return -1;
 309                        if ((XGIbios_mode[myindex].xres < xres) &&
 310                            (XGIbios_mode[myindex].yres < yres)) {
 311                                if (XGIbios_mode[myindex].bpp > 8)
 312                                        return -1;
 313                        }
 314                }
 315                goto check_memory;
 316        }
 317
 318        /* FIXME: for now, all is valid on XG27 */
 319        if (xgifb_info->chip == XG27)
 320                goto check_memory;
 321
 322        if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
 323                return -1;
 324
 325        switch (xgifb_info->display2) {
 326        case XGIFB_DISP_LCD:
 327                switch (hw_info->ulCRT2LCDType) {
 328                case LCD_640x480:
 329                        xres = 640;
 330                        yres = 480;
 331                        break;
 332                case LCD_800x600:
 333                        xres = 800;
 334                        yres = 600;
 335                        break;
 336                case LCD_1024x600:
 337                        xres = 1024;
 338                        yres = 600;
 339                        break;
 340                case LCD_1024x768:
 341                        xres = 1024;
 342                        yres = 768;
 343                        break;
 344                case LCD_1152x768:
 345                        xres = 1152;
 346                        yres = 768;
 347                        break;
 348                case LCD_1280x960:
 349                        xres = 1280;
 350                        yres = 960;
 351                        break;
 352                case LCD_1280x768:
 353                        xres = 1280;
 354                        yres = 768;
 355                        break;
 356                case LCD_1280x1024:
 357                        xres = 1280;
 358                        yres = 1024;
 359                        break;
 360                case LCD_1400x1050:
 361                        xres = 1400;
 362                        yres = 1050;
 363                        break;
 364                case LCD_1600x1200:
 365                        xres = 1600;
 366                        yres = 1200;
 367                        break;
 368                default:
 369                        xres = 0;
 370                        yres = 0;
 371                        break;
 372                }
 373                if (XGIbios_mode[myindex].xres > xres)
 374                        return -1;
 375                if (XGIbios_mode[myindex].yres > yres)
 376                        return -1;
 377                if ((hw_info->ulExternalChip == 0x01) || /* LVDS */
 378                    (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */
 379                        switch (XGIbios_mode[myindex].xres) {
 380                        case 512:
 381                                if (XGIbios_mode[myindex].yres != 512)
 382                                        return -1;
 383                                if (hw_info->ulCRT2LCDType == LCD_1024x600)
 384                                        return -1;
 385                                break;
 386                        case 640:
 387                                if ((XGIbios_mode[myindex].yres != 400) &&
 388                                    (XGIbios_mode[myindex].yres != 480))
 389                                        return -1;
 390                                break;
 391                        case 800:
 392                                if (XGIbios_mode[myindex].yres != 600)
 393                                        return -1;
 394                                break;
 395                        case 1024:
 396                                if ((XGIbios_mode[myindex].yres != 600) &&
 397                                    (XGIbios_mode[myindex].yres != 768))
 398                                        return -1;
 399                                if ((XGIbios_mode[myindex].yres == 600) &&
 400                                    (hw_info->ulCRT2LCDType != LCD_1024x600))
 401                                        return -1;
 402                                break;
 403                        case 1152:
 404                                if ((XGIbios_mode[myindex].yres) != 768)
 405                                        return -1;
 406                                if (hw_info->ulCRT2LCDType != LCD_1152x768)
 407                                        return -1;
 408                                break;
 409                        case 1280:
 410                                if ((XGIbios_mode[myindex].yres != 768) &&
 411                                    (XGIbios_mode[myindex].yres != 1024))
 412                                        return -1;
 413                                if ((XGIbios_mode[myindex].yres == 768) &&
 414                                    (hw_info->ulCRT2LCDType != LCD_1280x768))
 415                                        return -1;
 416                                break;
 417                        case 1400:
 418                                if (XGIbios_mode[myindex].yres != 1050)
 419                                        return -1;
 420                                break;
 421                        case 1600:
 422                                if (XGIbios_mode[myindex].yres != 1200)
 423                                        return -1;
 424                                break;
 425                        default:
 426                                return -1;
 427                        }
 428                } else {
 429                        switch (XGIbios_mode[myindex].xres) {
 430                        case 512:
 431                                if (XGIbios_mode[myindex].yres != 512)
 432                                        return -1;
 433                                break;
 434                        case 640:
 435                                if ((XGIbios_mode[myindex].yres != 400) &&
 436                                    (XGIbios_mode[myindex].yres != 480))
 437                                        return -1;
 438                                break;
 439                        case 800:
 440                                if (XGIbios_mode[myindex].yres != 600)
 441                                        return -1;
 442                                break;
 443                        case 1024:
 444                                if (XGIbios_mode[myindex].yres != 768)
 445                                        return -1;
 446                                break;
 447                        case 1280:
 448                                if ((XGIbios_mode[myindex].yres != 960) &&
 449                                    (XGIbios_mode[myindex].yres != 1024))
 450                                        return -1;
 451                                if (XGIbios_mode[myindex].yres == 960) {
 452                                        if (hw_info->ulCRT2LCDType ==
 453                                            LCD_1400x1050)
 454                                                return -1;
 455                                }
 456                                break;
 457                        case 1400:
 458                                if (XGIbios_mode[myindex].yres != 1050)
 459                                        return -1;
 460                                break;
 461                        case 1600:
 462                                if (XGIbios_mode[myindex].yres != 1200)
 463                                        return -1;
 464                                break;
 465                        default:
 466                                return -1;
 467                        }
 468                }
 469                break;
 470        case XGIFB_DISP_TV:
 471                switch (XGIbios_mode[myindex].xres) {
 472                case 512:
 473                case 640:
 474                case 800:
 475                        break;
 476                case 720:
 477                        if (xgifb_info->TV_type == TVMODE_NTSC) {
 478                                if (XGIbios_mode[myindex].yres != 480)
 479                                        return -1;
 480                        } else if (xgifb_info->TV_type == TVMODE_PAL) {
 481                                if (XGIbios_mode[myindex].yres != 576)
 482                                        return -1;
 483                        }
 484                        /* LVDS/CHRONTEL does not support 720 */
 485                        if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL ||
 486                            xgifb_info->hasVB == HASVB_CHRONTEL) {
 487                                return -1;
 488                        }
 489                        break;
 490                case 1024:
 491                        if (xgifb_info->TV_type == TVMODE_NTSC) {
 492                                if (XGIbios_mode[myindex].bpp == 32)
 493                                        return -1;
 494                        }
 495                        break;
 496                default:
 497                        return -1;
 498                }
 499                break;
 500        case XGIFB_DISP_CRT:
 501                if (XGIbios_mode[myindex].xres > 1280)
 502                        return -1;
 503                break;
 504        case XGIFB_DISP_NONE:
 505                break;
 506        }
 507
 508check_memory:
 509        required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres *
 510                       XGIbios_mode[myindex].bpp / 8;
 511        if (required_mem > xgifb_info->video_size)
 512                return -1;
 513        return myindex;
 514}
 515
 516static void XGIfb_search_crt2type(const char *name)
 517{
 518        int i = 0;
 519
 520        if (!name)
 521                return;
 522
 523        while (XGI_crt2type[i].type_no != -1) {
 524                if (!strcmp(name, XGI_crt2type[i].name)) {
 525                        XGIfb_crt2type = XGI_crt2type[i].type_no;
 526                        XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
 527                        break;
 528                }
 529                i++;
 530        }
 531        if (XGIfb_crt2type < 0)
 532                pr_info("Invalid CRT2 type: %s\n", name);
 533}
 534
 535static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info,
 536                                    unsigned int rate)
 537{
 538        u16 xres, yres;
 539        int i = 0;
 540
 541        xres = XGIbios_mode[xgifb_info->mode_idx].xres;
 542        yres = XGIbios_mode[xgifb_info->mode_idx].yres;
 543
 544        xgifb_info->rate_idx = 0;
 545        while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
 546                if ((XGIfb_vrate[i].xres == xres) &&
 547                    (XGIfb_vrate[i].yres == yres)) {
 548                        if (XGIfb_vrate[i].refresh == rate) {
 549                                xgifb_info->rate_idx = XGIfb_vrate[i].idx;
 550                                break;
 551                        } else if (XGIfb_vrate[i].refresh > rate) {
 552                                if ((XGIfb_vrate[i].refresh - rate) <= 3) {
 553                                        pr_debug("Adjusting rate from %d up to %d\n",
 554                                                 rate, XGIfb_vrate[i].refresh);
 555                                        xgifb_info->rate_idx =
 556                                                XGIfb_vrate[i].idx;
 557                                        xgifb_info->refresh_rate =
 558                                                XGIfb_vrate[i].refresh;
 559                                } else if (((rate - XGIfb_vrate[i - 1].refresh)
 560                                                <= 2) && (XGIfb_vrate[i].idx
 561                                                != 1)) {
 562                                        pr_debug("Adjusting rate from %d down to %d\n",
 563                                                 rate,
 564                                                 XGIfb_vrate[i - 1].refresh);
 565                                        xgifb_info->rate_idx =
 566                                                XGIfb_vrate[i - 1].idx;
 567                                        xgifb_info->refresh_rate =
 568                                                XGIfb_vrate[i - 1].refresh;
 569                                }
 570                                break;
 571                        } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
 572                                pr_debug("Adjusting rate from %d down to %d\n",
 573                                         rate, XGIfb_vrate[i].refresh);
 574                                xgifb_info->rate_idx = XGIfb_vrate[i].idx;
 575                                break;
 576                        }
 577                }
 578                i++;
 579        }
 580        if (xgifb_info->rate_idx > 0)
 581                return xgifb_info->rate_idx;
 582        pr_info("Unsupported rate %d for %dx%d\n",
 583                rate, xres, yres);
 584        return 0;
 585}
 586
 587static void XGIfb_search_tvstd(const char *name)
 588{
 589        int i = 0;
 590
 591        if (!name)
 592                return;
 593
 594        while (XGI_tvtype[i].type_no != -1) {
 595                if (!strcmp(name, XGI_tvtype[i].name)) {
 596                        XGIfb_tvmode = XGI_tvtype[i].type_no;
 597                        break;
 598                }
 599                i++;
 600        }
 601}
 602
 603/* ----------- FBDev related routines for all series ----------- */
 604
 605static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info,
 606                             struct fb_var_screeninfo *var)
 607{
 608        switch (var->bits_per_pixel) {
 609        case 8:
 610                var->red.offset = 0;
 611                var->green.offset = 0;
 612                var->blue.offset = 0;
 613                var->red.length = 6;
 614                var->green.length = 6;
 615                var->blue.length = 6;
 616                xgifb_info->video_cmap_len = 256;
 617                break;
 618        case 16:
 619                var->red.offset = 11;
 620                var->red.length = 5;
 621                var->green.offset = 5;
 622                var->green.length = 6;
 623                var->blue.offset = 0;
 624                var->blue.length = 5;
 625                var->transp.offset = 0;
 626                var->transp.length = 0;
 627                xgifb_info->video_cmap_len = 16;
 628                break;
 629        case 32:
 630                var->red.offset = 16;
 631                var->red.length = 8;
 632                var->green.offset = 8;
 633                var->green.length = 8;
 634                var->blue.offset = 0;
 635                var->blue.length = 8;
 636                var->transp.offset = 24;
 637                var->transp.length = 8;
 638                xgifb_info->video_cmap_len = 16;
 639                break;
 640        }
 641}
 642
 643/* --------------------- SetMode routines ------------------------- */
 644
 645static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info)
 646{
 647        u8 cr30 = 0, cr31 = 0;
 648
 649        cr31 = xgifb_reg_get(XGICR, 0x31);
 650        cr31 &= ~0x60;
 651
 652        switch (xgifb_info->display2) {
 653        case XGIFB_DISP_CRT:
 654                cr30 = SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE;
 655                cr31 |= SIS_DRIVER_MODE;
 656                break;
 657        case XGIFB_DISP_LCD:
 658                cr30 = SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE;
 659                cr31 |= SIS_DRIVER_MODE;
 660                break;
 661        case XGIFB_DISP_TV:
 662                if (xgifb_info->TV_type == TVMODE_HIVISION)
 663                        cr30 = SIS_VB_OUTPUT_HIVISION
 664                                        | SIS_SIMULTANEOUS_VIEW_ENABLE;
 665                else if (xgifb_info->TV_plug == TVPLUG_SVIDEO)
 666                        cr30 = SIS_VB_OUTPUT_SVIDEO
 667                                        | SIS_SIMULTANEOUS_VIEW_ENABLE;
 668                else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE)
 669                        cr30 = SIS_VB_OUTPUT_COMPOSITE
 670                                        | SIS_SIMULTANEOUS_VIEW_ENABLE;
 671                else if (xgifb_info->TV_plug == TVPLUG_SCART)
 672                        cr30 = SIS_VB_OUTPUT_SCART
 673                                        | SIS_SIMULTANEOUS_VIEW_ENABLE;
 674                cr31 |= SIS_DRIVER_MODE;
 675
 676                if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL)
 677                        cr31 |= 0x01;
 678                else
 679                        cr31 &= ~0x01;
 680                break;
 681        default: /* disable CRT2 */
 682                cr30 = 0x00;
 683                cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
 684        }
 685
 686        xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
 687        xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
 688        xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33,
 689                      (xgifb_info->rate_idx & 0x0F));
 690}
 691
 692static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
 693{
 694        u8 reg;
 695        unsigned char doit = 1;
 696
 697        if (xgifb_info->video_bpp == 8) {
 698                /*
 699                 * We can't switch off CRT1 on LVDS/Chrontel
 700                 * in 8bpp Modes
 701                 */
 702                if ((xgifb_info->hasVB == HASVB_LVDS) ||
 703                    (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) {
 704                        doit = 0;
 705                }
 706                /*
 707                 * We can't switch off CRT1 on 301B-DH
 708                 * in 8bpp Modes if using LCD
 709                 */
 710                if (xgifb_info->display2 == XGIFB_DISP_LCD)
 711                        doit = 0;
 712        }
 713
 714        /* We can't switch off CRT1 if bridge is in slave mode */
 715        if (xgifb_info->hasVB != HASVB_NONE) {
 716                reg = xgifb_reg_get(XGIPART1, 0x00);
 717
 718                if ((reg & 0x50) == 0x10)
 719                        doit = 0;
 720
 721        } else {
 722                XGIfb_crt1off = 0;
 723        }
 724
 725        reg = xgifb_reg_get(XGICR, 0x17);
 726        if ((XGIfb_crt1off) && (doit))
 727                reg &= ~0x80;
 728        else
 729                reg |= 0x80;
 730        xgifb_reg_set(XGICR, 0x17, reg);
 731
 732        xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04);
 733
 734        if (xgifb_info->display2 == XGIFB_DISP_TV &&
 735            xgifb_info->hasVB == HASVB_301) {
 736                reg = xgifb_reg_get(XGIPART4, 0x01);
 737
 738                if (reg < 0xB0) { /* Set filter for XGI301 */
 739                        int filter_tb;
 740
 741                        switch (xgifb_info->video_width) {
 742                        case 320:
 743                                filter_tb = (xgifb_info->TV_type ==
 744                                             TVMODE_NTSC) ? 4 : 12;
 745                                break;
 746                        case 640:
 747                                filter_tb = (xgifb_info->TV_type ==
 748                                             TVMODE_NTSC) ? 5 : 13;
 749                                break;
 750                        case 720:
 751                                filter_tb = (xgifb_info->TV_type ==
 752                                             TVMODE_NTSC) ? 6 : 14;
 753                                break;
 754                        case 800:
 755                                filter_tb = (xgifb_info->TV_type ==
 756                                             TVMODE_NTSC) ? 7 : 15;
 757                                break;
 758                        default:
 759                                filter_tb = 0;
 760                                filter = -1;
 761                                break;
 762                        }
 763                        xgifb_reg_or(XGIPART1,
 764                                     SIS_CRT2_WENABLE_315,
 765                                     0x01);
 766
 767                        if (xgifb_info->TV_type == TVMODE_NTSC) {
 768                                xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
 769
 770                                if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
 771                                        xgifb_reg_and(XGIPART2, 0x30, 0xdf);
 772
 773                                } else if (xgifb_info->TV_plug
 774                                                == TVPLUG_COMPOSITE) {
 775                                        xgifb_reg_or(XGIPART2, 0x30, 0x20);
 776
 777                                        switch (xgifb_info->video_width) {
 778                                        case 640:
 779                                                xgifb_reg_set(XGIPART2,
 780                                                              0x35,
 781                                                              0xEB);
 782                                                xgifb_reg_set(XGIPART2,
 783                                                              0x36,
 784                                                              0x04);
 785                                                xgifb_reg_set(XGIPART2,
 786                                                              0x37,
 787                                                              0x25);
 788                                                xgifb_reg_set(XGIPART2,
 789                                                              0x38,
 790                                                              0x18);
 791                                                break;
 792                                        case 720:
 793                                                xgifb_reg_set(XGIPART2,
 794                                                              0x35,
 795                                                              0xEE);
 796                                                xgifb_reg_set(XGIPART2,
 797                                                              0x36,
 798                                                              0x0C);
 799                                                xgifb_reg_set(XGIPART2,
 800                                                              0x37,
 801                                                              0x22);
 802                                                xgifb_reg_set(XGIPART2,
 803                                                              0x38,
 804                                                              0x08);
 805                                                break;
 806                                        case 800:
 807                                                xgifb_reg_set(XGIPART2,
 808                                                              0x35,
 809                                                              0xEB);
 810                                                xgifb_reg_set(XGIPART2,
 811                                                              0x36,
 812                                                              0x15);
 813                                                xgifb_reg_set(XGIPART2,
 814                                                              0x37,
 815                                                              0x25);
 816                                                xgifb_reg_set(XGIPART2,
 817                                                              0x38,
 818                                                              0xF6);
 819                                                break;
 820                                        }
 821                                }
 822
 823                        } else if (xgifb_info->TV_type == TVMODE_PAL) {
 824                                xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
 825
 826                                if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
 827                                        xgifb_reg_and(XGIPART2, 0x30, 0xDF);
 828
 829                                } else if (xgifb_info->TV_plug
 830                                                == TVPLUG_COMPOSITE) {
 831                                        xgifb_reg_or(XGIPART2, 0x30, 0x20);
 832
 833                                        switch (xgifb_info->video_width) {
 834                                        case 640:
 835                                                xgifb_reg_set(XGIPART2,
 836                                                              0x35,
 837                                                              0xF1);
 838                                                xgifb_reg_set(XGIPART2,
 839                                                              0x36,
 840                                                              0xF7);
 841                                                xgifb_reg_set(XGIPART2,
 842                                                              0x37,
 843                                                              0x1F);
 844                                                xgifb_reg_set(XGIPART2,
 845                                                              0x38,
 846                                                              0x32);
 847                                                break;
 848                                        case 720:
 849                                                xgifb_reg_set(XGIPART2,
 850                                                              0x35,
 851                                                              0xF3);
 852                                                xgifb_reg_set(XGIPART2,
 853                                                              0x36,
 854                                                              0x00);
 855                                                xgifb_reg_set(XGIPART2,
 856                                                              0x37,
 857                                                              0x1D);
 858                                                xgifb_reg_set(XGIPART2,
 859                                                              0x38,
 860                                                              0x20);
 861                                                break;
 862                                        case 800:
 863                                                xgifb_reg_set(XGIPART2,
 864                                                              0x35,
 865                                                              0xFC);
 866                                                xgifb_reg_set(XGIPART2,
 867                                                              0x36,
 868                                                              0xFB);
 869                                                xgifb_reg_set(XGIPART2,
 870                                                              0x37,
 871                                                              0x14);
 872                                                xgifb_reg_set(XGIPART2,
 873                                                              0x38,
 874                                                              0x2A);
 875                                                break;
 876                                        }
 877                                }
 878                        }
 879
 880                        if ((filter >= 0) && (filter <= 7)) {
 881                                pr_debug("FilterTable[%d]-%d: %*ph\n",
 882                                         filter_tb, filter,
 883                                         4, XGI_TV_filter[filter_tb].
 884                                                   filter[filter]);
 885                                xgifb_reg_set(
 886                                        XGIPART2,
 887                                        0x35,
 888                                        (XGI_TV_filter[filter_tb].
 889                                                filter[filter][0]));
 890                                xgifb_reg_set(
 891                                        XGIPART2,
 892                                        0x36,
 893                                        (XGI_TV_filter[filter_tb].
 894                                                filter[filter][1]));
 895                                xgifb_reg_set(
 896                                        XGIPART2,
 897                                        0x37,
 898                                        (XGI_TV_filter[filter_tb].
 899                                                filter[filter][2]));
 900                                xgifb_reg_set(
 901                                        XGIPART2,
 902                                        0x38,
 903                                        (XGI_TV_filter[filter_tb].
 904                                                filter[filter][3]));
 905                        }
 906                }
 907        }
 908}
 909
 910static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 911                            struct fb_info *info)
 912{
 913        struct xgifb_video_info *xgifb_info = info->par;
 914        struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
 915        unsigned int htotal = var->left_margin + var->xres + var->right_margin
 916                        + var->hsync_len;
 917        unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
 918                        + var->vsync_len;
 919#if defined(__BIG_ENDIAN)
 920        u8 cr_data;
 921#endif
 922        unsigned int drate = 0, hrate = 0;
 923        int found_mode = 0;
 924        int old_mode;
 925
 926        info->var.xres_virtual = var->xres_virtual;
 927        info->var.yres_virtual = var->yres_virtual;
 928        info->var.bits_per_pixel = var->bits_per_pixel;
 929
 930        if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
 931                vtotal <<= 1;
 932        else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
 933                vtotal <<= 2;
 934
 935        if (!htotal || !vtotal) {
 936                pr_debug("Invalid 'var' information\n");
 937                return -EINVAL;
 938        } pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n",
 939                        var->pixclock, htotal, vtotal);
 940
 941        if (var->pixclock) {
 942                drate = 1000000000 / var->pixclock;
 943                hrate = (drate * 1000) / htotal;
 944                xgifb_info->refresh_rate = (unsigned int)(hrate * 2
 945                                / vtotal);
 946        } else {
 947                xgifb_info->refresh_rate = 60;
 948        }
 949
 950        pr_debug("Change mode to %dx%dx%d-%dHz\n",
 951                 var->xres, var->yres, var->bits_per_pixel,
 952                 xgifb_info->refresh_rate);
 953
 954        old_mode = xgifb_info->mode_idx;
 955        xgifb_info->mode_idx = 0;
 956
 957        while ((XGIbios_mode[xgifb_info->mode_idx].mode_no != 0) &&
 958               (XGIbios_mode[xgifb_info->mode_idx].xres <= var->xres)) {
 959                if ((XGIbios_mode[xgifb_info->mode_idx].xres == var->xres) &&
 960                    (XGIbios_mode[xgifb_info->mode_idx].yres == var->yres) &&
 961                    (XGIbios_mode[xgifb_info->mode_idx].bpp
 962                                                == var->bits_per_pixel)) {
 963                        found_mode = 1;
 964                        break;
 965                }
 966                xgifb_info->mode_idx++;
 967        }
 968
 969        if (found_mode)
 970                xgifb_info->mode_idx = XGIfb_validate_mode(xgifb_info,
 971                                                        xgifb_info->mode_idx);
 972        else
 973                xgifb_info->mode_idx = -1;
 974
 975        if (xgifb_info->mode_idx < 0) {
 976                pr_err("Mode %dx%dx%d not supported\n",
 977                       var->xres, var->yres, var->bits_per_pixel);
 978                xgifb_info->mode_idx = old_mode;
 979                return -EINVAL;
 980        }
 981
 982        if (XGIfb_search_refresh_rate(xgifb_info,
 983                                      xgifb_info->refresh_rate) == 0) {
 984                xgifb_info->rate_idx = 1;
 985                xgifb_info->refresh_rate = 60;
 986        }
 987
 988        if (isactive) {
 989                XGIfb_pre_setmode(xgifb_info);
 990                if (XGISetModeNew(xgifb_info, hw_info,
 991                                  XGIbios_mode[xgifb_info->mode_idx].mode_no)
 992                                        == 0) {
 993                        pr_err("Setting mode[0x%x] failed\n",
 994                               XGIbios_mode[xgifb_info->mode_idx].mode_no);
 995                        return -EINVAL;
 996                }
 997                info->fix.line_length = (info->var.xres_virtual
 998                                * info->var.bits_per_pixel) >> 6;
 999
1000                xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1001
1002                xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1003                xgifb_reg_set(XGISR,
1004                              0x0E,
1005                              (info->fix.line_length & 0xff00) >> 8);
1006
1007                XGIfb_post_setmode(xgifb_info);
1008
1009                pr_debug("Set new mode: %dx%dx%d-%d\n",
1010                         XGIbios_mode[xgifb_info->mode_idx].xres,
1011                         XGIbios_mode[xgifb_info->mode_idx].yres,
1012                         XGIbios_mode[xgifb_info->mode_idx].bpp,
1013                         xgifb_info->refresh_rate);
1014
1015                xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
1016                xgifb_info->video_vwidth = info->var.xres_virtual;
1017                xgifb_info->video_width =
1018                        XGIbios_mode[xgifb_info->mode_idx].xres;
1019                xgifb_info->video_vheight = info->var.yres_virtual;
1020                xgifb_info->video_height =
1021                        XGIbios_mode[xgifb_info->mode_idx].yres;
1022                xgifb_info->org_x = 0;
1023                xgifb_info->org_y = 0;
1024                xgifb_info->video_linelength = info->var.xres_virtual
1025                                * (xgifb_info->video_bpp >> 3);
1026                switch (xgifb_info->video_bpp) {
1027                case 8:
1028                        xgifb_info->DstColor = 0x0000;
1029                        xgifb_info->XGI310_AccelDepth = 0x00000000;
1030                        xgifb_info->video_cmap_len = 256;
1031#if defined(__BIG_ENDIAN)
1032                        cr_data = xgifb_reg_get(XGICR, 0x4D);
1033                        xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1034#endif
1035                        break;
1036                case 16:
1037                        xgifb_info->DstColor = 0x8000;
1038                        xgifb_info->XGI310_AccelDepth = 0x00010000;
1039#if defined(__BIG_ENDIAN)
1040                        cr_data = xgifb_reg_get(XGICR, 0x4D);
1041                        xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1042#endif
1043                        xgifb_info->video_cmap_len = 16;
1044                        break;
1045                case 32:
1046                        xgifb_info->DstColor = 0xC000;
1047                        xgifb_info->XGI310_AccelDepth = 0x00020000;
1048                        xgifb_info->video_cmap_len = 16;
1049#if defined(__BIG_ENDIAN)
1050                        cr_data = xgifb_reg_get(XGICR, 0x4D);
1051                        xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1052#endif
1053                        break;
1054                default:
1055                        xgifb_info->video_cmap_len = 16;
1056                        pr_err("Unsupported depth %d\n",
1057                               xgifb_info->video_bpp);
1058                        break;
1059                }
1060        }
1061        XGIfb_bpp_to_var(xgifb_info, var); /* update ARGB info */
1062
1063        dumpVGAReg(xgifb_info);
1064        return 0;
1065}
1066
1067static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
1068{
1069        struct xgifb_video_info *xgifb_info = info->par;
1070        unsigned int base;
1071
1072        base = var->yoffset * info->var.xres_virtual + var->xoffset;
1073
1074        /* calculate base bpp dep. */
1075        switch (info->var.bits_per_pixel) {
1076        case 16:
1077                base >>= 1;
1078                break;
1079        case 32:
1080                break;
1081        case 8:
1082        default:
1083                base >>= 2;
1084                break;
1085        }
1086
1087        xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1088
1089        xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1090        xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1091        xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1092        xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
1093        xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1094
1095        if (xgifb_info->display2 != XGIFB_DISP_NONE) {
1096                xgifb_reg_or(XGIPART1, SIS_CRT2_WENABLE_315, 0x01);
1097                xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1098                xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1099                xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1100                xgifb_reg_and_or(XGIPART1,
1101                                 0x02,
1102                                 0x7F,
1103                                 ((base >> 24) & 0x01) << 7);
1104        }
1105        return 0;
1106}
1107
1108static int XGIfb_open(struct fb_info *info, int user)
1109{
1110        return 0;
1111}
1112
1113static int XGIfb_release(struct fb_info *info, int user)
1114{
1115        return 0;
1116}
1117
1118/* similar to sisfb_get_cmap_len */
1119static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1120{
1121        return (var->bits_per_pixel == 8) ? 256 : 16;
1122}
1123
1124static int XGIfb_setcolreg(unsigned int regno, unsigned int red,
1125                           unsigned int green, unsigned int blue,
1126                           unsigned int transp, struct fb_info *info)
1127{
1128        struct xgifb_video_info *xgifb_info = info->par;
1129
1130        if (regno >= XGIfb_get_cmap_len(&info->var))
1131                return 1;
1132
1133        switch (info->var.bits_per_pixel) {
1134        case 8:
1135                outb(regno, XGIDACA);
1136                outb((red >> 10), XGIDACD);
1137                outb((green >> 10), XGIDACD);
1138                outb((blue >> 10), XGIDACD);
1139                if (xgifb_info->display2 != XGIFB_DISP_NONE) {
1140                        outb(regno, XGIDAC2A);
1141                        outb((red >> 8), XGIDAC2D);
1142                        outb((green >> 8), XGIDAC2D);
1143                        outb((blue >> 8), XGIDAC2D);
1144                }
1145                break;
1146        case 16:
1147                ((u32 *)(info->pseudo_palette))[regno] = ((red & 0xf800))
1148                                | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1149                                >> 11);
1150                break;
1151        case 32:
1152                red >>= 8;
1153                green >>= 8;
1154                blue >>= 8;
1155                ((u32 *)(info->pseudo_palette))[regno] = (red << 16) | (green
1156                                << 8) | (blue);
1157                break;
1158        }
1159        return 0;
1160}
1161
1162/* ----------- FBDev related routines for all series ---------- */
1163
1164static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1165                         struct fb_info *info)
1166{
1167        struct xgifb_video_info *xgifb_info = info->par;
1168
1169        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1170
1171        strncpy(fix->id, "XGI", sizeof(fix->id) - 1);
1172
1173        /* if register_framebuffer has been called, we must lock */
1174        if (atomic_read(&info->count))
1175                mutex_lock(&info->mm_lock);
1176
1177        fix->smem_start = xgifb_info->video_base;
1178        fix->smem_len = xgifb_info->video_size;
1179
1180        /* if register_framebuffer has been called, we can unlock */
1181        if (atomic_read(&info->count))
1182                mutex_unlock(&info->mm_lock);
1183
1184        fix->type = FB_TYPE_PACKED_PIXELS;
1185        fix->type_aux = 0;
1186        if (xgifb_info->video_bpp == 8)
1187                fix->visual = FB_VISUAL_PSEUDOCOLOR;
1188        else
1189                fix->visual = FB_VISUAL_DIRECTCOLOR;
1190        fix->xpanstep = 0;
1191        if (XGIfb_ypan)
1192                fix->ypanstep = 1;
1193        fix->ywrapstep = 0;
1194        fix->line_length = xgifb_info->video_linelength;
1195        fix->mmio_start = xgifb_info->mmio_base;
1196        fix->mmio_len = xgifb_info->mmio_size;
1197        fix->accel = FB_ACCEL_SIS_XABRE;
1198
1199        return 0;
1200}
1201
1202static int XGIfb_set_par(struct fb_info *info)
1203{
1204        int err;
1205
1206        err = XGIfb_do_set_var(&info->var, 1, info);
1207        if (err)
1208                return err;
1209        XGIfb_get_fix(&info->fix, -1, info);
1210        return 0;
1211}
1212
1213static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1214{
1215        struct xgifb_video_info *xgifb_info = info->par;
1216        unsigned int htotal = var->left_margin + var->xres + var->right_margin
1217                        + var->hsync_len;
1218        unsigned int vtotal = 0;
1219        unsigned int drate = 0, hrate = 0;
1220        int found_mode = 0;
1221        int search_idx;
1222
1223        if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1224                vtotal = var->upper_margin + var->yres + var->lower_margin
1225                                + var->vsync_len;
1226                vtotal <<= 1;
1227        } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1228                vtotal = var->upper_margin + var->yres + var->lower_margin
1229                                + var->vsync_len;
1230                vtotal <<= 2;
1231        } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1232                vtotal = var->upper_margin + (var->yres / 2)
1233                                + var->lower_margin + var->vsync_len;
1234        } else
1235                vtotal = var->upper_margin + var->yres + var->lower_margin
1236                                + var->vsync_len;
1237
1238        if (!(htotal) || !(vtotal)) {
1239                pr_debug("No valid timing data\n");
1240                return -EINVAL;
1241        }
1242
1243        if (var->pixclock && htotal && vtotal) {
1244                drate = 1000000000 / var->pixclock;
1245                hrate = (drate * 1000) / htotal;
1246                xgifb_info->refresh_rate =
1247                        (unsigned int)(hrate * 2 / vtotal);
1248                pr_debug(
1249                        "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1250                        "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1251                        __func__, var->pixclock, htotal, vtotal,
1252                        __func__, drate, hrate, xgifb_info->refresh_rate);
1253        } else {
1254                xgifb_info->refresh_rate = 60;
1255        }
1256
1257        search_idx = 0;
1258        while ((XGIbios_mode[search_idx].mode_no != 0) &&
1259               (XGIbios_mode[search_idx].xres <= var->xres)) {
1260                if ((XGIbios_mode[search_idx].xres == var->xres) &&
1261                    (XGIbios_mode[search_idx].yres == var->yres) &&
1262                    (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1263                        if (XGIfb_validate_mode(xgifb_info, search_idx) > 0) {
1264                                found_mode = 1;
1265                                break;
1266                        }
1267                }
1268                search_idx++;
1269        }
1270
1271        if (!found_mode) {
1272                pr_err("%dx%dx%d is no valid mode\n",
1273                       var->xres, var->yres, var->bits_per_pixel);
1274                search_idx = 0;
1275                while (XGIbios_mode[search_idx].mode_no != 0) {
1276                        if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1277                            (var->yres <= XGIbios_mode[search_idx].yres) &&
1278                            (var->bits_per_pixel ==
1279                             XGIbios_mode[search_idx].bpp)) {
1280                                if (XGIfb_validate_mode(xgifb_info,
1281                                                        search_idx) > 0) {
1282                                        found_mode = 1;
1283                                        break;
1284                                }
1285                        }
1286                        search_idx++;
1287                }
1288                if (found_mode) {
1289                        var->xres = XGIbios_mode[search_idx].xres;
1290                        var->yres = XGIbios_mode[search_idx].yres;
1291                        pr_debug("Adapted to mode %dx%dx%d\n",
1292                                 var->xres, var->yres, var->bits_per_pixel);
1293
1294                } else {
1295                        pr_err("Failed to find similar mode to %dx%dx%d\n",
1296                               var->xres, var->yres, var->bits_per_pixel);
1297                        return -EINVAL;
1298                }
1299        }
1300
1301        /* Adapt RGB settings */
1302        XGIfb_bpp_to_var(xgifb_info, var);
1303
1304        if (!XGIfb_ypan) {
1305                if (var->xres != var->xres_virtual)
1306                        var->xres_virtual = var->xres;
1307                if (var->yres != var->yres_virtual)
1308                        var->yres_virtual = var->yres;
1309        }
1310
1311        /* Truncate offsets to maximum if too high */
1312        if (var->xoffset > var->xres_virtual - var->xres)
1313                var->xoffset = var->xres_virtual - var->xres - 1;
1314
1315        if (var->yoffset > var->yres_virtual - var->yres)
1316                var->yoffset = var->yres_virtual - var->yres - 1;
1317
1318        /* Set everything else to 0 */
1319        var->red.msb_right = 0;
1320        var->green.msb_right = 0;
1321        var->blue.msb_right = 0;
1322        var->transp.offset = 0;
1323        var->transp.length = 0;
1324        var->transp.msb_right = 0;
1325
1326        return 0;
1327}
1328
1329static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1330                             struct fb_info *info)
1331{
1332        int err;
1333
1334        if (var->xoffset > (info->var.xres_virtual - info->var.xres))
1335                return -EINVAL;
1336        if (var->yoffset > (info->var.yres_virtual - info->var.yres))
1337                return -EINVAL;
1338
1339        if (var->vmode & FB_VMODE_YWRAP) {
1340                if (var->yoffset >= info->var.yres_virtual || var->xoffset)
1341                        return -EINVAL;
1342        } else if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1343                   var->yoffset + info->var.yres > info->var.yres_virtual) {
1344                return -EINVAL;
1345        }
1346        err = XGIfb_pan_var(var, info);
1347        if (err < 0)
1348                return err;
1349
1350        info->var.xoffset = var->xoffset;
1351        info->var.yoffset = var->yoffset;
1352        if (var->vmode & FB_VMODE_YWRAP)
1353                info->var.vmode |= FB_VMODE_YWRAP;
1354        else
1355                info->var.vmode &= ~FB_VMODE_YWRAP;
1356
1357        return 0;
1358}
1359
1360static int XGIfb_blank(int blank, struct fb_info *info)
1361{
1362        struct xgifb_video_info *xgifb_info = info->par;
1363        u8 reg;
1364
1365        reg = xgifb_reg_get(XGICR, 0x17);
1366
1367        if (blank > 0)
1368                reg &= 0x7f;
1369        else
1370                reg |= 0x80;
1371
1372        xgifb_reg_set(XGICR, 0x17, reg);
1373        xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1374        xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
1375        return 0;
1376}
1377
1378static struct fb_ops XGIfb_ops = {
1379        .owner = THIS_MODULE,
1380        .fb_open = XGIfb_open,
1381        .fb_release = XGIfb_release,
1382        .fb_check_var = XGIfb_check_var,
1383        .fb_set_par = XGIfb_set_par,
1384        .fb_setcolreg = XGIfb_setcolreg,
1385        .fb_pan_display = XGIfb_pan_display,
1386        .fb_blank = XGIfb_blank,
1387        .fb_fillrect = cfb_fillrect,
1388        .fb_copyarea = cfb_copyarea,
1389        .fb_imageblit = cfb_imageblit,
1390};
1391
1392/* ---------------- Chip generation dependent routines ---------------- */
1393
1394/* for XGI 315/550/650/740/330 */
1395
1396static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
1397{
1398        u8 ChannelNum, tmp;
1399        u8 reg = 0;
1400
1401        /* xorg driver sets 32MB * 1 channel */
1402        if (xgifb_info->chip == XG27)
1403                xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51);
1404
1405        reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE);
1406        if (!reg)
1407                return -1;
1408
1409        switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1410        case XGI_DRAM_SIZE_1MB:
1411                xgifb_info->video_size = 0x100000;
1412                break;
1413        case XGI_DRAM_SIZE_2MB:
1414                xgifb_info->video_size = 0x200000;
1415                break;
1416        case XGI_DRAM_SIZE_4MB:
1417                xgifb_info->video_size = 0x400000;
1418                break;
1419        case XGI_DRAM_SIZE_8MB:
1420                xgifb_info->video_size = 0x800000;
1421                break;
1422        case XGI_DRAM_SIZE_16MB:
1423                xgifb_info->video_size = 0x1000000;
1424                break;
1425        case XGI_DRAM_SIZE_32MB:
1426                xgifb_info->video_size = 0x2000000;
1427                break;
1428        case XGI_DRAM_SIZE_64MB:
1429                xgifb_info->video_size = 0x4000000;
1430                break;
1431        case XGI_DRAM_SIZE_128MB:
1432                xgifb_info->video_size = 0x8000000;
1433                break;
1434        case XGI_DRAM_SIZE_256MB:
1435                xgifb_info->video_size = 0x10000000;
1436                break;
1437        default:
1438                return -1;
1439        }
1440
1441        tmp = (reg & 0x0c) >> 2;
1442        switch (xgifb_info->chip) {
1443        case XG20:
1444        case XG21:
1445        case XG27:
1446                ChannelNum = 1;
1447                break;
1448
1449        case XG42:
1450                if (reg & 0x04)
1451                        ChannelNum = 2;
1452                else
1453                        ChannelNum = 1;
1454                break;
1455
1456        case XG40:
1457        default:
1458                if (tmp == 2)
1459                        ChannelNum = 2;
1460                else if (tmp == 3)
1461                        ChannelNum = 3;
1462                else
1463                        ChannelNum = 1;
1464                break;
1465        }
1466
1467        xgifb_info->video_size = xgifb_info->video_size * ChannelNum;
1468
1469        pr_info("SR14=%x DramSzie %x ChannelNum %x\n",
1470                reg, xgifb_info->video_size, ChannelNum);
1471        return 0;
1472}
1473
1474static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
1475{
1476        u8 cr32, temp = 0;
1477
1478        xgifb_info->TV_plug = 0;
1479        xgifb_info->TV_type = 0;
1480
1481        cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
1482
1483        if ((cr32 & SIS_CRT1) && !XGIfb_crt1off)
1484                XGIfb_crt1off = 0;
1485        else {
1486                if (cr32 & 0x5F)
1487                        XGIfb_crt1off = 1;
1488                else
1489                        XGIfb_crt1off = 0;
1490        }
1491
1492        if (!xgifb_info->display2_force) {
1493                if (cr32 & SIS_VB_TV)
1494                        xgifb_info->display2 = XGIFB_DISP_TV;
1495                else if (cr32 & SIS_VB_LCD)
1496                        xgifb_info->display2 = XGIFB_DISP_LCD;
1497                else if (cr32 & SIS_VB_CRT2)
1498                        xgifb_info->display2 = XGIFB_DISP_CRT;
1499                else
1500                        xgifb_info->display2 = XGIFB_DISP_NONE;
1501        }
1502
1503        if (XGIfb_tvplug != -1)
1504                /* Override with option */
1505                xgifb_info->TV_plug = XGIfb_tvplug;
1506        else if (cr32 & SIS_VB_HIVISION) {
1507                xgifb_info->TV_type = TVMODE_HIVISION;
1508                xgifb_info->TV_plug = TVPLUG_SVIDEO;
1509        } else if (cr32 & SIS_VB_SVIDEO)
1510                xgifb_info->TV_plug = TVPLUG_SVIDEO;
1511        else if (cr32 & SIS_VB_COMPOSITE)
1512                xgifb_info->TV_plug = TVPLUG_COMPOSITE;
1513        else if (cr32 & SIS_VB_SCART)
1514                xgifb_info->TV_plug = TVPLUG_SCART;
1515
1516        if (xgifb_info->TV_type == 0) {
1517                temp = xgifb_reg_get(XGICR, 0x38);
1518                if (temp & 0x10)
1519                        xgifb_info->TV_type = TVMODE_PAL;
1520                else
1521                        xgifb_info->TV_type = TVMODE_NTSC;
1522        }
1523
1524        /* Copy forceCRT1 option to CRT1off if option is given */
1525        if (XGIfb_forcecrt1 != -1) {
1526                if (XGIfb_forcecrt1)
1527                        XGIfb_crt1off = 0;
1528                else
1529                        XGIfb_crt1off = 1;
1530        }
1531}
1532
1533static bool XGIfb_has_VB(struct xgifb_video_info *xgifb_info)
1534{
1535        u8 vb_chipid;
1536
1537        vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
1538        switch (vb_chipid) {
1539        case 0x01:
1540                xgifb_info->hasVB = HASVB_301;
1541                break;
1542        case 0x02:
1543                xgifb_info->hasVB = HASVB_302;
1544                break;
1545        default:
1546                xgifb_info->hasVB = HASVB_NONE;
1547                return false;
1548        }
1549        return true;
1550}
1551
1552static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info)
1553{
1554        u8 reg;
1555
1556        if (!XGIfb_has_VB(xgifb_info)) {
1557                reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1558                switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
1559                case SIS_EXTERNAL_CHIP_LVDS:
1560                        xgifb_info->hasVB = HASVB_LVDS;
1561                        break;
1562                case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
1563                        xgifb_info->hasVB = HASVB_LVDS_CHRONTEL;
1564                        break;
1565                default:
1566                        break;
1567                }
1568        }
1569}
1570
1571static int __init xgifb_optval(char *fullopt, int validx)
1572{
1573        unsigned long lres;
1574
1575        if (kstrtoul(fullopt + validx, 0, &lres) < 0 || lres > INT_MAX) {
1576                pr_err("Invalid value for option: %s\n", fullopt);
1577                return 0;
1578        }
1579        return lres;
1580}
1581
1582static int __init XGIfb_setup(char *options)
1583{
1584        char *this_opt;
1585
1586        if (!options || !*options)
1587                return 0;
1588
1589        pr_info("Options: %s\n", options);
1590
1591        while ((this_opt = strsep(&options, ",")) != NULL) {
1592                if (!*this_opt)
1593                        continue;
1594
1595                if (!strncmp(this_opt, "mode:", 5)) {
1596                        mode = this_opt + 5;
1597                } else if (!strncmp(this_opt, "vesa:", 5)) {
1598                        vesa = xgifb_optval(this_opt, 5);
1599                } else if (!strncmp(this_opt, "vrate:", 6)) {
1600                        refresh_rate = xgifb_optval(this_opt, 6);
1601                } else if (!strncmp(this_opt, "rate:", 5)) {
1602                        refresh_rate = xgifb_optval(this_opt, 5);
1603                } else if (!strncmp(this_opt, "crt1off", 7)) {
1604                        XGIfb_crt1off = 1;
1605                } else if (!strncmp(this_opt, "filter:", 7)) {
1606                        filter = xgifb_optval(this_opt, 7);
1607                } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1608                        XGIfb_search_crt2type(this_opt + 14);
1609                } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
1610                        XGIfb_forcecrt1 = xgifb_optval(this_opt, 10);
1611                } else if (!strncmp(this_opt, "tvmode:", 7)) {
1612                        XGIfb_search_tvstd(this_opt + 7);
1613                } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1614                        XGIfb_search_tvstd(this_opt + 7);
1615                } else if (!strncmp(this_opt, "dstn", 4)) {
1616                        enable_dstn = 1;
1617                        /* DSTN overrules forcecrt2type */
1618                        XGIfb_crt2type = XGIFB_DISP_LCD;
1619                } else if (!strncmp(this_opt, "noypan", 6)) {
1620                        XGIfb_ypan = 0;
1621                } else {
1622                        mode = this_opt;
1623                }
1624        }
1625        return 0;
1626}
1627
1628static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1629{
1630        u8 reg, reg1;
1631        u8 CR48, CR38;
1632        int ret;
1633        struct fb_info *fb_info;
1634        struct xgifb_video_info *xgifb_info;
1635        struct xgi_hw_device_info *hw_info;
1636        unsigned long video_size_max;
1637
1638        fb_info = framebuffer_alloc(sizeof(*xgifb_info), &pdev->dev);
1639        if (!fb_info)
1640                return -ENOMEM;
1641
1642        xgifb_info = fb_info->par;
1643        hw_info = &xgifb_info->hw_info;
1644        xgifb_info->fb_info = fb_info;
1645        xgifb_info->chip_id = pdev->device;
1646        pci_read_config_byte(pdev,
1647                             PCI_REVISION_ID,
1648                             &xgifb_info->revision_id);
1649        hw_info->jChipRevision = xgifb_info->revision_id;
1650
1651        xgifb_info->pcibus = pdev->bus->number;
1652        xgifb_info->pcislot = PCI_SLOT(pdev->devfn);
1653        xgifb_info->pcifunc = PCI_FUNC(pdev->devfn);
1654        xgifb_info->subsysvendor = pdev->subsystem_vendor;
1655        xgifb_info->subsysdevice = pdev->subsystem_device;
1656
1657        video_size_max = pci_resource_len(pdev, 0);
1658        xgifb_info->video_base = pci_resource_start(pdev, 0);
1659        xgifb_info->mmio_base = pci_resource_start(pdev, 1);
1660        xgifb_info->mmio_size = pci_resource_len(pdev, 1);
1661        xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30;
1662        dev_info(&pdev->dev, "Relocate IO address: %Lx [%08lx]\n",
1663                 (u64)pci_resource_start(pdev, 2),
1664                 xgifb_info->vga_base);
1665
1666        if (pci_enable_device(pdev)) {
1667                ret = -EIO;
1668                goto error;
1669        }
1670
1671        if (XGIfb_crt2type != -1) {
1672                xgifb_info->display2 = XGIfb_crt2type;
1673                xgifb_info->display2_force = true;
1674        }
1675
1676        XGIRegInit(&xgifb_info->dev_info, xgifb_info->vga_base);
1677
1678        xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1679        reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD);
1680
1681        if (reg1 != 0xa1) { /* I/O error */
1682                dev_err(&pdev->dev, "I/O error\n");
1683                ret = -EIO;
1684                goto error_disable;
1685        }
1686
1687        switch (xgifb_info->chip_id) {
1688        case PCI_DEVICE_ID_XGI_20:
1689                xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
1690                CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
1691                if (CR48 & GPIOG_READ)
1692                        xgifb_info->chip = XG21;
1693                else
1694                        xgifb_info->chip = XG20;
1695                break;
1696        case PCI_DEVICE_ID_XGI_40:
1697                xgifb_info->chip = XG40;
1698                break;
1699        case PCI_DEVICE_ID_XGI_42:
1700                xgifb_info->chip = XG42;
1701                break;
1702        case PCI_DEVICE_ID_XGI_27:
1703                xgifb_info->chip = XG27;
1704                break;
1705        default:
1706                ret = -ENODEV;
1707                goto error_disable;
1708        }
1709
1710        dev_info(&pdev->dev, "chipid = %x\n", xgifb_info->chip);
1711        hw_info->jChipType = xgifb_info->chip;
1712
1713        if (XGIfb_get_dram_size(xgifb_info)) {
1714                xgifb_info->video_size = min_t(unsigned long, video_size_max,
1715                                                SZ_16M);
1716        } else if (xgifb_info->video_size > video_size_max) {
1717                xgifb_info->video_size = video_size_max;
1718        }
1719
1720        /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
1721        xgifb_reg_or(XGISR,
1722                     IND_SIS_PCI_ADDRESS_SET,
1723                     (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
1724        /* Enable 2D accelerator engine */
1725        xgifb_reg_or(XGISR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
1726
1727        hw_info->ulVideoMemorySize = xgifb_info->video_size;
1728
1729        if (!request_mem_region(xgifb_info->video_base,
1730                                xgifb_info->video_size,
1731                                "XGIfb FB")) {
1732                dev_err(&pdev->dev, "Unable request memory size %x\n",
1733                        xgifb_info->video_size);
1734                dev_err(&pdev->dev,
1735                        "Fatal error: Unable to reserve frame buffer memory. Is there another framebuffer driver active?\n");
1736                ret = -ENODEV;
1737                goto error_disable;
1738        }
1739
1740        if (!request_mem_region(xgifb_info->mmio_base,
1741                                xgifb_info->mmio_size,
1742                                "XGIfb MMIO")) {
1743                dev_err(&pdev->dev,
1744                        "Fatal error: Unable to reserve MMIO region\n");
1745                ret = -ENODEV;
1746                goto error_0;
1747        }
1748
1749        xgifb_info->video_vbase =
1750                ioremap_wc(xgifb_info->video_base, xgifb_info->video_size);
1751        hw_info->pjVideoMemoryAddress =
1752                ioremap_wc(xgifb_info->video_base, xgifb_info->video_size);
1753        xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base,
1754                                            xgifb_info->mmio_size);
1755
1756        dev_info(&pdev->dev,
1757                 "Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n",
1758                 (u64)xgifb_info->video_base,
1759                 xgifb_info->video_vbase,
1760                 xgifb_info->video_size / 1024);
1761
1762        dev_info(&pdev->dev,
1763                 "MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n",
1764                 (u64)xgifb_info->mmio_base, xgifb_info->mmio_vbase,
1765                 xgifb_info->mmio_size / 1024);
1766
1767        pci_set_drvdata(pdev, xgifb_info);
1768        if (!XGIInitNew(pdev))
1769                dev_err(&pdev->dev, "XGIInitNew() failed!\n");
1770
1771        xgifb_info->mtrr = -1;
1772
1773        xgifb_info->hasVB = HASVB_NONE;
1774        if ((xgifb_info->chip == XG20) ||
1775            (xgifb_info->chip == XG27)) {
1776                xgifb_info->hasVB = HASVB_NONE;
1777        } else if (xgifb_info->chip == XG21) {
1778                CR38 = xgifb_reg_get(XGICR, 0x38);
1779                if ((CR38 & 0xE0) == 0xC0)
1780                        xgifb_info->display2 = XGIFB_DISP_LCD;
1781                else if ((CR38 & 0xE0) == 0x60)
1782                        xgifb_info->hasVB = HASVB_CHRONTEL;
1783                else
1784                        xgifb_info->hasVB = HASVB_NONE;
1785        } else {
1786                XGIfb_get_VB_type(xgifb_info);
1787        }
1788
1789        hw_info->ujVBChipID = VB_CHIP_UNKNOWN;
1790
1791        hw_info->ulExternalChip = 0;
1792
1793        switch (xgifb_info->hasVB) {
1794        case HASVB_301:
1795                reg = xgifb_reg_get(XGIPART4, 0x01);
1796                if (reg >= 0xE0) {
1797                        hw_info->ujVBChipID = VB_CHIP_302LV;
1798                        dev_info(&pdev->dev,
1799                                 "XGI302LV bridge detected (revision 0x%02x)\n",
1800                                 reg);
1801                } else if (reg >= 0xD0) {
1802                        hw_info->ujVBChipID = VB_CHIP_301LV;
1803                        dev_info(&pdev->dev,
1804                                 "XGI301LV bridge detected (revision 0x%02x)\n",
1805                                 reg);
1806                } else {
1807                        hw_info->ujVBChipID = VB_CHIP_301;
1808                        dev_info(&pdev->dev, "XGI301 bridge detected\n");
1809                }
1810                break;
1811        case HASVB_302:
1812                reg = xgifb_reg_get(XGIPART4, 0x01);
1813                if (reg >= 0xE0) {
1814                        hw_info->ujVBChipID = VB_CHIP_302LV;
1815                        dev_info(&pdev->dev,
1816                                 "XGI302LV bridge detected (revision 0x%02x)\n",
1817                                 reg);
1818                } else if (reg >= 0xD0) {
1819                        hw_info->ujVBChipID = VB_CHIP_301LV;
1820                        dev_info(&pdev->dev,
1821                                 "XGI302LV bridge detected (revision 0x%02x)\n",
1822                                 reg);
1823                } else if (reg >= 0xB0) {
1824                        reg1 = xgifb_reg_get(XGIPART4, 0x23);
1825
1826                        hw_info->ujVBChipID = VB_CHIP_302B;
1827
1828                } else {
1829                        hw_info->ujVBChipID = VB_CHIP_302;
1830                        dev_info(&pdev->dev, "XGI302 bridge detected\n");
1831                }
1832                break;
1833        case HASVB_LVDS:
1834                hw_info->ulExternalChip = 0x1;
1835                dev_info(&pdev->dev, "LVDS transmitter detected\n");
1836                break;
1837        case HASVB_TRUMPION:
1838                hw_info->ulExternalChip = 0x2;
1839                dev_info(&pdev->dev, "Trumpion Zurac LVDS scaler detected\n");
1840                break;
1841        case HASVB_CHRONTEL:
1842                hw_info->ulExternalChip = 0x4;
1843                dev_info(&pdev->dev, "Chrontel TV encoder detected\n");
1844                break;
1845        case HASVB_LVDS_CHRONTEL:
1846                hw_info->ulExternalChip = 0x5;
1847                dev_info(&pdev->dev,
1848                         "LVDS transmitter and Chrontel TV encoder detected\n");
1849                break;
1850        default:
1851                dev_info(&pdev->dev, "No or unknown bridge type detected\n");
1852                break;
1853        }
1854
1855        if (xgifb_info->hasVB != HASVB_NONE)
1856                XGIfb_detect_VB(xgifb_info);
1857        else if (xgifb_info->chip != XG21)
1858                xgifb_info->display2 = XGIFB_DISP_NONE;
1859
1860        if (xgifb_info->display2 == XGIFB_DISP_LCD) {
1861                if (!enable_dstn) {
1862                        reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
1863                        reg &= 0x0f;
1864                        hw_info->ulCRT2LCDType = XGI310paneltype[reg];
1865                }
1866        }
1867
1868        xgifb_info->mode_idx = -1;
1869
1870        if (mode)
1871                XGIfb_search_mode(xgifb_info, mode);
1872        else if (vesa != -1)
1873                XGIfb_search_vesamode(xgifb_info, vesa);
1874
1875        if (xgifb_info->mode_idx >= 0)
1876                xgifb_info->mode_idx =
1877                        XGIfb_validate_mode(xgifb_info, xgifb_info->mode_idx);
1878
1879        if (xgifb_info->mode_idx < 0) {
1880                if (xgifb_info->display2 == XGIFB_DISP_LCD &&
1881                    xgifb_info->chip == XG21)
1882                        xgifb_info->mode_idx =
1883                                XGIfb_GetXG21DefaultLVDSModeIdx(xgifb_info);
1884                else
1885                        xgifb_info->mode_idx = DEFAULT_MODE;
1886        }
1887
1888        if (xgifb_info->mode_idx < 0) {
1889                dev_err(&pdev->dev, "No supported video mode found\n");
1890                ret = -EINVAL;
1891                goto error_1;
1892        }
1893
1894        /* set default refresh rate */
1895        xgifb_info->refresh_rate = refresh_rate;
1896        if (xgifb_info->refresh_rate == 0)
1897                xgifb_info->refresh_rate = 60;
1898        if (XGIfb_search_refresh_rate(xgifb_info, xgifb_info->refresh_rate) == 0) {
1899                xgifb_info->rate_idx = 1;
1900                xgifb_info->refresh_rate = 60;
1901        }
1902
1903        xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
1904        xgifb_info->video_vwidth =
1905                xgifb_info->video_width =
1906                        XGIbios_mode[xgifb_info->mode_idx].xres;
1907        xgifb_info->video_vheight =
1908                xgifb_info->video_height =
1909                        XGIbios_mode[xgifb_info->mode_idx].yres;
1910        xgifb_info->org_x = 0;
1911        xgifb_info->org_y = 0;
1912        xgifb_info->video_linelength =
1913                xgifb_info->video_width *
1914                (xgifb_info->video_bpp >> 3);
1915        switch (xgifb_info->video_bpp) {
1916        case 8:
1917                xgifb_info->DstColor = 0x0000;
1918                xgifb_info->XGI310_AccelDepth = 0x00000000;
1919                xgifb_info->video_cmap_len = 256;
1920                break;
1921        case 16:
1922                xgifb_info->DstColor = 0x8000;
1923                xgifb_info->XGI310_AccelDepth = 0x00010000;
1924                xgifb_info->video_cmap_len = 16;
1925                break;
1926        case 32:
1927                xgifb_info->DstColor = 0xC000;
1928                xgifb_info->XGI310_AccelDepth = 0x00020000;
1929                xgifb_info->video_cmap_len = 16;
1930                break;
1931        default:
1932                xgifb_info->video_cmap_len = 16;
1933                pr_info("Unsupported depth %d\n",
1934                        xgifb_info->video_bpp);
1935                break;
1936        }
1937
1938        pr_info("Default mode is %dx%dx%d (%dHz)\n",
1939                xgifb_info->video_width, xgifb_info->video_height,
1940                xgifb_info->video_bpp, xgifb_info->refresh_rate);
1941
1942        fb_info->var.red.length         = 8;
1943        fb_info->var.green.length       = 8;
1944        fb_info->var.blue.length        = 8;
1945        fb_info->var.activate           = FB_ACTIVATE_NOW;
1946        fb_info->var.height             = -1;
1947        fb_info->var.width              = -1;
1948        fb_info->var.vmode              = FB_VMODE_NONINTERLACED;
1949        fb_info->var.xres               = xgifb_info->video_width;
1950        fb_info->var.xres_virtual       = xgifb_info->video_width;
1951        fb_info->var.yres               = xgifb_info->video_height;
1952        fb_info->var.yres_virtual       = xgifb_info->video_height;
1953        fb_info->var.bits_per_pixel     = xgifb_info->video_bpp;
1954
1955        XGIfb_bpp_to_var(xgifb_info, &fb_info->var);
1956
1957        fb_info->var.pixclock = (u32)(1000000000 / XGIfb_mode_rate_to_dclock
1958                                      (&xgifb_info->dev_info, hw_info,
1959                                       XGIbios_mode[xgifb_info->mode_idx].mode_no));
1960
1961        if (XGIfb_mode_rate_to_ddata(&xgifb_info->dev_info,
1962                                     hw_info, XGIbios_mode[xgifb_info->mode_idx].mode_no,
1963                                     &fb_info->var.left_margin,
1964                                     &fb_info->var.right_margin,
1965                                     &fb_info->var.upper_margin,
1966                                     &fb_info->var.lower_margin,
1967                                     &fb_info->var.hsync_len,
1968                                     &fb_info->var.vsync_len,
1969                                     &fb_info->var.sync,
1970                                     &fb_info->var.vmode)) {
1971                if ((fb_info->var.vmode & FB_VMODE_MASK) ==
1972                    FB_VMODE_INTERLACED) {
1973                        fb_info->var.yres <<= 1;
1974                        fb_info->var.yres_virtual <<= 1;
1975                } else if ((fb_info->var.vmode & FB_VMODE_MASK) ==
1976                           FB_VMODE_DOUBLE) {
1977                        fb_info->var.pixclock >>= 1;
1978                        fb_info->var.yres >>= 1;
1979                        fb_info->var.yres_virtual >>= 1;
1980                }
1981        }
1982
1983        fb_info->flags = FBINFO_FLAG_DEFAULT;
1984        fb_info->screen_base = xgifb_info->video_vbase;
1985        fb_info->fbops = &XGIfb_ops;
1986        XGIfb_get_fix(&fb_info->fix, -1, fb_info);
1987        fb_info->pseudo_palette = xgifb_info->pseudo_palette;
1988
1989        fb_alloc_cmap(&fb_info->cmap, 256, 0);
1990
1991        xgifb_info->mtrr = arch_phys_wc_add(xgifb_info->video_base,
1992                                            xgifb_info->video_size);
1993
1994        if (register_framebuffer(fb_info) < 0) {
1995                ret = -EINVAL;
1996                goto error_mtrr;
1997        }
1998
1999        dumpVGAReg(xgifb_info);
2000
2001        return 0;
2002
2003error_mtrr:
2004        arch_phys_wc_del(xgifb_info->mtrr);
2005error_1:
2006        iounmap(xgifb_info->mmio_vbase);
2007        iounmap(xgifb_info->video_vbase);
2008        release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
2009error_0:
2010        release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
2011error_disable:
2012        pci_disable_device(pdev);
2013error:
2014        framebuffer_release(fb_info);
2015        return ret;
2016}
2017
2018/* -------------------- PCI DEVICE HANDLING -------------------- */
2019
2020static void xgifb_remove(struct pci_dev *pdev)
2021{
2022        struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
2023        struct fb_info *fb_info = xgifb_info->fb_info;
2024
2025        unregister_framebuffer(fb_info);
2026        arch_phys_wc_del(xgifb_info->mtrr);
2027        iounmap(xgifb_info->mmio_vbase);
2028        iounmap(xgifb_info->video_vbase);
2029        release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
2030        release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
2031        pci_disable_device(pdev);
2032        framebuffer_release(fb_info);
2033}
2034
2035static struct pci_driver xgifb_driver = {
2036        .name = "xgifb",
2037        .id_table = xgifb_pci_table,
2038        .probe = xgifb_probe,
2039        .remove = xgifb_remove
2040};
2041
2042/* -------------------- MODULE -------------------- */
2043
2044module_param(mode, charp, 0000);
2045MODULE_PARM_DESC(mode,
2046                 "Selects the desired default display mode in the format XxYxDepth (eg. 1024x768x16).");
2047
2048module_param(forcecrt2type, charp, 0000);
2049MODULE_PARM_DESC(forcecrt2type,
2050                 "Force the second display output type. Possible values are NONE, LCD, TV, VGA, SVIDEO or COMPOSITE.");
2051
2052module_param(vesa, int, 0000);
2053MODULE_PARM_DESC(vesa,
2054                 "Selects the desired default display mode by VESA mode number (eg. 0x117).");
2055
2056module_param(filter, int, 0000);
2057MODULE_PARM_DESC(filter,
2058                 "Selects TV flicker filter type (only for systems with a SiS301 video bridge). Possible values 0-7. Default: [no filter]).");
2059
2060static int __init xgifb_init(void)
2061{
2062        char *option = NULL;
2063
2064        if (forcecrt2type)
2065                XGIfb_search_crt2type(forcecrt2type);
2066        if (fb_get_options("xgifb", &option))
2067                return -ENODEV;
2068        XGIfb_setup(option);
2069
2070        return pci_register_driver(&xgifb_driver);
2071}
2072
2073static void __exit xgifb_remove_module(void)
2074{
2075        pci_unregister_driver(&xgifb_driver);
2076        pr_debug("Module unloaded\n");
2077}
2078
2079MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2080MODULE_LICENSE("GPL");
2081MODULE_AUTHOR("XGITECH , Others");
2082module_init(xgifb_init);
2083module_exit(xgifb_remove_module);
2084