Root/drivers/staging/xgifb/vb_init.c

1#include <linux/delay.h>
2#include <linux/vmalloc.h>
3
4#include "XGIfb.h"
5#include "vb_def.h"
6#include "vb_util.h"
7#include "vb_setmode.h"
8#include "vb_init.h"
9static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = {
10    { 16, 0x45},
11    { 8, 0x35},
12    { 4, 0x31},
13    { 2, 0x21} };
14
15static const unsigned short XGINew_DDRDRAM_TYPE20[12][2] = {
16    { 128, 0x5D},
17    { 64, 0x59},
18    { 64, 0x4D},
19    { 32, 0x55},
20    { 32, 0x49},
21    { 32, 0x3D},
22    { 16, 0x51},
23    { 16, 0x45},
24    { 16, 0x39},
25    { 8, 0x41},
26    { 8, 0x35},
27    { 4, 0x31} };
28
29#define XGIFB_ROM_SIZE 65536
30
31static unsigned char
32XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
33               struct vb_device_info *pVBInfo)
34{
35    unsigned char data, temp;
36
37    if (HwDeviceExtension->jChipType < XG20) {
38        data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02;
39        if (data == 0)
40            data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) &
41                   0x02) >> 1;
42        return data;
43    } else if (HwDeviceExtension->jChipType == XG27) {
44        temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
45        /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
46        if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08))
47            data = 0; /* DDR */
48        else
49            data = 1; /* DDRII */
50        return data;
51    } else if (HwDeviceExtension->jChipType == XG21) {
52        /* Independent GPIO control */
53        xgifb_reg_and(pVBInfo->P3d4, 0xB4, ~0x02);
54        udelay(800);
55        xgifb_reg_or(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */
56        /* GPIOF 0:DVI 1:DVO */
57        temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
58        /* HOTPLUG_SUPPORT */
59        /* for current XG20 & XG21, GPIOH is floating, driver will
60         * fix DDR temporarily */
61        if (temp & 0x01) /* DVI read GPIOH */
62            data = 1; /* DDRII */
63        else
64            data = 0; /* DDR */
65        /* ~HOTPLUG_SUPPORT */
66        xgifb_reg_or(pVBInfo->P3d4, 0xB4, 0x02);
67        return data;
68    } else {
69        data = xgifb_reg_get(pVBInfo->P3d4, 0x97) & 0x01;
70
71        if (data == 1)
72            data++;
73
74        return data;
75    }
76}
77
78static void XGINew_DDR1x_MRS_340(unsigned long P3c4,
79                 struct vb_device_info *pVBInfo)
80{
81    xgifb_reg_set(P3c4, 0x18, 0x01);
82    xgifb_reg_set(P3c4, 0x19, 0x20);
83    xgifb_reg_set(P3c4, 0x16, 0x00);
84    xgifb_reg_set(P3c4, 0x16, 0x80);
85
86    mdelay(3);
87    xgifb_reg_set(P3c4, 0x18, 0x00);
88    xgifb_reg_set(P3c4, 0x19, 0x20);
89    xgifb_reg_set(P3c4, 0x16, 0x00);
90    xgifb_reg_set(P3c4, 0x16, 0x80);
91
92    udelay(60);
93    xgifb_reg_set(P3c4,
94              0x18,
95              pVBInfo->SR15[2][pVBInfo->ram_type]); /* SR18 */
96    xgifb_reg_set(P3c4, 0x19, 0x01);
97    xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[0]);
98    xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[1]);
99    mdelay(1);
100    xgifb_reg_set(P3c4, 0x1B, 0x03);
101    udelay(500);
102    xgifb_reg_set(P3c4,
103              0x18,
104              pVBInfo->SR15[2][pVBInfo->ram_type]); /* SR18 */
105    xgifb_reg_set(P3c4, 0x19, 0x00);
106    xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[2]);
107    xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[3]);
108    xgifb_reg_set(P3c4, 0x1B, 0x00);
109}
110
111static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension,
112        struct vb_device_info *pVBInfo)
113{
114
115    xgifb_reg_set(pVBInfo->P3c4,
116              0x28,
117              pVBInfo->MCLKData[pVBInfo->ram_type].SR28);
118    xgifb_reg_set(pVBInfo->P3c4,
119              0x29,
120              pVBInfo->MCLKData[pVBInfo->ram_type].SR29);
121    xgifb_reg_set(pVBInfo->P3c4,
122              0x2A,
123              pVBInfo->MCLKData[pVBInfo->ram_type].SR2A);
124
125    xgifb_reg_set(pVBInfo->P3c4,
126              0x2E,
127              pVBInfo->ECLKData[pVBInfo->ram_type].SR2E);
128    xgifb_reg_set(pVBInfo->P3c4,
129              0x2F,
130              pVBInfo->ECLKData[pVBInfo->ram_type].SR2F);
131    xgifb_reg_set(pVBInfo->P3c4,
132              0x30,
133              pVBInfo->ECLKData[pVBInfo->ram_type].SR30);
134
135    /* When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
136    /* Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz,
137     * Set SR32 D[1:0] = 10b */
138    if (HwDeviceExtension->jChipType == XG42) {
139        if ((pVBInfo->MCLKData[pVBInfo->ram_type].SR28 == 0x1C) &&
140            (pVBInfo->MCLKData[pVBInfo->ram_type].SR29 == 0x01) &&
141            (((pVBInfo->ECLKData[pVBInfo->ram_type].SR2E == 0x1C) &&
142              (pVBInfo->ECLKData[pVBInfo->ram_type].SR2F == 0x01)) ||
143             ((pVBInfo->ECLKData[pVBInfo->ram_type].SR2E == 0x22) &&
144              (pVBInfo->ECLKData[pVBInfo->ram_type].SR2F == 0x01))))
145            xgifb_reg_set(pVBInfo->P3c4,
146                      0x32,
147                      ((unsigned char) xgifb_reg_get(
148                      pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
149    }
150}
151
152static void XGINew_DDRII_Bootup_XG27(
153            struct xgi_hw_device_info *HwDeviceExtension,
154            unsigned long P3c4, struct vb_device_info *pVBInfo)
155{
156    unsigned long P3d4 = P3c4 + 0x10;
157    pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
158    XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
159
160    /* Set Double Frequency */
161    xgifb_reg_set(P3d4, 0x97, pVBInfo->XGINew_CR97); /* CR97 */
162
163    udelay(200);
164
165    xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */
166    xgifb_reg_set(P3c4, 0x19, 0x80); /* Set SR19 */
167    xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
168    udelay(15);
169    xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
170    udelay(15);
171
172    xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */
173    xgifb_reg_set(P3c4, 0x19, 0xC0); /* Set SR19 */
174    xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
175    udelay(15);
176    xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
177    udelay(15);
178
179    xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */
180    xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */
181    xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
182    udelay(30);
183    xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
184    udelay(15);
185
186    xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */
187    xgifb_reg_set(P3c4, 0x19, 0x0A); /* Set SR19 */
188    xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
189    udelay(30);
190    xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
191    xgifb_reg_set(P3c4, 0x16, 0x80); /* Set SR16 */
192
193    xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B */
194    udelay(60);
195    xgifb_reg_set(P3c4, 0x1B, 0x00); /* Set SR1B */
196
197    xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */
198    xgifb_reg_set(P3c4, 0x19, 0x08); /* Set SR19 */
199    xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
200
201    udelay(30);
202    xgifb_reg_set(P3c4, 0x16, 0x83); /* Set SR16 */
203    udelay(15);
204
205    xgifb_reg_set(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */
206    xgifb_reg_set(P3c4, 0x19, 0x46); /* Set SR19 */
207    xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
208    udelay(30);
209    xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
210    udelay(15);
211
212    xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */
213    xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */
214    xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
215    udelay(30);
216    xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
217    udelay(15);
218
219    /* Set SR1B refresh control 000:close; 010:open */
220    xgifb_reg_set(P3c4, 0x1B, 0x04);
221    udelay(200);
222
223}
224
225static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension,
226        unsigned long P3c4, struct vb_device_info *pVBInfo)
227{
228    unsigned long P3d4 = P3c4 + 0x10;
229
230    pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
231    XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
232
233    xgifb_reg_set(P3d4, 0x97, 0x11); /* CR97 */
234
235    udelay(200);
236    xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS2 */
237    xgifb_reg_set(P3c4, 0x19, 0x80);
238    xgifb_reg_set(P3c4, 0x16, 0x05);
239    xgifb_reg_set(P3c4, 0x16, 0x85);
240
241    xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS3 */
242    xgifb_reg_set(P3c4, 0x19, 0xC0);
243    xgifb_reg_set(P3c4, 0x16, 0x05);
244    xgifb_reg_set(P3c4, 0x16, 0x85);
245
246    xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS1 */
247    xgifb_reg_set(P3c4, 0x19, 0x40);
248    xgifb_reg_set(P3c4, 0x16, 0x05);
249    xgifb_reg_set(P3c4, 0x16, 0x85);
250
251    xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */
252    xgifb_reg_set(P3c4, 0x19, 0x02);
253    xgifb_reg_set(P3c4, 0x16, 0x05);
254    xgifb_reg_set(P3c4, 0x16, 0x85);
255
256    udelay(15);
257    xgifb_reg_set(P3c4, 0x1B, 0x04); /* SR1B */
258    udelay(30);
259    xgifb_reg_set(P3c4, 0x1B, 0x00); /* SR1B */
260    udelay(100);
261
262    xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */
263    xgifb_reg_set(P3c4, 0x19, 0x00);
264    xgifb_reg_set(P3c4, 0x16, 0x05);
265    xgifb_reg_set(P3c4, 0x16, 0x85);
266
267    udelay(200);
268}
269
270static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4,
271                  struct vb_device_info *pVBInfo)
272{
273    xgifb_reg_set(P3c4, 0x18, 0x01);
274    xgifb_reg_set(P3c4, 0x19, 0x40);
275    xgifb_reg_set(P3c4, 0x16, 0x00);
276    xgifb_reg_set(P3c4, 0x16, 0x80);
277    udelay(60);
278
279    xgifb_reg_set(P3c4, 0x18, 0x00);
280    xgifb_reg_set(P3c4, 0x19, 0x40);
281    xgifb_reg_set(P3c4, 0x16, 0x00);
282    xgifb_reg_set(P3c4, 0x16, 0x80);
283    udelay(60);
284    xgifb_reg_set(P3c4,
285              0x18,
286              pVBInfo->SR15[2][pVBInfo->ram_type]); /* SR18 */
287    xgifb_reg_set(P3c4, 0x19, 0x01);
288    xgifb_reg_set(P3c4, 0x16, 0x03);
289    xgifb_reg_set(P3c4, 0x16, 0x83);
290    mdelay(1);
291    xgifb_reg_set(P3c4, 0x1B, 0x03);
292    udelay(500);
293    xgifb_reg_set(P3c4,
294              0x18,
295              pVBInfo->SR15[2][pVBInfo->ram_type]); /* SR18 */
296    xgifb_reg_set(P3c4, 0x19, 0x00);
297    xgifb_reg_set(P3c4, 0x16, 0x03);
298    xgifb_reg_set(P3c4, 0x16, 0x83);
299    xgifb_reg_set(P3c4, 0x1B, 0x00);
300}
301
302static void XGINew_DDR1x_DefaultRegister(
303        struct xgi_hw_device_info *HwDeviceExtension,
304        unsigned long Port, struct vb_device_info *pVBInfo)
305{
306    unsigned long P3d4 = Port, P3c4 = Port - 0x10;
307
308    if (HwDeviceExtension->jChipType >= XG20) {
309        XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
310        xgifb_reg_set(P3d4,
311                  0x82,
312                  pVBInfo->CR40[11][pVBInfo->ram_type]); /* CR82 */
313        xgifb_reg_set(P3d4,
314                  0x85,
315                  pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */
316        xgifb_reg_set(P3d4,
317                  0x86,
318                  pVBInfo->CR40[13][pVBInfo->ram_type]); /* CR86 */
319
320        xgifb_reg_set(P3d4, 0x98, 0x01);
321        xgifb_reg_set(P3d4, 0x9A, 0x02);
322
323        XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo);
324    } else {
325        XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
326
327        switch (HwDeviceExtension->jChipType) {
328        case XG42:
329            /* CR82 */
330            xgifb_reg_set(P3d4,
331                      0x82,
332                      pVBInfo->CR40[11][pVBInfo->ram_type]);
333            /* CR85 */
334            xgifb_reg_set(P3d4,
335                      0x85,
336                      pVBInfo->CR40[12][pVBInfo->ram_type]);
337            /* CR86 */
338            xgifb_reg_set(P3d4,
339                      0x86,
340                      pVBInfo->CR40[13][pVBInfo->ram_type]);
341            break;
342        default:
343            xgifb_reg_set(P3d4, 0x82, 0x88);
344            xgifb_reg_set(P3d4, 0x86, 0x00);
345            /* Insert read command for delay */
346            xgifb_reg_get(P3d4, 0x86);
347            xgifb_reg_set(P3d4, 0x86, 0x88);
348            xgifb_reg_get(P3d4, 0x86);
349            xgifb_reg_set(P3d4,
350                      0x86,
351                      pVBInfo->CR40[13][pVBInfo->ram_type]);
352            xgifb_reg_set(P3d4, 0x82, 0x77);
353            xgifb_reg_set(P3d4, 0x85, 0x00);
354
355            /* Insert read command for delay */
356            xgifb_reg_get(P3d4, 0x85);
357            xgifb_reg_set(P3d4, 0x85, 0x88);
358
359            /* Insert read command for delay */
360            xgifb_reg_get(P3d4, 0x85);
361            /* CR85 */
362            xgifb_reg_set(P3d4,
363                      0x85,
364                      pVBInfo->CR40[12][pVBInfo->ram_type]);
365            /* CR82 */
366            xgifb_reg_set(P3d4,
367                      0x82,
368                      pVBInfo->CR40[11][pVBInfo->ram_type]);
369            break;
370        }
371
372        xgifb_reg_set(P3d4, 0x97, 0x00);
373        xgifb_reg_set(P3d4, 0x98, 0x01);
374        xgifb_reg_set(P3d4, 0x9A, 0x02);
375        XGINew_DDR1x_MRS_340(P3c4, pVBInfo);
376    }
377}
378
379static void XGINew_DDR2_DefaultRegister(
380        struct xgi_hw_device_info *HwDeviceExtension,
381        unsigned long Port, struct vb_device_info *pVBInfo)
382{
383    unsigned long P3d4 = Port, P3c4 = Port - 0x10;
384
385    /* keep following setting sequence, each setting in
386     * the same reg insert idle */
387    xgifb_reg_set(P3d4, 0x82, 0x77);
388    xgifb_reg_set(P3d4, 0x86, 0x00);
389    xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
390    xgifb_reg_set(P3d4, 0x86, 0x88);
391    xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
392    /* CR86 */
393    xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][pVBInfo->ram_type]);
394    xgifb_reg_set(P3d4, 0x82, 0x77);
395    xgifb_reg_set(P3d4, 0x85, 0x00);
396    xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
397    xgifb_reg_set(P3d4, 0x85, 0x88);
398    xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
399    xgifb_reg_set(P3d4,
400              0x85,
401              pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */
402    if (HwDeviceExtension->jChipType == XG27)
403        /* CR82 */
404        xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][pVBInfo->ram_type]);
405    else
406        xgifb_reg_set(P3d4, 0x82, 0xA8); /* CR82 */
407
408    xgifb_reg_set(P3d4, 0x98, 0x01);
409    xgifb_reg_set(P3d4, 0x9A, 0x02);
410    if (HwDeviceExtension->jChipType == XG27)
411        XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo);
412    else
413        XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo);
414}
415
416static void XGINew_SetDRAMDefaultRegister340(
417        struct xgi_hw_device_info *HwDeviceExtension,
418        unsigned long Port, struct vb_device_info *pVBInfo)
419{
420    unsigned char temp, temp1, temp2, temp3, i, j, k;
421
422    unsigned long P3d4 = Port, P3c4 = Port - 0x10;
423
424    xgifb_reg_set(P3d4, 0x6D, pVBInfo->CR40[8][pVBInfo->ram_type]);
425    xgifb_reg_set(P3d4, 0x68, pVBInfo->CR40[5][pVBInfo->ram_type]);
426    xgifb_reg_set(P3d4, 0x69, pVBInfo->CR40[6][pVBInfo->ram_type]);
427    xgifb_reg_set(P3d4, 0x6A, pVBInfo->CR40[7][pVBInfo->ram_type]);
428
429    temp2 = 0;
430    for (i = 0; i < 4; i++) {
431        /* CR6B DQS fine tune delay */
432        temp = pVBInfo->CR6B[pVBInfo->ram_type][i];
433        for (j = 0; j < 4; j++) {
434            temp1 = ((temp >> (2 * j)) & 0x03) << 2;
435            temp2 |= temp1;
436            xgifb_reg_set(P3d4, 0x6B, temp2);
437            /* Insert read command for delay */
438            xgifb_reg_get(P3d4, 0x6B);
439            temp2 &= 0xF0;
440            temp2 += 0x10;
441        }
442    }
443
444    temp2 = 0;
445    for (i = 0; i < 4; i++) {
446        /* CR6E DQM fine tune delay */
447        temp = pVBInfo->CR6E[pVBInfo->ram_type][i];
448        for (j = 0; j < 4; j++) {
449            temp1 = ((temp >> (2 * j)) & 0x03) << 2;
450            temp2 |= temp1;
451            xgifb_reg_set(P3d4, 0x6E, temp2);
452            /* Insert read command for delay */
453            xgifb_reg_get(P3d4, 0x6E);
454            temp2 &= 0xF0;
455            temp2 += 0x10;
456        }
457    }
458
459    temp3 = 0;
460    for (k = 0; k < 4; k++) {
461        /* CR6E_D[1:0] select channel */
462        xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3);
463        temp2 = 0;
464        for (i = 0; i < 8; i++) {
465            /* CR6F DQ fine tune delay */
466            temp = pVBInfo->CR6F[pVBInfo->ram_type][8 * k + i];
467            for (j = 0; j < 4; j++) {
468                temp1 = (temp >> (2 * j)) & 0x03;
469                temp2 |= temp1;
470                xgifb_reg_set(P3d4, 0x6F, temp2);
471                /* Insert read command for delay */
472                xgifb_reg_get(P3d4, 0x6F);
473                temp2 &= 0xF8;
474                temp2 += 0x08;
475            }
476        }
477        temp3 += 0x01;
478    }
479
480    xgifb_reg_set(P3d4,
481              0x80,
482              pVBInfo->CR40[9][pVBInfo->ram_type]); /* CR80 */
483    xgifb_reg_set(P3d4,
484              0x81,
485              pVBInfo->CR40[10][pVBInfo->ram_type]); /* CR81 */
486
487    temp2 = 0x80;
488    /* CR89 terminator type select */
489    temp = pVBInfo->CR89[pVBInfo->ram_type][0];
490    for (j = 0; j < 4; j++) {
491        temp1 = (temp >> (2 * j)) & 0x03;
492        temp2 |= temp1;
493        xgifb_reg_set(P3d4, 0x89, temp2);
494        xgifb_reg_get(P3d4, 0x89); /* Insert read command for delay */
495        temp2 &= 0xF0;
496        temp2 += 0x10;
497    }
498
499    temp = pVBInfo->CR89[pVBInfo->ram_type][1];
500    temp1 = temp & 0x03;
501    temp2 |= temp1;
502    xgifb_reg_set(P3d4, 0x89, temp2);
503
504    temp = pVBInfo->CR40[3][pVBInfo->ram_type];
505    temp1 = temp & 0x0F;
506    temp2 = (temp >> 4) & 0x07;
507    temp3 = temp & 0x80;
508    xgifb_reg_set(P3d4, 0x45, temp1); /* CR45 */
509    xgifb_reg_set(P3d4, 0x99, temp2); /* CR99 */
510    xgifb_reg_or(P3d4, 0x40, temp3); /* CR40_D[7] */
511    xgifb_reg_set(P3d4,
512              0x41,
513              pVBInfo->CR40[0][pVBInfo->ram_type]); /* CR41 */
514
515    if (HwDeviceExtension->jChipType == XG27)
516        xgifb_reg_set(P3d4, 0x8F, XG27_CR8F); /* CR8F */
517
518    for (j = 0; j <= 6; j++) /* CR90 - CR96 */
519        xgifb_reg_set(P3d4, (0x90 + j),
520                pVBInfo->CR40[14 + j][pVBInfo->ram_type]);
521
522    for (j = 0; j <= 2; j++) /* CRC3 - CRC5 */
523        xgifb_reg_set(P3d4, (0xC3 + j),
524                pVBInfo->CR40[21 + j][pVBInfo->ram_type]);
525
526    for (j = 0; j < 2; j++) /* CR8A - CR8B */
527        xgifb_reg_set(P3d4, (0x8A + j),
528                pVBInfo->CR40[1 + j][pVBInfo->ram_type]);
529
530    if (HwDeviceExtension->jChipType == XG42)
531        xgifb_reg_set(P3d4, 0x8C, 0x87);
532
533    xgifb_reg_set(P3d4,
534              0x59,
535              pVBInfo->CR40[4][pVBInfo->ram_type]); /* CR59 */
536
537    xgifb_reg_set(P3d4, 0x83, 0x09); /* CR83 */
538    xgifb_reg_set(P3d4, 0x87, 0x00); /* CR87 */
539    xgifb_reg_set(P3d4, 0xCF, XG40_CRCF); /* CRCF */
540    if (pVBInfo->ram_type) {
541        xgifb_reg_set(P3c4, 0x17, 0x80); /* SR17 DDRII */
542        if (HwDeviceExtension->jChipType == XG27)
543            xgifb_reg_set(P3c4, 0x17, 0x02); /* SR17 DDRII */
544
545    } else {
546        xgifb_reg_set(P3c4, 0x17, 0x00); /* SR17 DDR */
547    }
548    xgifb_reg_set(P3c4, 0x1A, 0x87); /* SR1A */
549
550    temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
551    if (temp == 0) {
552        XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
553    } else {
554        xgifb_reg_set(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */
555        XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
556    }
557    xgifb_reg_set(P3c4,
558              0x1B,
559              pVBInfo->SR15[3][pVBInfo->ram_type]); /* SR1B */
560}
561
562
563static unsigned short XGINew_SetDRAMSize20Reg(
564        unsigned short dram_size,
565        struct vb_device_info *pVBInfo)
566{
567    unsigned short data = 0, memsize = 0;
568    int RankSize;
569    unsigned char ChannelNo;
570
571    RankSize = dram_size * pVBInfo->ram_bus / 8;
572    data = xgifb_reg_get(pVBInfo->P3c4, 0x13);
573    data &= 0x80;
574
575    if (data == 0x80)
576        RankSize *= 2;
577
578    data = 0;
579
580    if (pVBInfo->ram_channel == 3)
581        ChannelNo = 4;
582    else
583        ChannelNo = pVBInfo->ram_channel;
584
585    if (ChannelNo * RankSize <= 256) {
586        while ((RankSize >>= 1) > 0)
587            data += 0x10;
588
589        memsize = data >> 4;
590
591        /* Fix DRAM Sizing Error */
592        xgifb_reg_set(pVBInfo->P3c4,
593                  0x14,
594                  (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) |
595                (data & 0xF0));
596        udelay(15);
597    }
598    return memsize;
599}
600
601static int XGINew_ReadWriteRest(unsigned short StopAddr,
602        unsigned short StartAddr, struct vb_device_info *pVBInfo)
603{
604    int i;
605    unsigned long Position = 0;
606    void __iomem *fbaddr = pVBInfo->FBAddr;
607
608    writel(Position, fbaddr + Position);
609
610    for (i = StartAddr; i <= StopAddr; i++) {
611        Position = 1 << i;
612        writel(Position, fbaddr + Position);
613    }
614
615    udelay(500); /* Fix #1759 Memory Size error in Multi-Adapter. */
616
617    Position = 0;
618
619    if (readl(fbaddr + Position) != Position)
620        return 0;
621
622    for (i = StartAddr; i <= StopAddr; i++) {
623        Position = 1 << i;
624        if (readl(fbaddr + Position) != Position)
625            return 0;
626    }
627    return 1;
628}
629
630static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
631{
632    unsigned char data;
633
634    data = xgifb_reg_get(pVBInfo->P3d4, 0x97);
635
636    if ((data & 0x10) == 0) {
637        data = xgifb_reg_get(pVBInfo->P3c4, 0x39);
638        data = (data & 0x02) >> 1;
639        return data;
640    } else {
641        return data & 0x01;
642    }
643}
644
645static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension,
646        struct vb_device_info *pVBInfo)
647{
648    unsigned char data;
649
650    switch (HwDeviceExtension->jChipType) {
651    case XG20:
652    case XG21:
653        data = xgifb_reg_get(pVBInfo->P3d4, 0x97);
654        data = data & 0x01;
655        pVBInfo->ram_channel = 1; /* XG20 "JUST" one channel */
656
657        if (data == 0) { /* Single_32_16 */
658
659            if ((HwDeviceExtension->ulVideoMemorySize - 1)
660                    > 0x1000000) {
661
662                pVBInfo->ram_bus = 32; /* 32 bits */
663                /* 22bit + 2 rank + 32bit */
664                xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
665                xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52);
666                udelay(15);
667
668                if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
669                    return;
670
671                if ((HwDeviceExtension->ulVideoMemorySize - 1) >
672                    0x800000) {
673                    /* 22bit + 1 rank + 32bit */
674                    xgifb_reg_set(pVBInfo->P3c4,
675                              0x13,
676                              0x31);
677                    xgifb_reg_set(pVBInfo->P3c4,
678                              0x14,
679                              0x42);
680                    udelay(15);
681
682                    if (XGINew_ReadWriteRest(23,
683                                 23,
684                                 pVBInfo) == 1)
685                        return;
686                }
687            }
688
689            if ((HwDeviceExtension->ulVideoMemorySize - 1) >
690                0x800000) {
691                pVBInfo->ram_bus = 16; /* 16 bits */
692                /* 22bit + 2 rank + 16bit */
693                xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
694                xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41);
695                udelay(15);
696
697                if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
698                    return;
699                else
700                    xgifb_reg_set(pVBInfo->P3c4,
701                              0x13,
702                              0x31);
703                udelay(15);
704            }
705
706        } else { /* Dual_16_8 */
707            if ((HwDeviceExtension->ulVideoMemorySize - 1) >
708                0x800000) {
709                pVBInfo->ram_bus = 16; /* 16 bits */
710                /* (0x31:12x8x2) 22bit + 2 rank */
711                xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
712                /* 0x41:16Mx16 bit*/
713                xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41);
714                udelay(15);
715
716                if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
717                    return;
718
719                if ((HwDeviceExtension->ulVideoMemorySize - 1) >
720                    0x400000) {
721                    /* (0x31:12x8x2) 22bit + 1 rank */
722                    xgifb_reg_set(pVBInfo->P3c4,
723                              0x13,
724                              0x31);
725                    /* 0x31:8Mx16 bit*/
726                    xgifb_reg_set(pVBInfo->P3c4,
727                              0x14,
728                              0x31);
729                    udelay(15);
730
731                    if (XGINew_ReadWriteRest(22,
732                                 22,
733                                 pVBInfo) == 1)
734                        return;
735                }
736            }
737
738            if ((HwDeviceExtension->ulVideoMemorySize - 1) >
739                0x400000) {
740                pVBInfo->ram_bus = 8; /* 8 bits */
741                /* (0x31:12x8x2) 22bit + 2 rank */
742                xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
743                /* 0x30:8Mx8 bit*/
744                xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30);
745                udelay(15);
746
747                if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1)
748                    return;
749                else /* (0x31:12x8x2) 22bit + 1 rank */
750                    xgifb_reg_set(pVBInfo->P3c4,
751                              0x13,
752                              0x31);
753                udelay(15);
754            }
755        }
756        break;
757
758    case XG27:
759        pVBInfo->ram_bus = 16; /* 16 bits */
760        pVBInfo->ram_channel = 1; /* Single channel */
761        xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/
762        break;
763    case XG42:
764        /*
765         XG42 SR14 D[3] Reserve
766         D[2] = 1, Dual Channel
767         = 0, Single Channel
768
769         It's Different from Other XG40 Series.
770         */
771        if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */
772            pVBInfo->ram_bus = 32; /* 32 bits */
773            pVBInfo->ram_channel = 2; /* 2 Channel */
774            xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
775            xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x44);
776
777            if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
778                return;
779
780            xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
781            xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x34);
782            if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
783                return;
784
785            pVBInfo->ram_channel = 1; /* Single Channel */
786            xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
787            xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x40);
788
789            if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
790                return;
791            else {
792                xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
793                xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30);
794            }
795        } else { /* DDR */
796            pVBInfo->ram_bus = 64; /* 64 bits */
797            pVBInfo->ram_channel = 1; /* 1 channels */
798            xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
799            xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52);
800
801            if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
802                return;
803            else {
804                xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
805                xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42);
806            }
807        }
808
809        break;
810
811    default: /* XG40 */
812
813        if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */
814            pVBInfo->ram_bus = 32; /* 32 bits */
815            pVBInfo->ram_channel = 3;
816            xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
817            xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C);
818
819            if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
820                return;
821
822            pVBInfo->ram_channel = 2; /* 2 channels */
823            xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48);
824
825            if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
826                return;
827
828            xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
829            xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C);
830
831            if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) {
832                pVBInfo->ram_channel = 3; /* 4 channels */
833            } else {
834                pVBInfo->ram_channel = 2; /* 2 channels */
835                xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38);
836            }
837        } else { /* DDR */
838            pVBInfo->ram_bus = 64; /* 64 bits */
839            pVBInfo->ram_channel = 2; /* 2 channels */
840            xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1);
841            xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A);
842
843            if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) {
844                return;
845            } else {
846                xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21);
847                xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A);
848            }
849        }
850        break;
851    }
852}
853
854static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension,
855        struct vb_device_info *pVBInfo)
856{
857    u8 i, size;
858    unsigned short memsize, start_addr;
859    const unsigned short (*dram_table)[2];
860
861    xgifb_reg_set(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */
862    xgifb_reg_set(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */
863    XGINew_CheckChannel(HwDeviceExtension, pVBInfo);
864
865    if (HwDeviceExtension->jChipType >= XG20) {
866        dram_table = XGINew_DDRDRAM_TYPE20;
867        size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE20);
868        start_addr = 5;
869    } else {
870        dram_table = XGINew_DDRDRAM_TYPE340;
871        size = ARRAY_SIZE(XGINew_DDRDRAM_TYPE340);
872        start_addr = 9;
873    }
874
875    for (i = 0; i < size; i++) {
876        /* SetDRAMSizingType */
877        xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, dram_table[i][1]);
878        udelay(15); /* should delay 50 ns */
879
880        memsize = XGINew_SetDRAMSize20Reg(dram_table[i][0], pVBInfo);
881
882        if (memsize == 0)
883            continue;
884
885        memsize += (pVBInfo->ram_channel - 2) + 20;
886        if ((HwDeviceExtension->ulVideoMemorySize - 1) <
887            (unsigned long) (1 << memsize))
888            continue;
889
890        if (XGINew_ReadWriteRest(memsize, start_addr, pVBInfo) == 1)
891            return 1;
892    }
893    return 0;
894}
895
896static void XGINew_SetDRAMSize_340(struct xgifb_video_info *xgifb_info,
897        struct xgi_hw_device_info *HwDeviceExtension,
898        struct vb_device_info *pVBInfo)
899{
900    unsigned short data;
901
902    pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
903
904    XGISetModeNew(xgifb_info, HwDeviceExtension, 0x2e);
905
906    data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
907    /* disable read cache */
908    xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF));
909    XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
910
911    XGINew_DDRSizing340(HwDeviceExtension, pVBInfo);
912    data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
913    /* enable read cache */
914    xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20));
915}
916
917static u8 *xgifb_copy_rom(struct pci_dev *dev, size_t *rom_size)
918{
919    void __iomem *rom_address;
920    u8 *rom_copy;
921
922    rom_address = pci_map_rom(dev, rom_size);
923    if (rom_address == NULL)
924        return NULL;
925
926    rom_copy = vzalloc(XGIFB_ROM_SIZE);
927    if (rom_copy == NULL)
928        goto done;
929
930    *rom_size = min_t(size_t, *rom_size, XGIFB_ROM_SIZE);
931    memcpy_fromio(rom_copy, rom_address, *rom_size);
932
933done:
934    pci_unmap_rom(dev, rom_address);
935    return rom_copy;
936}
937
938static void xgifb_read_vbios(struct pci_dev *pdev,
939                  struct vb_device_info *pVBInfo)
940{
941    struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
942    u8 *vbios;
943    unsigned long i;
944    unsigned char j;
945    struct XGI21_LVDSCapStruct *lvds;
946    size_t vbios_size;
947    int entry;
948
949    if (xgifb_info->chip != XG21)
950        return;
951    pVBInfo->IF_DEF_LVDS = 0;
952    vbios = xgifb_copy_rom(pdev, &vbios_size);
953    if (vbios == NULL) {
954        dev_err(&pdev->dev, "Video BIOS not available\n");
955        return;
956    }
957    if (vbios_size <= 0x65)
958        goto error;
959    /*
960     * The user can ignore the LVDS bit in the BIOS and force the display
961     * type.
962     */
963    if (!(vbios[0x65] & 0x1) &&
964        (!xgifb_info->display2_force ||
965         xgifb_info->display2 != XGIFB_DISP_LCD)) {
966        vfree(vbios);
967        return;
968    }
969    if (vbios_size <= 0x317)
970        goto error;
971    i = vbios[0x316] | (vbios[0x317] << 8);
972    if (vbios_size <= i - 1)
973        goto error;
974    j = vbios[i - 1];
975    if (j == 0)
976        goto error;
977    if (j == 0xff)
978        j = 1;
979    /*
980     * Read the LVDS table index scratch register set by the BIOS.
981     */
982    entry = xgifb_reg_get(xgifb_info->dev_info.P3d4, 0x36);
983    if (entry >= j)
984        entry = 0;
985    i += entry * 25;
986    lvds = &xgifb_info->lvds_data;
987    if (vbios_size <= i + 24)
988        goto error;
989    lvds->LVDS_Capability = vbios[i] | (vbios[i + 1] << 8);
990    lvds->LVDSHT = vbios[i + 2] | (vbios[i + 3] << 8);
991    lvds->LVDSVT = vbios[i + 4] | (vbios[i + 5] << 8);
992    lvds->LVDSHDE = vbios[i + 6] | (vbios[i + 7] << 8);
993    lvds->LVDSVDE = vbios[i + 8] | (vbios[i + 9] << 8);
994    lvds->LVDSHFP = vbios[i + 10] | (vbios[i + 11] << 8);
995    lvds->LVDSVFP = vbios[i + 12] | (vbios[i + 13] << 8);
996    lvds->LVDSHSYNC = vbios[i + 14] | (vbios[i + 15] << 8);
997    lvds->LVDSVSYNC = vbios[i + 16] | (vbios[i + 17] << 8);
998    lvds->VCLKData1 = vbios[i + 18];
999    lvds->VCLKData2 = vbios[i + 19];
1000    lvds->PSC_S1 = vbios[i + 20];
1001    lvds->PSC_S2 = vbios[i + 21];
1002    lvds->PSC_S3 = vbios[i + 22];
1003    lvds->PSC_S4 = vbios[i + 23];
1004    lvds->PSC_S5 = vbios[i + 24];
1005    vfree(vbios);
1006    pVBInfo->IF_DEF_LVDS = 1;
1007    return;
1008error:
1009    dev_err(&pdev->dev, "Video BIOS corrupted\n");
1010    vfree(vbios);
1011}
1012
1013static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
1014        struct vb_device_info *pVBInfo)
1015{
1016    unsigned short tempbx = 0, temp, tempcx, CR3CData;
1017
1018    temp = xgifb_reg_get(pVBInfo->P3d4, 0x32);
1019
1020    if (temp & Monitor1Sense)
1021        tempbx |= ActiveCRT1;
1022    if (temp & LCDSense)
1023        tempbx |= ActiveLCD;
1024    if (temp & Monitor2Sense)
1025        tempbx |= ActiveCRT2;
1026    if (temp & TVSense) {
1027        tempbx |= ActiveTV;
1028        if (temp & AVIDEOSense)
1029            tempbx |= (ActiveAVideo << 8);
1030        if (temp & SVIDEOSense)
1031            tempbx |= (ActiveSVideo << 8);
1032        if (temp & SCARTSense)
1033            tempbx |= (ActiveSCART << 8);
1034        if (temp & HiTVSense)
1035            tempbx |= (ActiveHiTV << 8);
1036        if (temp & YPbPrSense)
1037            tempbx |= (ActiveYPbPr << 8);
1038    }
1039
1040    tempcx = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
1041    tempcx |= (xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8);
1042
1043    if (tempbx & tempcx) {
1044        CR3CData = xgifb_reg_get(pVBInfo->P3d4, 0x3c);
1045        if (!(CR3CData & DisplayDeviceFromCMOS))
1046            tempcx = 0x1FF0;
1047    } else {
1048        tempcx = 0x1FF0;
1049    }
1050
1051    tempbx &= tempcx;
1052    xgifb_reg_set(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF));
1053    xgifb_reg_set(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8));
1054}
1055
1056static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension,
1057        struct vb_device_info *pVBInfo)
1058{
1059    unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data;
1060
1061    temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d);
1062    temp |= xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8;
1063    temp |= (xgifb_reg_get(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8;
1064
1065    if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
1066        if (temp & ActiveCRT2)
1067            tempcl = SetCRT2ToRAMDAC;
1068    }
1069
1070    if (temp & ActiveLCD) {
1071        tempcl |= SetCRT2ToLCD;
1072        if (temp & DriverMode) {
1073            if (temp & ActiveTV) {
1074                tempch = SetToLCDA | EnableDualEdge;
1075                temp ^= SetCRT2ToLCD;
1076
1077                if ((temp >> 8) & ActiveAVideo)
1078                    tempcl |= SetCRT2ToAVIDEO;
1079                if ((temp >> 8) & ActiveSVideo)
1080                    tempcl |= SetCRT2ToSVIDEO;
1081                if ((temp >> 8) & ActiveSCART)
1082                    tempcl |= SetCRT2ToSCART;
1083
1084                if (pVBInfo->IF_DEF_HiVision == 1) {
1085                    if ((temp >> 8) & ActiveHiTV)
1086                        tempcl |= SetCRT2ToHiVision;
1087                }
1088
1089                if (pVBInfo->IF_DEF_YPbPr == 1) {
1090                    if ((temp >> 8) & ActiveYPbPr)
1091                        tempch |= SetYPbPr;
1092                }
1093            }
1094        }
1095    } else {
1096        if ((temp >> 8) & ActiveAVideo)
1097            tempcl |= SetCRT2ToAVIDEO;
1098        if ((temp >> 8) & ActiveSVideo)
1099            tempcl |= SetCRT2ToSVIDEO;
1100        if ((temp >> 8) & ActiveSCART)
1101            tempcl |= SetCRT2ToSCART;
1102
1103        if (pVBInfo->IF_DEF_HiVision == 1) {
1104            if ((temp >> 8) & ActiveHiTV)
1105                tempcl |= SetCRT2ToHiVision;
1106        }
1107
1108        if (pVBInfo->IF_DEF_YPbPr == 1) {
1109            if ((temp >> 8) & ActiveYPbPr)
1110                tempch |= SetYPbPr;
1111        }
1112    }
1113
1114    tempcl |= SetSimuScanMode;
1115    if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV)
1116            || (temp & ActiveCRT2)))
1117        tempcl ^= (SetSimuScanMode | SwitchCRT2);
1118    if ((temp & ActiveLCD) && (temp & ActiveTV))
1119        tempcl ^= (SetSimuScanMode | SwitchCRT2);
1120    xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl);
1121
1122    CR31Data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
1123    CR31Data &= ~(SetNotSimuMode >> 8);
1124    if (!(temp & ActiveCRT1))
1125        CR31Data |= (SetNotSimuMode >> 8);
1126    CR31Data &= ~(DisableCRT2Display >> 8);
1127    if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2)))
1128        CR31Data |= (DisableCRT2Display >> 8);
1129    xgifb_reg_set(pVBInfo->P3d4, 0x31, CR31Data);
1130
1131    CR38Data = xgifb_reg_get(pVBInfo->P3d4, 0x38);
1132    CR38Data &= ~SetYPbPr;
1133    CR38Data |= tempch;
1134    xgifb_reg_set(pVBInfo->P3d4, 0x38, CR38Data);
1135
1136}
1137
1138static unsigned short XGINew_SenseLCD(struct xgi_hw_device_info
1139                            *HwDeviceExtension,
1140                      struct vb_device_info *pVBInfo)
1141{
1142    unsigned short temp;
1143
1144    /* add lcd sense */
1145    if (HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN) {
1146        return 0;
1147    } else {
1148        temp = (unsigned short) HwDeviceExtension->ulCRT2LCDType;
1149        switch (HwDeviceExtension->ulCRT2LCDType) {
1150        case LCD_INVALID:
1151        case LCD_800x600:
1152        case LCD_1024x768:
1153        case LCD_1280x1024:
1154            break;
1155
1156        case LCD_640x480:
1157        case LCD_1024x600:
1158        case LCD_1152x864:
1159        case LCD_1280x960:
1160        case LCD_1152x768:
1161            temp = 0;
1162            break;
1163
1164        case LCD_1400x1050:
1165        case LCD_1280x768:
1166        case LCD_1600x1200:
1167            break;
1168
1169        case LCD_1920x1440:
1170        case LCD_2048x1536:
1171            temp = 0;
1172            break;
1173
1174        default:
1175            break;
1176        }
1177        xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp);
1178        return 1;
1179    }
1180}
1181
1182static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension,
1183        struct vb_device_info *pVBInfo)
1184{
1185    unsigned char Temp;
1186
1187    if (pVBInfo->IF_DEF_LVDS) { /* For XG21 LVDS */
1188        xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
1189        /* LVDS on chip */
1190        xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
1191    } else {
1192        /* Enable GPIOA/B read */
1193        xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
1194        Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0;
1195        if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
1196            XGINew_SenseLCD(HwDeviceExtension, pVBInfo);
1197            xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
1198            /* Enable read GPIOF */
1199            xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20);
1200            Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04;
1201            if (!Temp)
1202                xgifb_reg_and_or(pVBInfo->P3d4,
1203                         0x38,
1204                         ~0xE0,
1205                         0x80); /* TMDS on chip */
1206            else
1207                xgifb_reg_and_or(pVBInfo->P3d4,
1208                         0x38,
1209                         ~0xE0,
1210                         0xA0); /* Only DVO on chip */
1211            /* Disable read GPIOF */
1212            xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20);
1213        }
1214    }
1215}
1216
1217static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension,
1218        struct vb_device_info *pVBInfo)
1219{
1220    unsigned char Temp, bCR4A;
1221
1222    pVBInfo->IF_DEF_LVDS = 0;
1223    bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
1224    /* Enable GPIOA/B/C read */
1225    xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07);
1226    Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07;
1227    xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A);
1228
1229    if (Temp <= 0x02) {
1230        /* LVDS setting */
1231        xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
1232        xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21);
1233    } else {
1234        /* TMDS/DVO setting */
1235        xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0);
1236    }
1237    xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
1238
1239}
1240
1241static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
1242{
1243    unsigned char CR38, CR4A, temp;
1244
1245    CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
1246    /* enable GPIOE read */
1247    xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10);
1248    CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38);
1249    temp = 0;
1250    if ((CR38 & 0xE0) > 0x80) {
1251        temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
1252        temp &= 0x08;
1253        temp >>= 3;
1254    }
1255
1256    xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
1257
1258    return temp;
1259}
1260
1261static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
1262{
1263    unsigned char CR4A, temp;
1264
1265    CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
1266    /* enable GPIOA/B/C read */
1267    xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
1268    temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
1269    if (temp <= 2)
1270        temp &= 0x03;
1271    else
1272        temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01);
1273
1274    xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
1275
1276    return temp;
1277}
1278
1279unsigned char XGIInitNew(struct pci_dev *pdev)
1280{
1281    struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
1282    struct xgi_hw_device_info *HwDeviceExtension = &xgifb_info->hw_info;
1283    struct vb_device_info VBINF;
1284    struct vb_device_info *pVBInfo = &VBINF;
1285    unsigned char i, temp = 0, temp1;
1286
1287    pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
1288
1289    pVBInfo->BaseAddr = xgifb_info->vga_base;
1290
1291    if (pVBInfo->FBAddr == NULL) {
1292        dev_dbg(&pdev->dev, "pVBInfo->FBAddr == 0\n");
1293        return 0;
1294    }
1295    if (pVBInfo->BaseAddr == 0) {
1296        dev_dbg(&pdev->dev, "pVBInfo->BaseAddr == 0\n");
1297        return 0;
1298    }
1299
1300    outb(0x67, (pVBInfo->BaseAddr + 0x12)); /* 3c2 <- 67 ,ynlai */
1301
1302    pVBInfo->ISXPDOS = 0;
1303
1304    pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
1305    pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
1306    pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
1307    pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
1308    pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
1309    pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
1310    pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
1311    pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
1312    pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
1313    pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
1314    pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
1315    pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
1316    pVBInfo->Part1Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_04;
1317    pVBInfo->Part2Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_10;
1318    pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12;
1319    pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14;
1320    pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2;
1321
1322    if (HwDeviceExtension->jChipType < XG20)
1323        /* Run XGI_GetVBType before InitTo330Pointer */
1324        XGI_GetVBType(pVBInfo);
1325
1326    InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
1327
1328    xgifb_read_vbios(pdev, pVBInfo);
1329
1330    /* Openkey */
1331    xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
1332
1333    /* GetXG21Sense (GPIO) */
1334    if (HwDeviceExtension->jChipType == XG21)
1335        XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo);
1336
1337    if (HwDeviceExtension->jChipType == XG27)
1338        XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo);
1339
1340    /* Reset Extended register */
1341
1342    for (i = 0x06; i < 0x20; i++)
1343        xgifb_reg_set(pVBInfo->P3c4, i, 0);
1344
1345    for (i = 0x21; i <= 0x27; i++)
1346        xgifb_reg_set(pVBInfo->P3c4, i, 0);
1347
1348    for (i = 0x31; i <= 0x3B; i++)
1349        xgifb_reg_set(pVBInfo->P3c4, i, 0);
1350
1351    /* Auto over driver for XG42 */
1352    if (HwDeviceExtension->jChipType == XG42)
1353        xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0);
1354
1355    for (i = 0x79; i <= 0x7C; i++)
1356        xgifb_reg_set(pVBInfo->P3d4, i, 0);
1357
1358    if (HwDeviceExtension->jChipType >= XG20)
1359        xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97);
1360
1361    /* SetDefExt1Regs begin */
1362    xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07);
1363    if (HwDeviceExtension->jChipType == XG27) {
1364        xgifb_reg_set(pVBInfo->P3c4, 0x40, XG27_SR40);
1365        xgifb_reg_set(pVBInfo->P3c4, 0x41, XG27_SR41);
1366    }
1367    xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F);
1368    xgifb_reg_set(pVBInfo->P3c4, 0x1F, XGI330_SR1F);
1369    /* Frame buffer can read/write SR20 */
1370    xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0);
1371    /* H/W request for slow corner chip */
1372    xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70);
1373    if (HwDeviceExtension->jChipType == XG27)
1374        xgifb_reg_set(pVBInfo->P3c4, 0x36, XG27_SR36);
1375
1376    if (HwDeviceExtension->jChipType < XG20) {
1377        u32 Temp;
1378
1379        /* Set AGP customize registers (in SetDefAGPRegs) Start */
1380        for (i = 0x47; i <= 0x4C; i++)
1381            xgifb_reg_set(pVBInfo->P3d4,
1382                      i,
1383                      pVBInfo->AGPReg[i - 0x47]);
1384
1385        for (i = 0x70; i <= 0x71; i++)
1386            xgifb_reg_set(pVBInfo->P3d4,
1387                      i,
1388                      pVBInfo->AGPReg[6 + i - 0x70]);
1389
1390        for (i = 0x74; i <= 0x77; i++)
1391            xgifb_reg_set(pVBInfo->P3d4,
1392                      i,
1393                      pVBInfo->AGPReg[8 + i - 0x74]);
1394
1395        pci_read_config_dword(pdev, 0x50, &Temp);
1396        Temp >>= 20;
1397        Temp &= 0xF;
1398
1399        if (Temp == 1)
1400            xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
1401    } /* != XG20 */
1402
1403    /* Set PCI */
1404    xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23);
1405    xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24);
1406    xgifb_reg_set(pVBInfo->P3c4, 0x25, XGI330_SR25);
1407
1408    if (HwDeviceExtension->jChipType < XG20) {
1409        /* Set VB */
1410        XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
1411        /* disable VideoCapture */
1412        xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
1413        xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00);
1414        /* chk if BCLK>=100MHz */
1415        temp1 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x7B);
1416        temp = (unsigned char) ((temp1 >> 4) & 0x0F);
1417
1418        xgifb_reg_set(pVBInfo->Part1Port,
1419                  0x02, XGI330_CRT2Data_1_2);
1420
1421        xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
1422    } /* != XG20 */
1423
1424    xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F);
1425
1426    if ((HwDeviceExtension->jChipType == XG42) &&
1427        XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) {
1428        /* Not DDR */
1429        xgifb_reg_set(pVBInfo->P3c4,
1430                  0x31,
1431                  (XGI330_SR31 & 0x3F) | 0x40);
1432        xgifb_reg_set(pVBInfo->P3c4,
1433                  0x32,
1434                  (XGI330_SR32 & 0xFC) | 0x01);
1435    } else {
1436        xgifb_reg_set(pVBInfo->P3c4, 0x31, XGI330_SR31);
1437        xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32);
1438    }
1439    xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33);
1440
1441    if (HwDeviceExtension->jChipType < XG20) {
1442        if (XGI_BridgeIsOn(pVBInfo) == 1) {
1443            if (pVBInfo->IF_DEF_LVDS == 0) {
1444                xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C);
1445                xgifb_reg_set(pVBInfo->Part4Port,
1446                          0x0D, XGI330_CRT2Data_4_D);
1447                xgifb_reg_set(pVBInfo->Part4Port,
1448                          0x0E, XGI330_CRT2Data_4_E);
1449                xgifb_reg_set(pVBInfo->Part4Port,
1450                          0x10, XGI330_CRT2Data_4_10);
1451                xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F);
1452            }
1453
1454            XGI_LockCRT2(HwDeviceExtension, pVBInfo);
1455        }
1456    } /* != XG20 */
1457
1458    XGI_SenseCRT1(pVBInfo);
1459
1460    if (HwDeviceExtension->jChipType == XG21) {
1461
1462        xgifb_reg_and_or(pVBInfo->P3d4,
1463                 0x32,
1464                 ~Monitor1Sense,
1465                 Monitor1Sense); /* Z9 default has CRT */
1466        temp = GetXG21FPBits(pVBInfo);
1467        xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp);
1468
1469    }
1470    if (HwDeviceExtension->jChipType == XG27) {
1471        xgifb_reg_and_or(pVBInfo->P3d4,
1472                 0x32,
1473                 ~Monitor1Sense,
1474                 Monitor1Sense); /* Z9 default has CRT */
1475        temp = GetXG27FPBits(pVBInfo);
1476        xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp);
1477    }
1478
1479    pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
1480
1481    XGINew_SetDRAMDefaultRegister340(HwDeviceExtension,
1482                     pVBInfo->P3d4,
1483                     pVBInfo);
1484
1485    XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo);
1486
1487    xgifb_reg_set(pVBInfo->P3c4,
1488              0x22,
1489              (unsigned char) ((pVBInfo->SR22) & 0xFE));
1490
1491    xgifb_reg_set(pVBInfo->P3c4, 0x21, pVBInfo->SR21);
1492
1493    XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo);
1494    XGINew_SetModeScratch(HwDeviceExtension, pVBInfo);
1495
1496    xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87);
1497    xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x31);
1498
1499    return 1;
1500} /* end of init */
1501

Archive Download this file



interactive