Merge branches 'acpica', 'aml-custom', 'bugzilla-16548', 'bugzilla-20242', 'd3-cold...
[firefly-linux-kernel-4.4.55.git] / drivers / staging / xgifb / vb_ext.c
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
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
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
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
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
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
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
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
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 }