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