Root/drivers/staging/xgifb/XGI_main_26.c

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

Archive Download this file



interactive