• 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 		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