• 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 		 */
62 		/* DVI read GPIOH */
63 		data &= 0x01; /* 1=DDRII, 0=DDR */
64 		/* ~HOTPLUG_SUPPORT */
65 		xgifb_reg_or(pVBInfo->P3d4, 0xB4, 0x02);
66 		return data;
67 	}
68 	data = xgifb_reg_get(pVBInfo->P3d4, 0x97) & 0x01;
69 
70 	if (data == 1)
71 		data++;
72 
73 	return data;
74 }
75 
XGINew_DDR1x_MRS_340(unsigned long P3c4,struct vb_device_info * pVBInfo)76 static void XGINew_DDR1x_MRS_340(unsigned long P3c4,
77 				 struct vb_device_info *pVBInfo)
78 {
79 	xgifb_reg_set(P3c4, 0x18, 0x01);
80 	xgifb_reg_set(P3c4, 0x19, 0x20);
81 	xgifb_reg_set(P3c4, 0x16, 0x00);
82 	xgifb_reg_set(P3c4, 0x16, 0x80);
83 
84 	usleep_range(3, 1003);
85 	xgifb_reg_set(P3c4, 0x18, 0x00);
86 	xgifb_reg_set(P3c4, 0x19, 0x20);
87 	xgifb_reg_set(P3c4, 0x16, 0x00);
88 	xgifb_reg_set(P3c4, 0x16, 0x80);
89 
90 	usleep_range(60, 1060);
91 	xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
92 	xgifb_reg_set(P3c4, 0x19, 0x01);
93 	xgifb_reg_set(P3c4, 0x16, 0x03);
94 	xgifb_reg_set(P3c4, 0x16, 0x83);
95 	usleep_range(1, 1001);
96 	xgifb_reg_set(P3c4, 0x1B, 0x03);
97 	usleep_range(500, 1500);
98 	xgifb_reg_set(P3c4, 0x18, pVBInfo->SR18[pVBInfo->ram_type]); /* SR18 */
99 	xgifb_reg_set(P3c4, 0x19, 0x00);
100 	xgifb_reg_set(P3c4, 0x16, 0x03);
101 	xgifb_reg_set(P3c4, 0x16, 0x83);
102 	xgifb_reg_set(P3c4, 0x1B, 0x00);
103 }
104 
XGINew_SetMemoryClock(struct vb_device_info * pVBInfo)105 static void XGINew_SetMemoryClock(struct vb_device_info *pVBInfo)
106 {
107 	xgifb_reg_set(pVBInfo->P3c4,
108 		      0x28,
109 		      pVBInfo->MCLKData[pVBInfo->ram_type].SR28);
110 	xgifb_reg_set(pVBInfo->P3c4,
111 		      0x29,
112 		      pVBInfo->MCLKData[pVBInfo->ram_type].SR29);
113 	xgifb_reg_set(pVBInfo->P3c4,
114 		      0x2A,
115 		      pVBInfo->MCLKData[pVBInfo->ram_type].SR2A);
116 
117 	xgifb_reg_set(pVBInfo->P3c4,
118 		      0x2E,
119 		      XGI340_ECLKData[pVBInfo->ram_type].SR2E);
120 	xgifb_reg_set(pVBInfo->P3c4,
121 		      0x2F,
122 		      XGI340_ECLKData[pVBInfo->ram_type].SR2F);
123 	xgifb_reg_set(pVBInfo->P3c4,
124 		      0x30,
125 		      XGI340_ECLKData[pVBInfo->ram_type].SR30);
126 }
127 
XGINew_DDRII_Bootup_XG27(struct xgi_hw_device_info * HwDeviceExtension,unsigned long P3c4,struct vb_device_info * pVBInfo)128 static void XGINew_DDRII_Bootup_XG27(
129 			struct xgi_hw_device_info *HwDeviceExtension,
130 			unsigned long P3c4, struct vb_device_info *pVBInfo)
131 {
132 	unsigned long P3d4 = P3c4 + 0x10;
133 
134 	pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
135 	XGINew_SetMemoryClock(pVBInfo);
136 
137 	/* Set Double Frequency */
138 	xgifb_reg_set(P3d4, 0x97, pVBInfo->XGINew_CR97); /* CR97 */
139 
140 	usleep_range(200, 1200);
141 
142 	xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */
143 	xgifb_reg_set(P3c4, 0x19, 0x80); /* Set SR19 */
144 	xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
145 	usleep_range(15, 1015);
146 	xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
147 	usleep_range(15, 1015);
148 
149 	xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */
150 	xgifb_reg_set(P3c4, 0x19, 0xC0); /* Set SR19 */
151 	xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
152 	usleep_range(15, 1015);
153 	xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
154 	usleep_range(15, 1015);
155 
156 	xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */
157 	xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */
158 	xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
159 	usleep_range(30, 1030);
160 	xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
161 	usleep_range(15, 1015);
162 
163 	xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */
164 	xgifb_reg_set(P3c4, 0x19, 0x0A); /* Set SR19 */
165 	xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
166 	usleep_range(30, 1030);
167 	xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
168 	xgifb_reg_set(P3c4, 0x16, 0x80); /* Set SR16 */
169 
170 	xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B */
171 	usleep_range(60, 1060);
172 	xgifb_reg_set(P3c4, 0x1B, 0x00); /* Set SR1B */
173 
174 	xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */
175 	xgifb_reg_set(P3c4, 0x19, 0x08); /* Set SR19 */
176 	xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */
177 
178 	usleep_range(30, 1030);
179 	xgifb_reg_set(P3c4, 0x16, 0x83); /* Set SR16 */
180 	usleep_range(15, 1015);
181 
182 	xgifb_reg_set(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */
183 	xgifb_reg_set(P3c4, 0x19, 0x46); /* Set SR19 */
184 	xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
185 	usleep_range(30, 1030);
186 	xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
187 	usleep_range(15, 1015);
188 
189 	xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */
190 	xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */
191 	xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */
192 	usleep_range(30, 1030);
193 	xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
194 	usleep_range(15, 1015);
195 
196 	/* Set SR1B refresh control 000:close; 010:open */
197 	xgifb_reg_set(P3c4, 0x1B, 0x04);
198 	usleep_range(200, 1200);
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 	usleep_range(200, 1200);
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 	usleep_range(15, 1015);
233 	xgifb_reg_set(P3c4, 0x1B, 0x04); /* SR1B */
234 	usleep_range(30, 1030);
235 	xgifb_reg_set(P3c4, 0x1B, 0x00); /* SR1B */
236 	usleep_range(100, 1100);
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 	usleep_range(200, 1200);
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 	usleep_range(60, 1060);
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 	usleep_range(60, 1060);
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 	usleep_range(1, 1001);
265 	xgifb_reg_set(P3c4, 0x1B, 0x03);
266 	usleep_range(500, 1500);
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 	 */
360 	xgifb_reg_set(P3d4, 0x82, 0x77);
361 	xgifb_reg_set(P3d4, 0x86, 0x00);
362 	xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
363 	xgifb_reg_set(P3d4, 0x86, 0x88);
364 	xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
365 	/* CR86 */
366 	xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][pVBInfo->ram_type]);
367 	xgifb_reg_set(P3d4, 0x82, 0x77);
368 	xgifb_reg_set(P3d4, 0x85, 0x00);
369 	xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
370 	xgifb_reg_set(P3d4, 0x85, 0x88);
371 	xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
372 	xgifb_reg_set(P3d4,
373 		      0x85,
374 		      pVBInfo->CR40[12][pVBInfo->ram_type]); /* CR85 */
375 	if (HwDeviceExtension->jChipType == XG27)
376 		/* CR82 */
377 		xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][pVBInfo->ram_type]);
378 	else
379 		xgifb_reg_set(P3d4, 0x82, 0xA8); /* CR82 */
380 
381 	xgifb_reg_set(P3d4, 0x98, 0x01);
382 	xgifb_reg_set(P3d4, 0x9A, 0x02);
383 	if (HwDeviceExtension->jChipType == XG27)
384 		XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo);
385 	else
386 		XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo);
387 }
388 
XGI_SetDRAM_Helper(unsigned long P3d4,u8 seed,u8 temp2,u8 reg,u8 shift_factor,u8 mask1,u8 mask2)389 static void XGI_SetDRAM_Helper(unsigned long P3d4, u8 seed, u8 temp2, u8 reg,
390 	u8 shift_factor, u8 mask1, u8 mask2)
391 {
392 	u8 j;
393 
394 	for (j = 0; j < 4; j++) {
395 		temp2 |= (((seed >> (2 * j)) & 0x03) << shift_factor);
396 		xgifb_reg_set(P3d4, reg, temp2);
397 		xgifb_reg_get(P3d4, reg);
398 		temp2 &= mask1;
399 		temp2 += mask2;
400 	}
401 }
402 
XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info * HwDeviceExtension,unsigned long Port,struct vb_device_info * pVBInfo)403 static void XGINew_SetDRAMDefaultRegister340(
404 		struct xgi_hw_device_info *HwDeviceExtension,
405 		unsigned long Port, struct vb_device_info *pVBInfo)
406 {
407 	unsigned char temp, temp1, temp2, temp3, j, k;
408 
409 	unsigned long P3d4 = Port, P3c4 = Port - 0x10;
410 
411 	xgifb_reg_set(P3d4, 0x6D, pVBInfo->CR40[8][pVBInfo->ram_type]);
412 	xgifb_reg_set(P3d4, 0x68, pVBInfo->CR40[5][pVBInfo->ram_type]);
413 	xgifb_reg_set(P3d4, 0x69, pVBInfo->CR40[6][pVBInfo->ram_type]);
414 	xgifb_reg_set(P3d4, 0x6A, pVBInfo->CR40[7][pVBInfo->ram_type]);
415 
416 	/* CR6B DQS fine tune delay */
417 	temp = 0xaa;
418 	XGI_SetDRAM_Helper(P3d4, temp, 0, 0x6B, 2, 0xF0, 0x10);
419 
420 	/* CR6E DQM fine tune delay */
421 	XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6E, 2, 0xF0, 0x10);
422 
423 	temp3 = 0;
424 	for (k = 0; k < 4; k++) {
425 		/* CR6E_D[1:0] select channel */
426 		xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3);
427 		XGI_SetDRAM_Helper(P3d4, 0, 0, 0x6F, 0, 0xF8, 0x08);
428 		temp3 += 0x01;
429 	}
430 
431 	xgifb_reg_set(P3d4,
432 		      0x80,
433 		      pVBInfo->CR40[9][pVBInfo->ram_type]); /* CR80 */
434 	xgifb_reg_set(P3d4,
435 		      0x81,
436 		      pVBInfo->CR40[10][pVBInfo->ram_type]); /* CR81 */
437 
438 	temp2 = 0x80;
439 	/* CR89 terminator type select */
440 	XGI_SetDRAM_Helper(P3d4, 0, temp2, 0x89, 0, 0xF0, 0x10);
441 
442 	temp = 0;
443 	temp1 = temp & 0x03;
444 	temp2 |= temp1;
445 	xgifb_reg_set(P3d4, 0x89, temp2);
446 
447 	temp = pVBInfo->CR40[3][pVBInfo->ram_type];
448 	temp1 = temp & 0x0F;
449 	temp2 = (temp >> 4) & 0x07;
450 	temp3 = temp & 0x80;
451 	xgifb_reg_set(P3d4, 0x45, temp1); /* CR45 */
452 	xgifb_reg_set(P3d4, 0x99, temp2); /* CR99 */
453 	xgifb_reg_or(P3d4, 0x40, temp3); /* CR40_D[7] */
454 	xgifb_reg_set(P3d4,
455 		      0x41,
456 		      pVBInfo->CR40[0][pVBInfo->ram_type]); /* CR41 */
457 
458 	if (HwDeviceExtension->jChipType == XG27)
459 		xgifb_reg_set(P3d4, 0x8F, XG27_CR8F); /* CR8F */
460 
461 	for (j = 0; j <= 6; j++) /* CR90 - CR96 */
462 		xgifb_reg_set(P3d4, (0x90 + j),
463 				pVBInfo->CR40[14 + j][pVBInfo->ram_type]);
464 
465 	for (j = 0; j <= 2; j++) /* CRC3 - CRC5 */
466 		xgifb_reg_set(P3d4, (0xC3 + j),
467 				pVBInfo->CR40[21 + j][pVBInfo->ram_type]);
468 
469 	for (j = 0; j < 2; j++) /* CR8A - CR8B */
470 		xgifb_reg_set(P3d4, (0x8A + j),
471 				pVBInfo->CR40[1 + j][pVBInfo->ram_type]);
472 
473 	if (HwDeviceExtension->jChipType == XG42)
474 		xgifb_reg_set(P3d4, 0x8C, 0x87);
475 
476 	xgifb_reg_set(P3d4,
477 		      0x59,
478 		      pVBInfo->CR40[4][pVBInfo->ram_type]); /* CR59 */
479 
480 	xgifb_reg_set(P3d4, 0x83, 0x09); /* CR83 */
481 	xgifb_reg_set(P3d4, 0x87, 0x00); /* CR87 */
482 	xgifb_reg_set(P3d4, 0xCF, XG40_CRCF); /* CRCF */
483 	if (pVBInfo->ram_type) {
484 		xgifb_reg_set(P3c4, 0x17, 0x80); /* SR17 DDRII */
485 		if (HwDeviceExtension->jChipType == XG27)
486 			xgifb_reg_set(P3c4, 0x17, 0x02); /* SR17 DDRII */
487 
488 	} else {
489 		xgifb_reg_set(P3c4, 0x17, 0x00); /* SR17 DDR */
490 	}
491 	xgifb_reg_set(P3c4, 0x1A, 0x87); /* SR1A */
492 
493 	temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
494 	if (temp == 0) {
495 		XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
496 	} else {
497 		xgifb_reg_set(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */
498 		XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
499 	}
500 	xgifb_reg_set(P3c4, 0x1B, 0x03); /* SR1B */
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 		usleep_range(15, 1015);
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 	/* Fix #1759 Memory Size error in Multi-Adapter. */
556 	usleep_range(500, 1500);
557 
558 	Position = 0;
559 
560 	if (readl(fbaddr + Position) != Position)
561 		return 0;
562 
563 	for (i = StartAddr; i <= StopAddr; i++) {
564 		Position = 1 << i;
565 		if (readl(fbaddr + Position) != Position)
566 			return 0;
567 	}
568 	return 1;
569 }
570 
XGINew_CheckFrequence(struct vb_device_info * pVBInfo)571 static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
572 {
573 	unsigned char data;
574 
575 	data = xgifb_reg_get(pVBInfo->P3d4, 0x97);
576 
577 	if ((data & 0x10) == 0) {
578 		data = xgifb_reg_get(pVBInfo->P3c4, 0x39);
579 		data = (data & 0x02) >> 1;
580 		return data;
581 	}
582 	return data & 0x01;
583 }
584 
XGINew_CheckChannel(struct xgi_hw_device_info * HwDeviceExtension,struct vb_device_info * pVBInfo)585 static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension,
586 		struct vb_device_info *pVBInfo)
587 {
588 	unsigned char data;
589 
590 	switch (HwDeviceExtension->jChipType) {
591 	case XG20:
592 	case XG21:
593 		data = xgifb_reg_get(pVBInfo->P3d4, 0x97);
594 		data = data & 0x01;
595 		pVBInfo->ram_channel = 1; /* XG20 "JUST" one channel */
596 
597 		if (data == 0) { /* Single_32_16 */
598 
599 			if ((HwDeviceExtension->ulVideoMemorySize - 1)
600 					> 0x1000000) {
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 				usleep_range(15, 1015);
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 					usleep_range(15, 1015);
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 				usleep_range(15, 1015);
635 
636 				if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
637 					return;
638 				xgifb_reg_set(pVBInfo->P3c4,
639 					      0x13,
640 					      0x31);
641 				usleep_range(15, 1015);
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 				usleep_range(15, 1015);
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 					usleep_range(15, 1015);
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 				usleep_range(15, 1015);
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 				usleep_range(15, 1015);
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 		usleep_range(50, 1050); /* 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)
857 		return NULL;
858 
859 	rom_copy = vzalloc(XGIFB_ROM_SIZE);
860 	if (!rom_copy)
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) {
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 
XGINew_SenseLCD(struct xgi_hw_device_info * HwDeviceExtension,struct vb_device_info * pVBInfo)1064 static unsigned short XGINew_SenseLCD(struct xgi_hw_device_info
1065 							*HwDeviceExtension,
1066 				      struct vb_device_info *pVBInfo)
1067 {
1068 	unsigned short temp = HwDeviceExtension->ulCRT2LCDType;
1069 
1070 	switch (HwDeviceExtension->ulCRT2LCDType) {
1071 	case LCD_640x480:
1072 	case LCD_1024x600:
1073 	case LCD_1152x864:
1074 	case LCD_1280x960:
1075 	case LCD_1152x768:
1076 	case LCD_1920x1440:
1077 	case LCD_2048x1536:
1078 		temp = 0; /* overwrite used ulCRT2LCDType */
1079 		break;
1080 	case LCD_UNKNOWN: /* unknown lcd, do nothing */
1081 		return 0;
1082 	}
1083 	xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp);
1084 	return 1;
1085 }
1086 
XGINew_GetXG21Sense(struct pci_dev * pdev,struct vb_device_info * pVBInfo)1087 static void XGINew_GetXG21Sense(struct pci_dev *pdev,
1088 		struct vb_device_info *pVBInfo)
1089 {
1090 	struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
1091 	unsigned char Temp;
1092 
1093 	if (xgifb_read_vbios(pdev)) { /* For XG21 LVDS */
1094 		xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
1095 		/* LVDS on chip */
1096 		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
1097 	} else {
1098 		/* Enable GPIOA/B read  */
1099 		xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
1100 		Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0;
1101 		if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
1102 			XGINew_SenseLCD(&xgifb_info->hw_info, pVBInfo);
1103 			xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
1104 			/* Enable read GPIOF */
1105 			xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20);
1106 			if (xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04)
1107 				Temp = 0xA0; /* Only DVO on chip */
1108 			else
1109 				Temp = 0x80; /* TMDS on chip */
1110 			xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, Temp);
1111 			/* Disable read GPIOF */
1112 			xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20);
1113 		}
1114 	}
1115 }
1116 
XGINew_GetXG27Sense(struct vb_device_info * pVBInfo)1117 static void XGINew_GetXG27Sense(struct vb_device_info *pVBInfo)
1118 {
1119 	unsigned char Temp, bCR4A;
1120 
1121 	bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
1122 	/* Enable GPIOA/B/C read  */
1123 	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07);
1124 	Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07;
1125 	xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A);
1126 
1127 	if (Temp <= 0x02) {
1128 		/* LVDS setting */
1129 		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
1130 		xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21);
1131 	} else {
1132 		/* TMDS/DVO setting */
1133 		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0);
1134 	}
1135 	xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
1136 }
1137 
GetXG21FPBits(struct vb_device_info * pVBInfo)1138 static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
1139 {
1140 	unsigned char CR38, CR4A, temp;
1141 
1142 	CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
1143 	/* enable GPIOE read */
1144 	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10);
1145 	CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38);
1146 	temp = 0;
1147 	if ((CR38 & 0xE0) > 0x80) {
1148 		temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
1149 		temp &= 0x08;
1150 		temp >>= 3;
1151 	}
1152 
1153 	xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
1154 
1155 	return temp;
1156 }
1157 
GetXG27FPBits(struct vb_device_info * pVBInfo)1158 static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
1159 {
1160 	unsigned char CR4A, temp;
1161 
1162 	CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
1163 	/* enable GPIOA/B/C read */
1164 	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
1165 	temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
1166 	if (temp > 2)
1167 		temp = ((temp & 0x04) >> 1) | ((~temp) & 0x01);
1168 
1169 	xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A);
1170 
1171 	return temp;
1172 }
1173 
xgifb_bridge_is_on(struct vb_device_info * vb_info)1174 static bool xgifb_bridge_is_on(struct vb_device_info *vb_info)
1175 {
1176 	u8 flag;
1177 
1178 	flag = xgifb_reg_get(vb_info->Part4Port, 0x00);
1179 	return flag == 1 || flag == 2;
1180 }
1181 
XGIInitNew(struct pci_dev * pdev)1182 unsigned char XGIInitNew(struct pci_dev *pdev)
1183 {
1184 	struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
1185 	struct xgi_hw_device_info *HwDeviceExtension = &xgifb_info->hw_info;
1186 	struct vb_device_info VBINF;
1187 	struct vb_device_info *pVBInfo = &VBINF;
1188 	unsigned char i, temp = 0, temp1;
1189 
1190 	pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
1191 
1192 	if (!pVBInfo->FBAddr) {
1193 		dev_dbg(&pdev->dev, "pVBInfo->FBAddr == 0\n");
1194 		return 0;
1195 	}
1196 
1197 	XGIRegInit(pVBInfo, xgifb_info->vga_base);
1198 
1199 	outb(0x67, pVBInfo->P3c2);
1200 
1201 	InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
1202 
1203 	/* Openkey */
1204 	xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86);
1205 
1206 	/* GetXG21Sense (GPIO) */
1207 	if (HwDeviceExtension->jChipType == XG21)
1208 		XGINew_GetXG21Sense(pdev, pVBInfo);
1209 
1210 	if (HwDeviceExtension->jChipType == XG27)
1211 		XGINew_GetXG27Sense(pVBInfo);
1212 
1213 	/* Reset Extended register */
1214 
1215 	for (i = 0x06; i < 0x20; i++)
1216 		xgifb_reg_set(pVBInfo->P3c4, i, 0);
1217 
1218 	for (i = 0x21; i <= 0x27; i++)
1219 		xgifb_reg_set(pVBInfo->P3c4, i, 0);
1220 
1221 	for (i = 0x31; i <= 0x3B; i++)
1222 		xgifb_reg_set(pVBInfo->P3c4, i, 0);
1223 
1224 	/* Auto over driver for XG42 */
1225 	if (HwDeviceExtension->jChipType == XG42)
1226 		xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0);
1227 
1228 	for (i = 0x79; i <= 0x7C; i++)
1229 		xgifb_reg_set(pVBInfo->P3d4, i, 0);
1230 
1231 	if (HwDeviceExtension->jChipType >= XG20)
1232 		xgifb_reg_set(pVBInfo->P3d4, 0x97, pVBInfo->XGINew_CR97);
1233 
1234 	/* SetDefExt1Regs begin */
1235 	xgifb_reg_set(pVBInfo->P3c4, 0x07, XGI330_SR07);
1236 	if (HwDeviceExtension->jChipType == XG27) {
1237 		xgifb_reg_set(pVBInfo->P3c4, 0x40, XG27_SR40);
1238 		xgifb_reg_set(pVBInfo->P3c4, 0x41, XG27_SR41);
1239 	}
1240 	xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F);
1241 	xgifb_reg_set(pVBInfo->P3c4, 0x1F, XGI330_SR1F);
1242 	/* Frame buffer can read/write SR20 */
1243 	xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0);
1244 	/* H/W request for slow corner chip */
1245 	xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70);
1246 	if (HwDeviceExtension->jChipType == XG27)
1247 		xgifb_reg_set(pVBInfo->P3c4, 0x36, XG27_SR36);
1248 
1249 	if (HwDeviceExtension->jChipType < XG20) {
1250 		u32 Temp;
1251 
1252 		/* Set AGP customize registers (in SetDefAGPRegs) Start */
1253 		for (i = 0x47; i <= 0x4C; i++)
1254 			xgifb_reg_set(pVBInfo->P3d4,
1255 				      i,
1256 				      XGI340_AGPReg[i - 0x47]);
1257 
1258 		for (i = 0x70; i <= 0x71; i++)
1259 			xgifb_reg_set(pVBInfo->P3d4,
1260 				      i,
1261 				      XGI340_AGPReg[6 + i - 0x70]);
1262 
1263 		for (i = 0x74; i <= 0x77; i++)
1264 			xgifb_reg_set(pVBInfo->P3d4,
1265 				      i,
1266 				      XGI340_AGPReg[8 + i - 0x74]);
1267 
1268 		pci_read_config_dword(pdev, 0x50, &Temp);
1269 		Temp >>= 20;
1270 		Temp &= 0xF;
1271 
1272 		if (Temp == 1)
1273 			xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
1274 	} /* != XG20 */
1275 
1276 	/* Set PCI */
1277 	xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23);
1278 	xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24);
1279 	xgifb_reg_set(pVBInfo->P3c4, 0x25, 0);
1280 
1281 	if (HwDeviceExtension->jChipType < XG20) {
1282 		/* Set VB */
1283 		XGI_UnLockCRT2(pVBInfo);
1284 		/* disable VideoCapture */
1285 		xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
1286 		xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00);
1287 		/* chk if BCLK>=100MHz */
1288 		temp1 = xgifb_reg_get(pVBInfo->P3d4, 0x7B);
1289 
1290 		xgifb_reg_set(pVBInfo->Part1Port,
1291 			      0x02, XGI330_CRT2Data_1_2);
1292 
1293 		xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
1294 	} /* != XG20 */
1295 
1296 	xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F);
1297 
1298 	if ((HwDeviceExtension->jChipType == XG42) &&
1299 	    XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) {
1300 		/* Not DDR */
1301 		xgifb_reg_set(pVBInfo->P3c4,
1302 			      0x31,
1303 			      (XGI330_SR31 & 0x3F) | 0x40);
1304 		xgifb_reg_set(pVBInfo->P3c4,
1305 			      0x32,
1306 			      (XGI330_SR32 & 0xFC) | 0x01);
1307 	} else {
1308 		xgifb_reg_set(pVBInfo->P3c4, 0x31, XGI330_SR31);
1309 		xgifb_reg_set(pVBInfo->P3c4, 0x32, XGI330_SR32);
1310 	}
1311 	xgifb_reg_set(pVBInfo->P3c4, 0x33, XGI330_SR33);
1312 
1313 	if (HwDeviceExtension->jChipType < XG20) {
1314 		if (xgifb_bridge_is_on(pVBInfo)) {
1315 			xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C);
1316 			xgifb_reg_set(pVBInfo->Part4Port,
1317 				      0x0D, XGI330_CRT2Data_4_D);
1318 			xgifb_reg_set(pVBInfo->Part4Port,
1319 				      0x0E, XGI330_CRT2Data_4_E);
1320 			xgifb_reg_set(pVBInfo->Part4Port,
1321 				      0x10, XGI330_CRT2Data_4_10);
1322 			xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F);
1323 			XGI_LockCRT2(pVBInfo);
1324 		}
1325 	} /* != XG20 */
1326 
1327 	XGI_SenseCRT1(pVBInfo);
1328 
1329 	if (HwDeviceExtension->jChipType == XG21) {
1330 		xgifb_reg_and_or(pVBInfo->P3d4,
1331 				 0x32,
1332 				 ~Monitor1Sense,
1333 				 Monitor1Sense); /* Z9 default has CRT */
1334 		temp = GetXG21FPBits(pVBInfo);
1335 		xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp);
1336 	}
1337 	if (HwDeviceExtension->jChipType == XG27) {
1338 		xgifb_reg_and_or(pVBInfo->P3d4,
1339 				 0x32,
1340 				 ~Monitor1Sense,
1341 				 Monitor1Sense); /* Z9 default has CRT */
1342 		temp = GetXG27FPBits(pVBInfo);
1343 		xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp);
1344 	}
1345 
1346 	pVBInfo->ram_type = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
1347 
1348 	XGINew_SetDRAMDefaultRegister340(HwDeviceExtension,
1349 					 pVBInfo->P3d4,
1350 					 pVBInfo);
1351 
1352 	XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo);
1353 
1354 	xgifb_reg_set(pVBInfo->P3c4, 0x22, 0xfa);
1355 	xgifb_reg_set(pVBInfo->P3c4, 0x21, 0xa3);
1356 
1357 	XGINew_ChkSenseStatus(pVBInfo);
1358 	XGINew_SetModeScratch(pVBInfo);
1359 
1360 	xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87);
1361 
1362 	return 1;
1363 } /* end of init */
1364