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