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