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"
9static const unsigned short XGINew_DDRDRAM_TYPE340[4][2] = {
10	{ 16, 0x45},
11	{  8, 0x35},
12	{  4, 0x31},
13	{  2, 0x21} };
14
15static 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
31static unsigned char
32XGINew_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
75static 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
104static 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
127static 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
201static 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
246static 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
274static 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
351static 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
388static 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
402static 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
503static 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
541static 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
570static 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
584static 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
787static 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
829static 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
850static 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
866done:
867	pci_unmap_rom(dev, rom_address);
868	return rom_copy;
869}
870
871static 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;
936error:
937	dev_err(&pdev->dev, "Video BIOS corrupted\n");
938	vfree(vbios);
939	return false;
940}
941
942static 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
984static 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
1065static 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
1088static 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
1118static 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
1140static 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
1160static 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
1176static 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
1184unsigned 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