1 #include <linux/version.h>
2 #include <asm/io.h>
3 #include <linux/types.h>
4 #include "XGIfb.h"
5 
6 #include "vb_def.h"
7 #include "vgatypes.h"
8 #include "vb_struct.h"
9 #include "vb_util.h"
10 #include "vb_setmode.h"
11 #include "vb_ext.h"
12 
13 /**************************************************************
14  *********************** Dynamic Sense ************************
15  *************************************************************/
16 
XGINew_Is301B(struct vb_device_info * pVBInfo)17 static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo)
18 {
19 	unsigned short flag;
20 
21 	flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
22 
23 	if (flag > 0x0B0)
24 		return 0; /* 301b */
25 	else
26 		return 1;
27 }
28 
XGINew_Sense(unsigned short tempbx,unsigned short tempcx,struct vb_device_info * pVBInfo)29 static unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, struct vb_device_info *pVBInfo)
30 {
31 	unsigned short temp, i, tempch;
32 
33 	temp = tempbx & 0xFF;
34 	xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp);
35 	temp = (tempbx & 0xFF00) >> 8;
36 	temp |= (tempcx & 0x00FF);
37 	xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
38 
39 	for (i = 0; i < 10; i++)
40 		XGI_LongWait(pVBInfo);
41 
42 	tempch = (tempcx & 0x7F00) >> 8;
43 	temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03);
44 	temp = temp ^ (0x0E);
45 	temp &= tempch;
46 
47 	if (temp > 0)
48 		return 1;
49 	else
50 		return 0;
51 }
52 
XGINew_GetLCDDDCInfo(struct xgi_hw_device_info * HwDeviceExtension,struct vb_device_info * pVBInfo)53 static unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
54 {
55 	unsigned short temp;
56 
57 	/* add lcd sense */
58 	if (HwDeviceExtension->ulCRT2LCDType == LCD_UNKNOWN) {
59 		return 0;
60 	} else {
61 		temp = (unsigned short) HwDeviceExtension->ulCRT2LCDType;
62 		switch (HwDeviceExtension->ulCRT2LCDType) {
63 		case LCD_INVALID:
64 		case LCD_800x600:
65 		case LCD_1024x768:
66 		case LCD_1280x1024:
67 			break;
68 
69 		case LCD_640x480:
70 		case LCD_1024x600:
71 		case LCD_1152x864:
72 		case LCD_1280x960:
73 		case LCD_1152x768:
74 			temp = 0;
75 			break;
76 
77 		case LCD_1400x1050:
78 		case LCD_1280x768:
79 		case LCD_1600x1200:
80 			break;
81 
82 		case LCD_1920x1440:
83 		case LCD_2048x1536:
84 			temp = 0;
85 			break;
86 
87 		default:
88 			break;
89 		}
90 		xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp);
91 		return 1;
92 	}
93 }
94 
XGINew_GetPanelID(struct vb_device_info * pVBInfo)95 static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo)
96 {
97 	unsigned short PanelTypeTable[16] = { SyncNN | PanelRGB18Bit
98 			| Panel800x600  | _PanelType00, SyncNN | PanelRGB18Bit
99 			| Panel1024x768 | _PanelType01, SyncNN | PanelRGB18Bit
100 			| Panel800x600  | _PanelType02, SyncNN | PanelRGB18Bit
101 			| Panel640x480  | _PanelType03, SyncNN | PanelRGB18Bit
102 			| Panel1024x768 | _PanelType04, SyncNN | PanelRGB18Bit
103 			| Panel1024x768 | _PanelType05, SyncNN | PanelRGB18Bit
104 			| Panel1024x768 | _PanelType06, SyncNN | PanelRGB24Bit
105 			| Panel1024x768 | _PanelType07, SyncNN | PanelRGB18Bit
106 			| Panel800x600  | _PanelType08, SyncNN | PanelRGB18Bit
107 			| Panel1024x768 | _PanelType09, SyncNN | PanelRGB18Bit
108 			| Panel800x600  | _PanelType0A, SyncNN | PanelRGB18Bit
109 			| Panel1024x768 | _PanelType0B, SyncNN | PanelRGB18Bit
110 			| Panel1024x768 | _PanelType0C, SyncNN | PanelRGB24Bit
111 			| Panel1024x768 | _PanelType0D, SyncNN | PanelRGB18Bit
112 			| Panel1024x768 | _PanelType0E, SyncNN | PanelRGB18Bit
113 			| Panel1024x768 | _PanelType0F };
114 	unsigned short tempax, tempbx, temp;
115 	/* unsigned short return_flag; */
116 
117 	tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A);
118 	tempbx = tempax & 0x1E;
119 
120 	if (tempax == 0)
121 		return 0;
122 	else {
123 		/*
124 		if (!(tempax & 0x10)) {
125 			if (pVBInfo->IF_DEF_LVDS == 1) {
126 				tempbx = 0;
127 				temp = xgifb_reg_get(pVBInfo->P3c4, 0x38);
128 				if (temp & 0x40)
129 					tempbx |= 0x08;
130 				if (temp & 0x20)
131 					tempbx |= 0x02;
132 				if (temp & 0x01)
133 					tempbx |= 0x01;
134 
135 				temp = xgifb_reg_get(pVBInfo->P3c4, 0x39);
136 				if (temp & 0x80)
137 					tempbx |= 0x04;
138 			 } else {
139 				return(0);
140 			 }
141 		}
142 		*/
143 
144 		tempbx = tempbx >> 1;
145 		temp = tempbx & 0x00F;
146 		xgifb_reg_set(pVBInfo->P3d4, 0x36, temp);
147 		tempbx--;
148 		tempbx = PanelTypeTable[tempbx];
149 
150 		temp = (tempbx & 0xFF00) >> 8;
151 		xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~(LCDSyncBit
152 				| LCDRGB18Bit), temp);
153 		return 1;
154 	}
155 }
156 
XGINew_BridgeIsEnable(struct xgi_hw_device_info * HwDeviceExtension,struct vb_device_info * pVBInfo)157 static unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
158 {
159 	unsigned short flag;
160 
161 	if (XGI_BridgeIsOn(pVBInfo) == 0) {
162 		flag = xgifb_reg_get(pVBInfo->Part1Port, 0x0);
163 
164 		if (flag & 0x050)
165 			return 1;
166 		else
167 			return 0;
168 
169 	}
170 	return 0;
171 }
172 
XGINew_SenseHiTV(struct xgi_hw_device_info * HwDeviceExtension,struct vb_device_info * pVBInfo)173 static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
174 {
175 	unsigned short tempbx, tempcx, temp, i, tempch;
176 
177 	tempbx = *pVBInfo->pYCSenseData2;
178 
179 	tempcx = 0x0604;
180 
181 	temp = tempbx & 0xFF;
182 	xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp);
183 	temp = (tempbx & 0xFF00) >> 8;
184 	temp |= (tempcx & 0x00FF);
185 	xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
186 
187 	for (i = 0; i < 10; i++)
188 		XGI_LongWait(pVBInfo);
189 
190 	tempch = (tempcx & 0xFF00) >> 8;
191 	temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03);
192 	temp = temp ^ (0x0E);
193 	temp &= tempch;
194 
195 	if (temp != tempch)
196 		return 0;
197 
198 	tempbx = *pVBInfo->pVideoSenseData2;
199 
200 	tempcx = 0x0804;
201 	temp = tempbx & 0xFF;
202 	xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp);
203 	temp = (tempbx & 0xFF00) >> 8;
204 	temp |= (tempcx & 0x00FF);
205 	xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
206 
207 	for (i = 0; i < 10; i++)
208 		XGI_LongWait(pVBInfo);
209 
210 	tempch = (tempcx & 0xFF00) >> 8;
211 	temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03);
212 	temp = temp ^ (0x0E);
213 	temp &= tempch;
214 
215 	if (temp != tempch) {
216 		return 0;
217 	} else {
218 		tempbx = 0x3FF;
219 		tempcx = 0x0804;
220 		temp = tempbx & 0xFF;
221 		xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp);
222 		temp = (tempbx & 0xFF00) >> 8;
223 		temp |= (tempcx & 0x00FF);
224 		xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp);
225 
226 		for (i = 0; i < 10; i++)
227 			XGI_LongWait(pVBInfo);
228 
229 		tempch = (tempcx & 0xFF00) >> 8;
230 		temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03);
231 		temp = temp ^ (0x0E);
232 		temp &= tempch;
233 
234 		if (temp != tempch)
235 			return 1;
236 		else
237 			return 0;
238 	}
239 }
240 
XGI_GetSenseStatus(struct xgi_hw_device_info * HwDeviceExtension,struct vb_device_info * pVBInfo)241 void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
242 {
243 	unsigned short tempax = 0, tempbx, tempcx, temp, P2reg0 = 0, SenseModeNo = 0,
244 			OutputSelect = *pVBInfo->pOutputSelect, ModeIdIndex, i;
245 	pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
246 
247 	if (pVBInfo->IF_DEF_LVDS == 1) {
248 		tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A); /* ynlai 02/27/2002 */
249 		tempbx = xgifb_reg_get(pVBInfo->P3c4, 0x1B);
250 		tempax = ((tempax & 0xFE) >> 1) | (tempbx << 8);
251 		if (tempax == 0x00) { /* Get Panel id from DDC */
252 			temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
253 			if (temp == 1) { /* LCD connect */
254 				xgifb_reg_and_or(pVBInfo->P3d4, 0x39, 0xFF, 0x01); /* set CR39 bit0="1" */
255 				xgifb_reg_and_or(pVBInfo->P3d4, 0x37, 0xEF, 0x00); /* clean CR37 bit4="0" */
256 				temp = LCDSense;
257 			} else { /* LCD don't connect */
258 				temp = 0;
259 			}
260 		} else {
261 			XGINew_GetPanelID(pVBInfo);
262 			temp = LCDSense;
263 		}
264 
265 		tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense);
266 		xgifb_reg_and_or(pVBInfo->P3d4, 0x32, tempbx, temp);
267 	} else { /* for 301 */
268 		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiVision */
269 			tempax = xgifb_reg_get(pVBInfo->P3c4, 0x38);
270 			temp = tempax & 0x01;
271 			tempax = xgifb_reg_get(pVBInfo->P3c4, 0x3A);
272 			temp = temp | (tempax & 0x02);
273 			xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xA0, temp);
274 		} else {
275 			if (XGI_BridgeIsOn(pVBInfo)) {
276 				P2reg0 = xgifb_reg_get(pVBInfo->Part2Port, 0x00);
277 				if (!XGINew_BridgeIsEnable(HwDeviceExtension, pVBInfo)) {
278 					SenseModeNo = 0x2e;
279 					/* xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x41); */
280 					/* XGISetModeNew(HwDeviceExtension, 0x2e); // ynlai InitMode */
281 
282 					temp = XGI_SearchModeID(SenseModeNo, &ModeIdIndex, pVBInfo);
283 					XGI_GetVGAType(HwDeviceExtension, pVBInfo);
284 					XGI_GetVBType(pVBInfo);
285 					pVBInfo->SetFlag = 0x00;
286 					pVBInfo->ModeType = ModeVGA;
287 					pVBInfo->VBInfo = SetCRT2ToRAMDAC | LoadDACFlag | SetInSlaveMode;
288 					XGI_GetLCDInfo(0x2e, ModeIdIndex, pVBInfo);
289 					XGI_GetTVInfo(0x2e, ModeIdIndex, pVBInfo);
290 					XGI_EnableBridge(HwDeviceExtension, pVBInfo);
291 					XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo);
292 					XGI_SetCRT2ModeRegs(0x2e, HwDeviceExtension, pVBInfo);
293 					/* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */
294 					xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20); /* Display Off 0212 */
295 					for (i = 0; i < 20; i++)
296 						XGI_LongWait(pVBInfo);
297 				}
298 				xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1c);
299 				tempax = 0;
300 				tempbx = *pVBInfo->pRGBSenseData;
301 
302 				if (!(XGINew_Is301B(pVBInfo)))
303 					tempbx = *pVBInfo->pRGBSenseData2;
304 
305 				tempcx = 0x0E08;
306 				if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
307 					if (XGINew_Sense(tempbx, tempcx, pVBInfo))
308 						tempax |= Monitor2Sense;
309 				}
310 
311 				if (pVBInfo->VBType & VB_XGI301C)
312 					xgifb_reg_or(pVBInfo->Part4Port, 0x0d, 0x04);
313 
314 				if (XGINew_SenseHiTV(HwDeviceExtension, pVBInfo)) { /* add by kuku for Multi-adapter sense HiTV */
315 					tempax |= HiTVSense;
316 					if ((pVBInfo->VBType & VB_XGI301C))
317 						tempax ^= (HiTVSense | YPbPrSense);
318 				}
319 
320 				if (!(tempax & (HiTVSense | YPbPrSense))) { /* start */
321 
322 					tempbx = *pVBInfo->pYCSenseData;
323 
324 					if (!(XGINew_Is301B(pVBInfo)))
325 						tempbx = *pVBInfo->pYCSenseData2;
326 
327 					tempcx = 0x0604;
328 					if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
329 						if (XGINew_Sense(tempbx, tempcx, pVBInfo))
330 							tempax |= SVIDEOSense;
331 					}
332 
333 					if (OutputSelect & BoardTVType) {
334 						tempbx = *pVBInfo->pVideoSenseData;
335 
336 						if (!(XGINew_Is301B(pVBInfo)))
337 							tempbx = *pVBInfo->pVideoSenseData2;
338 
339 						tempcx = 0x0804;
340 						if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
341 							if (XGINew_Sense(tempbx, tempcx, pVBInfo))
342 								tempax |= AVIDEOSense;
343 						}
344 					} else {
345 						if (!(tempax & SVIDEOSense)) {
346 							tempbx = *pVBInfo->pVideoSenseData;
347 
348 							if (!(XGINew_Is301B(pVBInfo)))
349 								tempbx = *pVBInfo->pVideoSenseData2;
350 
351 							tempcx = 0x0804;
352 							if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
353 								if (XGINew_Sense(tempbx, tempcx, pVBInfo))
354 									tempax |= AVIDEOSense;
355 							}
356 						}
357 					}
358 				}
359 			} /* end */
360 			if (!(tempax & Monitor2Sense)) {
361 				if (XGINew_SenseLCD(HwDeviceExtension, pVBInfo))
362 					tempax |= LCDSense;
363 			}
364 			tempbx = 0;
365 			tempcx = 0;
366 			XGINew_Sense(tempbx, tempcx, pVBInfo);
367 
368 			xgifb_reg_and_or(pVBInfo->P3d4, 0x32, ~0xDF, tempax);
369 			xgifb_reg_set(pVBInfo->Part2Port, 0x00, P2reg0);
370 
371 			if (!(P2reg0 & 0x20)) {
372 				pVBInfo->VBInfo = DisableCRT2Display;
373 				/* XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); */
374 			}
375 		}
376 	}
377 	XGI_DisableBridge(HwDeviceExtension, pVBInfo); /* shampoo 0226 */
378 
379 }
380 
XGINew_SenseLCD(struct xgi_hw_device_info * HwDeviceExtension,struct vb_device_info * pVBInfo)381 unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
382 {
383 	/* unsigned short SoftSetting ; */
384 	unsigned short temp;
385 
386 	temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
387 
388 	return temp;
389 }
390