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