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