diff options
Diffstat (limited to 'drivers/staging/xgifb')
-rw-r--r-- | drivers/staging/xgifb/vb_ext.c | 444 | ||||
-rw-r--r-- | drivers/staging/xgifb/vb_ext.h | 29 |
2 files changed, 473 insertions, 0 deletions
diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c new file mode 100644 index 00000000000..b1a25730b7c --- /dev/null +++ b/drivers/staging/xgifb/vb_ext.c | |||
@@ -0,0 +1,444 @@ | |||
1 | #include <linux/io.h> | ||
2 | #include <linux/types.h> | ||
3 | #include "XGIfb.h" | ||
4 | |||
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" | ||
11 | |||
12 | /************************************************************** | ||
13 | *********************** Dynamic Sense ************************ | ||
14 | *************************************************************/ | ||
15 | |||
16 | static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo) | ||
17 | { | ||
18 | unsigned short flag; | ||
19 | |||
20 | flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01); | ||
21 | |||
22 | if (flag > 0x0B0) | ||
23 | return 0; /* 301b */ | ||
24 | else | ||
25 | return 1; | ||
26 | } | ||
27 | |||
28 | static unsigned char XGINew_Sense(unsigned short tempbx, | ||
29 | unsigned short tempcx, | ||
30 | struct vb_device_info *pVBInfo) | ||
31 | { | ||
32 | unsigned short temp, i, tempch; | ||
33 | |||
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); | ||
39 | |||
40 | for (i = 0; i < 10; i++) | ||
41 | XGI_LongWait(pVBInfo); | ||
42 | |||
43 | tempch = (tempcx & 0x7F00) >> 8; | ||
44 | temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03); | ||
45 | temp = temp ^ (0x0E); | ||
46 | temp &= tempch; | ||
47 | |||
48 | if (temp > 0) | ||
49 | return 1; | ||
50 | else | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static unsigned char | ||
55 | XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, | ||
56 | struct vb_device_info *pVBInfo) | ||
57 | { | ||
58 | unsigned short temp; | ||
59 | |||
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; | ||
71 | |||
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; | ||
79 | |||
80 | case LCD_1400x1050: | ||
81 | case LCD_1280x768: | ||
82 | case LCD_1600x1200: | ||
83 | break; | ||
84 | |||
85 | case LCD_1920x1440: | ||
86 | case LCD_2048x1536: | ||
87 | temp = 0; | ||
88 | break; | ||
89 | |||
90 | default: | ||
91 | break; | ||
92 | } | ||
93 | xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp); | ||
94 | return 1; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) | ||
99 | { | ||
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; */ | ||
119 | |||
120 | tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A); | ||
121 | tempbx = tempax & 0x1E; | ||
122 | |||
123 | if (tempax == 0) | ||
124 | return 0; | ||
125 | else { | ||
126 | /* | ||
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; | ||
137 | |||
138 | temp = xgifb_reg_get(pVBInfo->P3c4, 0x39); | ||
139 | if (temp & 0x80) | ||
140 | tempbx |= 0x04; | ||
141 | } else { | ||
142 | return(0); | ||
143 | } | ||
144 | } | ||
145 | */ | ||
146 | |||
147 | tempbx = tempbx >> 1; | ||
148 | temp = tempbx & 0x00F; | ||
149 | xgifb_reg_set(pVBInfo->P3d4, 0x36, temp); | ||
150 | tempbx--; | ||
151 | tempbx = PanelTypeTable[tempbx]; | ||
152 | |||
153 | temp = (tempbx & 0xFF00) >> 8; | ||
154 | xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~(LCDSyncBit | ||
155 | | LCDRGB18Bit), temp); | ||
156 | return 1; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static unsigned char | ||
161 | XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension, | ||
162 | struct vb_device_info *pVBInfo) | ||
163 | { | ||
164 | unsigned short flag; | ||
165 | |||
166 | if (XGI_BridgeIsOn(pVBInfo) == 0) { | ||
167 | flag = xgifb_reg_get(pVBInfo->Part1Port, 0x0); | ||
168 | |||
169 | if (flag & 0x050) | ||
170 | return 1; | ||
171 | else | ||
172 | return 0; | ||
173 | |||
174 | } | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static unsigned char | ||
179 | XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, | ||
180 | struct vb_device_info *pVBInfo) | ||
181 | { | ||
182 | unsigned short tempbx, tempcx, temp, i, tempch; | ||
183 | |||
184 | tempbx = *pVBInfo->pYCSenseData2; | ||
185 | |||
186 | tempcx = 0x0604; | ||
187 | |||
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); | ||
193 | |||
194 | for (i = 0; i < 10; i++) | ||
195 | XGI_LongWait(pVBInfo); | ||
196 | |||
197 | tempch = (tempcx & 0xFF00) >> 8; | ||
198 | temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03); | ||
199 | temp = temp ^ (0x0E); | ||
200 | temp &= tempch; | ||
201 | |||
202 | if (temp != tempch) | ||
203 | return 0; | ||
204 | |||
205 | tempbx = *pVBInfo->pVideoSenseData2; | ||
206 | |||
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); | ||
213 | |||
214 | for (i = 0; i < 10; i++) | ||
215 | XGI_LongWait(pVBInfo); | ||
216 | |||
217 | tempch = (tempcx & 0xFF00) >> 8; | ||
218 | temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03); | ||
219 | temp = temp ^ (0x0E); | ||
220 | temp &= tempch; | ||
221 | |||
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); | ||
232 | |||
233 | for (i = 0; i < 10; i++) | ||
234 | XGI_LongWait(pVBInfo); | ||
235 | |||
236 | tempch = (tempcx & 0xFF00) >> 8; | ||
237 | temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03); | ||
238 | temp = temp ^ (0x0E); | ||
239 | temp &= tempch; | ||
240 | |||
241 | if (temp != tempch) | ||
242 | return 1; | ||
243 | else | ||
244 | return 0; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, | ||
249 | struct vb_device_info *pVBInfo) | ||
250 | { | ||
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; | ||
256 | |||
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; | ||
274 | } | ||
275 | } else { | ||
276 | XGINew_GetPanelID(pVBInfo); | ||
277 | temp = LCDSense; | ||
278 | } | ||
279 | |||
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 */ | ||
299 | |||
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); | ||
334 | } | ||
335 | xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1c); | ||
336 | tempax = 0; | ||
337 | tempbx = *pVBInfo->pRGBSenseData; | ||
338 | |||
339 | if (!(XGINew_Is301B(pVBInfo))) | ||
340 | tempbx = *pVBInfo->pRGBSenseData2; | ||
341 | |||
342 | tempcx = 0x0E08; | ||
343 | if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { | ||
344 | if (XGINew_Sense(tempbx, | ||
345 | tempcx, | ||
346 | pVBInfo)) | ||
347 | tempax |= Monitor2Sense; | ||
348 | } | ||
349 | |||
350 | if (pVBInfo->VBType & VB_XGI301C) | ||
351 | xgifb_reg_or(pVBInfo->Part4Port, | ||
352 | 0x0d, | ||
353 | 0x04); | ||
354 | |||
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); | ||
362 | } | ||
363 | |||
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; | ||
377 | } | ||
378 | |||
379 | if (OutputSelect & BoardTVType) { | ||
380 | tempbx = *pVBInfo->pVideoSenseData; | ||
381 | |||
382 | if (!(XGINew_Is301B(pVBInfo))) | ||
383 | tempbx = *pVBInfo->pVideoSenseData2; | ||
384 | |||
385 | tempcx = 0x0804; | ||
386 | if (XGINew_Sense(tempbx, | ||
387 | tempcx, | ||
388 | pVBInfo)) { | ||
389 | if (XGINew_Sense(tempbx, | ||
390 | tempcx, | ||
391 | pVBInfo)) | ||
392 | tempax |= AVIDEOSense; | ||
393 | } | ||
394 | } else { | ||
395 | if (!(tempax & SVIDEOSense)) { | ||
396 | tempbx = *pVBInfo->pVideoSenseData; | ||
397 | |||
398 | if (!(XGINew_Is301B(pVBInfo))) | ||
399 | tempbx = *pVBInfo->pVideoSenseData2; | ||
400 | |||
401 | tempcx = 0x0804; | ||
402 | if (XGINew_Sense(tempbx, | ||
403 | tempcx, | ||
404 | pVBInfo)) { | ||
405 | if (XGINew_Sense(tempbx, tempcx, pVBInfo)) | ||
406 | tempax |= AVIDEOSense; | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | } /* end */ | ||
412 | if (!(tempax & Monitor2Sense)) { | ||
413 | if (XGINew_SenseLCD(HwDeviceExtension, pVBInfo)) | ||
414 | tempax |= LCDSense; | ||
415 | } | ||
416 | tempbx = 0; | ||
417 | tempcx = 0; | ||
418 | XGINew_Sense(tempbx, tempcx, pVBInfo); | ||
419 | |||
420 | xgifb_reg_and_or(pVBInfo->P3d4, 0x32, ~0xDF, tempax); | ||
421 | xgifb_reg_set(pVBInfo->Part2Port, 0x00, P2reg0); | ||
422 | |||
423 | if (!(P2reg0 & 0x20)) { | ||
424 | pVBInfo->VBInfo = DisableCRT2Display; | ||
425 | /* XGI_SetCRT2Group301(SenseModeNo, | ||
426 | * HwDeviceExtension, | ||
427 | * pVBInfo); */ | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | XGI_DisableBridge(HwDeviceExtension, pVBInfo); /* shampoo 0226 */ | ||
432 | |||
433 | } | ||
434 | |||
435 | unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, | ||
436 | struct vb_device_info *pVBInfo) | ||
437 | { | ||
438 | /* unsigned short SoftSetting ; */ | ||
439 | unsigned short temp; | ||
440 | |||
441 | temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); | ||
442 | |||
443 | return temp; | ||
444 | } | ||
diff --git a/drivers/staging/xgifb/vb_ext.h b/drivers/staging/xgifb/vb_ext.h new file mode 100644 index 00000000000..814a446b70c --- /dev/null +++ b/drivers/staging/xgifb/vb_ext.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #ifndef _VBEXT_ | ||
2 | #define _VBEXT_ | ||
3 | |||
4 | struct DWORDREGS { | ||
5 | unsigned long Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp; | ||
6 | }; | ||
7 | |||
8 | struct WORDREGS { | ||
9 | unsigned short ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si, | ||
10 | hi_si, di, hi_di, bp, hi_bp; | ||
11 | }; | ||
12 | |||
13 | struct BYTEREGS { | ||
14 | unsigned char al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch, | ||
15 | hi_cl, hi_ch, dl, dh, hi_dl, hi_dh; | ||
16 | }; | ||
17 | |||
18 | typedef union _X86_REGS { | ||
19 | struct DWORDREGS e; | ||
20 | struct WORDREGS x; | ||
21 | struct BYTEREGS h; | ||
22 | } X86_REGS, *PX86_REGS; | ||
23 | |||
24 | extern void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, | ||
25 | struct vb_device_info *pVBInfo); | ||
26 | extern unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *, | ||
27 | struct vb_device_info *pVBInfo); | ||
28 | |||
29 | #endif | ||