]> rtime.felk.cvut.cz Git - linux-imx.git/blob - drivers/staging/xgifb/vb_init.c
Merge branch 'for-3.8' of git://linux-nfs.org/~bfields/linux
[linux-imx.git] / 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"
9 static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = {
10         { 16, 0x45},
11         {  8, 0x35},
12         {  4, 0x31},
13         {  2, 0x21} };
14
15 static 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
31 static unsigned char
32 XGINew_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
78 static 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, 0x03);
98         xgifb_reg_set(P3c4, 0x16, 0x83);
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, 0x03);
107         xgifb_reg_set(P3c4, 0x16, 0x83);
108         xgifb_reg_set(P3c4, 0x1B, 0x00);
109 }
110
111 static 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                       XGI340_ECLKData[pVBInfo->ram_type].SR2E);
128         xgifb_reg_set(pVBInfo->P3c4,
129                       0x2F,
130                       XGI340_ECLKData[pVBInfo->ram_type].SR2F);
131         xgifb_reg_set(pVBInfo->P3c4,
132                       0x30,
133                       XGI340_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                     (((XGI340_ECLKData[pVBInfo->ram_type].SR2E == 0x1C) &&
142                       (XGI340_ECLKData[pVBInfo->ram_type].SR2F == 0x01)) ||
143                      ((XGI340_ECLKData[pVBInfo->ram_type].SR2E == 0x22) &&
144                       (XGI340_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
152 static 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
225 static 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
270 static 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
302 static 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
379 static 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
416 static 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 = XGI340_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 = 0;
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 = 0;
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 = 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 = 0;
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
563 static 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
601 static 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
630 static 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
645 static 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
854 static 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
896 static 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
917 static 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
933 done:
934         pci_unmap_rom(dev, rom_address);
935         return rom_copy;
936 }
937
938 static 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;
1008 error:
1009         dev_err(&pdev->dev, "Video BIOS corrupted\n");
1010         vfree(vbios);
1011 }
1012
1013 static 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
1056 static 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
1138 static 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
1182 static 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
1217 static 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
1241 static 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
1261 static 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
1279 unsigned 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->P3c4 = pVBInfo->BaseAddr + 0x14;
1303         pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
1304         pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
1305         pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
1306         pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
1307         pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
1308         pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
1309         pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
1310         pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
1311         pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
1312         pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
1313         pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
1314         pVBInfo->Part1Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_04;
1315         pVBInfo->Part2Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_10;
1316         pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12;
1317         pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14;
1318         pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2;
1319
1320         if (HwDeviceExtension->jChipType < XG20)
1321                 /* Run XGI_GetVBType before InitTo330Pointer */
1322                 XGI_GetVBType(pVBInfo);
1323
1324         InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
1325
1326         xgifb_read_vbios(pdev, pVBInfo);
1327
1328         /* Openkey */
1329         xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
1330
1331         /* GetXG21Sense (GPIO) */
1332         if (HwDeviceExtension->jChipType == XG21)
1333                 XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo);
1334
1335         if (HwDeviceExtension->jChipType == XG27)
1336                 XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo);
1337
1338         /* Reset Extended register */
1339
1340         for (i = 0x06; i < 0x20; i++)
1341                 xgifb_reg_set(pVBInfo->P3c4, i, 0);
1342
1343         for (i = 0x21; i <= 0x27; i++)
1344                 xgifb_reg_set(pVBInfo->P3c4, i, 0);
1345
1346         for (i = 0x31; i <= 0x3B; i++)
1347                 xgifb_reg_set(pVBInfo->P3c4, i, 0);
1348
1349         /* Auto over driver for XG42 */
1350         if (HwDeviceExtension->jChipType == XG42)
1351                 xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0);
1352
1353         for (i = 0x79; i <= 0x7C; i++)
1354                 xgifb_reg_set(pVBInfo->P3d4, i, 0);
1355
1356         if (HwDeviceExtension->jChipType >= XG20)
1357                 xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97);
1358
1359         /* SetDefExt1Regs begin */
1360         xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07);
1361         if (HwDeviceExtension->jChipType == XG27) {
1362                 xgifb_reg_set(pVBInfo->P3c4, 0x40, XG27_SR40);
1363                 xgifb_reg_set(pVBInfo->P3c4, 0x41, XG27_SR41);
1364         }
1365         xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F);
1366         xgifb_reg_set(pVBInfo->P3c4, 0x1F, XGI330_SR1F);
1367         /* Frame buffer can read/write SR20 */
1368         xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0);
1369         /* H/W request for slow corner chip */
1370         xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70);
1371         if (HwDeviceExtension->jChipType == XG27)
1372                 xgifb_reg_set(pVBInfo->P3c4, 0x36, XG27_SR36);
1373
1374         if (HwDeviceExtension->jChipType < XG20) {
1375                 u32 Temp;
1376
1377                 /* Set AGP customize registers (in SetDefAGPRegs) Start */
1378                 for (i = 0x47; i <= 0x4C; i++)
1379                         xgifb_reg_set(pVBInfo->P3d4,
1380                                       i,
1381                                       XGI340_AGPReg[i - 0x47]);
1382
1383                 for (i = 0x70; i <= 0x71; i++)
1384                         xgifb_reg_set(pVBInfo->P3d4,
1385                                       i,
1386                                       XGI340_AGPReg[6 + i - 0x70]);
1387
1388                 for (i = 0x74; i <= 0x77; i++)
1389                         xgifb_reg_set(pVBInfo->P3d4,
1390                                       i,
1391                                       XGI340_AGPReg[8 + i - 0x74]);
1392
1393                 pci_read_config_dword(pdev, 0x50, &Temp);
1394                 Temp >>= 20;
1395                 Temp &= 0xF;
1396
1397                 if (Temp == 1)
1398                         xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
1399         } /* != XG20 */
1400
1401         /* Set PCI */
1402         xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23);
1403         xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24);
1404         xgifb_reg_set(pVBInfo->P3c4, 0x25, 0);
1405
1406         if (HwDeviceExtension->jChipType < XG20) {
1407                 /* Set VB */
1408                 XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
1409                 /* disable VideoCapture */
1410                 xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
1411                 xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00);
1412                 /* chk if BCLK>=100MHz */
1413                 temp1 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x7B);
1414                 temp = (unsigned char) ((temp1 >> 4) & 0x0F);
1415
1416                 xgifb_reg_set(pVBInfo->Part1Port,
1417                               0x02, XGI330_CRT2Data_1_2);
1418
1419                 xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
1420         } /* != XG20 */
1421
1422         xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F);
1423
1424         if ((HwDeviceExtension->jChipType == XG42) &&
1425             XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) {
1426                 /* Not DDR */
1427                 xgifb_reg_set(pVBInfo->P3c4,
1428                               0x31,
1429                               (XGI330_SR31 & 0x3F) | 0x40);
1430                 xgifb_reg_set(pVBInfo->P3c4,
1431                               0x32,
1432                               (XGI330_SR32 & 0xFC) | 0x01);
1433         } else {
1434                 xgifb_reg_set(pVBInfo->P3c4, 0x31, XGI330_SR31);
1435                 xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32);
1436         }
1437         xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33);
1438
1439         if (HwDeviceExtension->jChipType < XG20) {
1440                 if (XGI_BridgeIsOn(pVBInfo) == 1) {
1441                         if (pVBInfo->IF_DEF_LVDS == 0) {
1442                                 xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C);
1443                                 xgifb_reg_set(pVBInfo->Part4Port,
1444                                               0x0D, XGI330_CRT2Data_4_D);
1445                                 xgifb_reg_set(pVBInfo->Part4Port,
1446                                               0x0E, XGI330_CRT2Data_4_E);
1447                                 xgifb_reg_set(pVBInfo->Part4Port,
1448                                               0x10, XGI330_CRT2Data_4_10);
1449                                 xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F);
1450                         }
1451
1452                         XGI_LockCRT2(HwDeviceExtension, pVBInfo);
1453                 }
1454         } /* != XG20 */
1455
1456         XGI_SenseCRT1(pVBInfo);
1457
1458         if (HwDeviceExtension->jChipType == XG21) {
1459
1460                 xgifb_reg_and_or(pVBInfo->P3d4,
1461                                  0x32,
1462                                  ~Monitor1Sense,
1463                                  Monitor1Sense); /* Z9 default has CRT */
1464                 temp = GetXG21FPBits(pVBInfo);
1465                 xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp);
1466
1467         }
1468         if (HwDeviceExtension->jChipType == XG27) {
1469                 xgifb_reg_and_or(pVBInfo->P3d4,
1470                                  0x32,
1471                                  ~Monitor1Sense,
1472                                  Monitor1Sense); /* Z9 default has CRT */
1473                 temp = GetXG27FPBits(pVBInfo);
1474                 xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp);
1475         }
1476
1477         pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
1478
1479         XGINew_SetDRAMDefaultRegister340(HwDeviceExtension,
1480                                          pVBInfo->P3d4,
1481                                          pVBInfo);
1482
1483         XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo);
1484
1485         xgifb_reg_set(pVBInfo->P3c4, 0x22, 0xfa);
1486         xgifb_reg_set(pVBInfo->P3c4, 0x21, 0xa3);
1487
1488         XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo);
1489         XGINew_SetModeScratch(HwDeviceExtension, pVBInfo);
1490
1491         xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87);
1492
1493         return 1;
1494 } /* end of init */