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