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