Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vb_init.c
Go to the documentation of this file.
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, 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 
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  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 
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 = 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 
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  pVBInfo->AGPReg[i - 0x47]);
1382 
1383  for (i = 0x70; i <= 0x71; i++)
1384  xgifb_reg_set(pVBInfo->P3d4,
1385  i,
1386  pVBInfo->AGPReg[6 + i - 0x70]);
1387 
1388  for (i = 0x74; i <= 0x77; i++)
1389  xgifb_reg_set(pVBInfo->P3d4,
1390  i,
1391  pVBInfo->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, XGI330_SR25);
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,
1486  0x22,
1487  (unsigned char) ((pVBInfo->SR22) & 0xFE));
1488 
1489  xgifb_reg_set(pVBInfo->P3c4, 0x21, pVBInfo->SR21);
1490 
1491  XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo);
1492  XGINew_SetModeScratch(HwDeviceExtension, pVBInfo);
1493 
1494  xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87);
1495 
1496  return 1;
1497 } /* end of init */