PageRenderTime 2655ms CodeModel.GetById 42ms RepoModel.GetById 1ms app.codeStats 3ms

/drivers/video/sis/init301.c

https://bitbucket.org/abioy/linux
C | 11260 lines | 9172 code | 1583 blank | 505 comment | 3524 complexity | f965b504f6b9a385cf8db7cb0d0906b8 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /* $XFree86$ */
  2. /* $XdotOrg$ */
  3. /*
  4. * Mode initializing code (CRT2 section)
  5. * for SiS 300/305/540/630/730,
  6. * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
  7. * XGI V3XT/V5/V8, Z7
  8. * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
  9. *
  10. * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  11. *
  12. * If distributed as part of the Linux kernel, the following license terms
  13. * apply:
  14. *
  15. * * This program is free software; you can redistribute it and/or modify
  16. * * it under the terms of the GNU General Public License as published by
  17. * * the Free Software Foundation; either version 2 of the named License,
  18. * * or any later version.
  19. * *
  20. * * This program is distributed in the hope that it will be useful,
  21. * * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * * GNU General Public License for more details.
  24. * *
  25. * * You should have received a copy of the GNU General Public License
  26. * * along with this program; if not, write to the Free Software
  27. * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  28. *
  29. * Otherwise, the following license terms apply:
  30. *
  31. * * Redistribution and use in source and binary forms, with or without
  32. * * modification, are permitted provided that the following conditions
  33. * * are met:
  34. * * 1) Redistributions of source code must retain the above copyright
  35. * * notice, this list of conditions and the following disclaimer.
  36. * * 2) Redistributions in binary form must reproduce the above copyright
  37. * * notice, this list of conditions and the following disclaimer in the
  38. * * documentation and/or other materials provided with the distribution.
  39. * * 3) The name of the author may not be used to endorse or promote products
  40. * * derived from this software without specific prior written permission.
  41. * *
  42. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  43. * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  44. * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  45. * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  46. * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  47. * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  48. * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  49. * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50. * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  51. * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52. *
  53. * Author: Thomas Winischhofer <thomas@winischhofer.net>
  54. *
  55. * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
  56. * Used by permission.
  57. *
  58. */
  59. #ifdef HAVE_CONFIG_H
  60. #include "config.h"
  61. #endif
  62. #if 1
  63. #define SET_EMI /* 302LV/ELV: Set EMI values */
  64. #endif
  65. #if 1
  66. #define SET_PWD /* 301/302LV: Set PWD */
  67. #endif
  68. #define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */
  69. #define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */
  70. #define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */
  71. #include "init301.h"
  72. #ifdef SIS300
  73. #include "oem300.h"
  74. #endif
  75. #ifdef SIS315H
  76. #include "oem310.h"
  77. #endif
  78. #define SiS_I2CDELAY 1000
  79. #define SiS_I2CDELAYSHORT 150
  80. static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
  81. #ifdef SIS_LINUX_KERNEL
  82. static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
  83. #endif
  84. /*********************************************/
  85. /* HELPER: Lock/Unlock CRT2 */
  86. /*********************************************/
  87. void
  88. SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
  89. {
  90. if(SiS_Pr->ChipType == XGI_20)
  91. return;
  92. else if(SiS_Pr->ChipType >= SIS_315H)
  93. SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
  94. else
  95. SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
  96. }
  97. #ifdef SIS_LINUX_KERNEL
  98. static
  99. #endif
  100. void
  101. SiS_LockCRT2(struct SiS_Private *SiS_Pr)
  102. {
  103. if(SiS_Pr->ChipType == XGI_20)
  104. return;
  105. else if(SiS_Pr->ChipType >= SIS_315H)
  106. SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
  107. else
  108. SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
  109. }
  110. /*********************************************/
  111. /* HELPER: Write SR11 */
  112. /*********************************************/
  113. static void
  114. SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
  115. {
  116. if(SiS_Pr->ChipType >= SIS_661) {
  117. DataAND &= 0x0f;
  118. DataOR &= 0x0f;
  119. }
  120. SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
  121. }
  122. /*********************************************/
  123. /* HELPER: Get Pointer to LCD structure */
  124. /*********************************************/
  125. #ifdef SIS315H
  126. static unsigned char *
  127. GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
  128. {
  129. unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
  130. unsigned char *myptr = NULL;
  131. unsigned short romindex = 0, reg = 0, idx = 0;
  132. /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
  133. * due to the variaty of panels the BIOS doesn't know about.
  134. * Exception: If the BIOS has better knowledge (such as in case
  135. * of machines with a 301C and a panel that does not support DDC)
  136. * use the BIOS data as well.
  137. */
  138. if((SiS_Pr->SiS_ROMNew) &&
  139. ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
  140. if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
  141. else reg = 0x7d;
  142. idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
  143. if(idx < (8*26)) {
  144. myptr = (unsigned char *)&SiS_LCDStruct661[idx];
  145. }
  146. romindex = SISGETROMW(0x100);
  147. if(romindex) {
  148. romindex += idx;
  149. myptr = &ROMAddr[romindex];
  150. }
  151. }
  152. return myptr;
  153. }
  154. static unsigned short
  155. GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
  156. {
  157. unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
  158. unsigned short romptr = 0;
  159. /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
  160. * due to the variaty of panels the BIOS doesn't know about.
  161. * Exception: If the BIOS has better knowledge (such as in case
  162. * of machines with a 301C and a panel that does not support DDC)
  163. * use the BIOS data as well.
  164. */
  165. if((SiS_Pr->SiS_ROMNew) &&
  166. ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
  167. romptr = SISGETROMW(0x102);
  168. romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
  169. }
  170. return romptr;
  171. }
  172. #endif
  173. /*********************************************/
  174. /* Adjust Rate for CRT2 */
  175. /*********************************************/
  176. static bool
  177. SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
  178. unsigned short RRTI, unsigned short *i)
  179. {
  180. unsigned short checkmask=0, modeid, infoflag;
  181. modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
  182. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  183. if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
  184. checkmask |= SupportRAMDAC2;
  185. if(SiS_Pr->ChipType >= SIS_315H) {
  186. checkmask |= SupportRAMDAC2_135;
  187. if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
  188. checkmask |= SupportRAMDAC2_162;
  189. if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
  190. checkmask |= SupportRAMDAC2_202;
  191. }
  192. }
  193. }
  194. } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  195. checkmask |= SupportLCD;
  196. if(SiS_Pr->ChipType >= SIS_315H) {
  197. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  198. if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
  199. if(modeid == 0x2e) checkmask |= Support64048060Hz;
  200. }
  201. }
  202. }
  203. } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
  204. checkmask |= SupportHiVision;
  205. } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
  206. checkmask |= SupportTV;
  207. if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
  208. checkmask |= SupportTV1024;
  209. if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
  210. if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
  211. checkmask |= SupportYPbPr750p;
  212. }
  213. }
  214. }
  215. }
  216. } else { /* LVDS */
  217. if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  218. if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  219. checkmask |= SupportCHTV;
  220. }
  221. }
  222. if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  223. checkmask |= SupportLCD;
  224. }
  225. }
  226. /* Look backwards in table for matching CRT2 mode */
  227. for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
  228. infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
  229. if(infoflag & checkmask) return true;
  230. if((*i) == 0) break;
  231. }
  232. /* Look through the whole mode-section of the table from the beginning
  233. * for a matching CRT2 mode if no mode was found yet.
  234. */
  235. for((*i) = 0; ; (*i)++) {
  236. if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
  237. infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
  238. if(infoflag & checkmask) return true;
  239. }
  240. return false;
  241. }
  242. /*********************************************/
  243. /* Get rate index */
  244. /*********************************************/
  245. unsigned short
  246. SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  247. {
  248. unsigned short RRTI,i,backup_i;
  249. unsigned short modeflag,index,temp,backupindex;
  250. static const unsigned short LCDRefreshIndex[] = {
  251. 0x00, 0x00, 0x01, 0x01,
  252. 0x01, 0x01, 0x01, 0x01,
  253. 0x01, 0x01, 0x01, 0x01,
  254. 0x01, 0x01, 0x01, 0x01,
  255. 0x00, 0x00, 0x00, 0x00
  256. };
  257. /* Do NOT check for UseCustomMode here, will skrew up FIFO */
  258. if(ModeNo == 0xfe) return 0;
  259. if(ModeNo <= 0x13) {
  260. modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  261. } else {
  262. modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  263. }
  264. if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  265. if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  266. if(modeflag & HalfDCLK) return 0;
  267. }
  268. }
  269. if(ModeNo < 0x14) return 0xFFFF;
  270. index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
  271. backupindex = index;
  272. if(index > 0) index--;
  273. if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
  274. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  275. if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  276. if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0;
  277. else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
  278. }
  279. if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  280. if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
  281. temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
  282. if(index > temp) index = temp;
  283. }
  284. }
  285. } else {
  286. if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
  287. if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  288. if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
  289. }
  290. }
  291. }
  292. RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
  293. ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
  294. if(SiS_Pr->ChipType >= SIS_315H) {
  295. if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
  296. if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
  297. (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
  298. if(backupindex <= 1) RRTI++;
  299. }
  300. }
  301. }
  302. i = 0;
  303. do {
  304. if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
  305. temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
  306. temp &= ModeTypeMask;
  307. if(temp < SiS_Pr->SiS_ModeType) break;
  308. i++;
  309. index--;
  310. } while(index != 0xFFFF);
  311. if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
  312. if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  313. temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
  314. if(temp & InterlaceMode) i++;
  315. }
  316. }
  317. i--;
  318. if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
  319. backup_i = i;
  320. if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
  321. i = backup_i;
  322. }
  323. }
  324. return (RRTI + i);
  325. }
  326. /*********************************************/
  327. /* STORE CRT2 INFO in CR34 */
  328. /*********************************************/
  329. static void
  330. SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
  331. {
  332. unsigned short temp1, temp2;
  333. /* Store CRT1 ModeNo in CR34 */
  334. SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
  335. temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
  336. temp2 = ~(SetInSlaveMode >> 8);
  337. SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
  338. }
  339. /*********************************************/
  340. /* HELPER: GET SOME DATA FROM BIOS ROM */
  341. /*********************************************/
  342. #ifdef SIS300
  343. static bool
  344. SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
  345. {
  346. unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
  347. unsigned short temp,temp1;
  348. if(SiS_Pr->SiS_UseROM) {
  349. if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
  350. temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
  351. temp1 = SISGETROMW(0x23b);
  352. if(temp1 & temp) return true;
  353. }
  354. }
  355. return false;
  356. }
  357. static bool
  358. SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
  359. {
  360. unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
  361. unsigned short temp,temp1;
  362. if(SiS_Pr->SiS_UseROM) {
  363. if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
  364. temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
  365. temp1 = SISGETROMW(0x23d);
  366. if(temp1 & temp) return true;
  367. }
  368. }
  369. return false;
  370. }
  371. #endif
  372. /*********************************************/
  373. /* HELPER: DELAY FUNCTIONS */
  374. /*********************************************/
  375. void
  376. SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
  377. {
  378. while (delaytime-- > 0)
  379. SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
  380. }
  381. #if defined(SIS300) || defined(SIS315H)
  382. static void
  383. SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
  384. {
  385. SiS_DDC2Delay(SiS_Pr, delay * 36);
  386. }
  387. #endif
  388. #ifdef SIS315H
  389. static void
  390. SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
  391. {
  392. while(delay--) {
  393. SiS_GenericDelay(SiS_Pr, 6623);
  394. }
  395. }
  396. #endif
  397. #if defined(SIS300) || defined(SIS315H)
  398. static void
  399. SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
  400. {
  401. while(delay--) {
  402. SiS_GenericDelay(SiS_Pr, 66);
  403. }
  404. }
  405. #endif
  406. static void
  407. SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
  408. {
  409. #if defined(SIS300) || defined(SIS315H)
  410. unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
  411. unsigned short PanelID, DelayIndex, Delay=0;
  412. #endif
  413. if(SiS_Pr->ChipType < SIS_315H) {
  414. #ifdef SIS300
  415. PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
  416. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  417. if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
  418. if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
  419. }
  420. DelayIndex = PanelID >> 4;
  421. if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
  422. Delay = 3;
  423. } else {
  424. if(DelayTime >= 2) DelayTime -= 2;
  425. if(!(DelayTime & 0x01)) {
  426. Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
  427. } else {
  428. Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
  429. }
  430. if(SiS_Pr->SiS_UseROM) {
  431. if(ROMAddr[0x220] & 0x40) {
  432. if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
  433. else Delay = (unsigned short)ROMAddr[0x226];
  434. }
  435. }
  436. }
  437. SiS_ShortDelay(SiS_Pr, Delay);
  438. #endif /* SIS300 */
  439. } else {
  440. #ifdef SIS315H
  441. if((SiS_Pr->ChipType >= SIS_661) ||
  442. (SiS_Pr->ChipType <= SIS_315PRO) ||
  443. (SiS_Pr->ChipType == SIS_330) ||
  444. (SiS_Pr->SiS_ROMNew)) {
  445. if(!(DelayTime & 0x01)) {
  446. SiS_DDC2Delay(SiS_Pr, 0x1000);
  447. } else {
  448. SiS_DDC2Delay(SiS_Pr, 0x4000);
  449. }
  450. } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
  451. (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
  452. (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
  453. if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
  454. PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
  455. if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
  456. if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
  457. }
  458. if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
  459. DelayIndex = PanelID & 0x0f;
  460. } else {
  461. DelayIndex = PanelID >> 4;
  462. }
  463. if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) {
  464. Delay = 3;
  465. } else {
  466. if(DelayTime >= 2) DelayTime -= 2;
  467. if(!(DelayTime & 0x01)) {
  468. Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
  469. } else {
  470. Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
  471. }
  472. if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
  473. if(ROMAddr[0x13c] & 0x40) {
  474. if(!(DelayTime & 0x01)) {
  475. Delay = (unsigned short)ROMAddr[0x17e];
  476. } else {
  477. Delay = (unsigned short)ROMAddr[0x17f];
  478. }
  479. }
  480. }
  481. }
  482. SiS_ShortDelay(SiS_Pr, Delay);
  483. }
  484. } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
  485. DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
  486. if(!(DelayTime & 0x01)) {
  487. Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
  488. } else {
  489. Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
  490. }
  491. Delay <<= 8;
  492. SiS_DDC2Delay(SiS_Pr, Delay);
  493. }
  494. #endif /* SIS315H */
  495. }
  496. }
  497. #ifdef SIS315H
  498. static void
  499. SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
  500. {
  501. int i;
  502. for(i = 0; i < DelayLoop; i++) {
  503. SiS_PanelDelay(SiS_Pr, DelayTime);
  504. }
  505. }
  506. #endif
  507. /*********************************************/
  508. /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */
  509. /*********************************************/
  510. void
  511. SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
  512. {
  513. unsigned short watchdog;
  514. if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
  515. if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
  516. watchdog = 65535;
  517. while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
  518. watchdog = 65535;
  519. while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
  520. }
  521. #if defined(SIS300) || defined(SIS315H)
  522. static void
  523. SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
  524. {
  525. unsigned short watchdog;
  526. watchdog = 65535;
  527. while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
  528. watchdog = 65535;
  529. while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
  530. }
  531. #endif
  532. static void
  533. SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
  534. {
  535. if(SiS_Pr->ChipType < SIS_315H) {
  536. #ifdef SIS300
  537. if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
  538. if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
  539. }
  540. if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
  541. SiS_WaitRetrace1(SiS_Pr);
  542. } else {
  543. SiS_WaitRetrace2(SiS_Pr, 0x25);
  544. }
  545. #endif
  546. } else {
  547. #ifdef SIS315H
  548. if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
  549. SiS_WaitRetrace1(SiS_Pr);
  550. } else {
  551. SiS_WaitRetrace2(SiS_Pr, 0x30);
  552. }
  553. #endif
  554. }
  555. }
  556. static void
  557. SiS_VBWait(struct SiS_Private *SiS_Pr)
  558. {
  559. unsigned short tempal,temp,i,j;
  560. temp = 0;
  561. for(i = 0; i < 3; i++) {
  562. for(j = 0; j < 100; j++) {
  563. tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
  564. if(temp & 0x01) {
  565. if((tempal & 0x08)) continue;
  566. else break;
  567. } else {
  568. if(!(tempal & 0x08)) continue;
  569. else break;
  570. }
  571. }
  572. temp ^= 0x01;
  573. }
  574. }
  575. static void
  576. SiS_VBLongWait(struct SiS_Private *SiS_Pr)
  577. {
  578. if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  579. SiS_VBWait(SiS_Pr);
  580. } else {
  581. SiS_WaitRetrace1(SiS_Pr);
  582. }
  583. }
  584. /*********************************************/
  585. /* HELPER: MISC */
  586. /*********************************************/
  587. #ifdef SIS300
  588. static bool
  589. SiS_Is301B(struct SiS_Private *SiS_Pr)
  590. {
  591. if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
  592. return false;
  593. }
  594. #endif
  595. static bool
  596. SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
  597. {
  598. if(SiS_Pr->ChipType == SIS_730) {
  599. if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
  600. }
  601. if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
  602. return false;
  603. }
  604. bool
  605. SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
  606. {
  607. #ifdef SIS315H
  608. if(SiS_Pr->ChipType >= SIS_315H) {
  609. if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
  610. if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
  611. }
  612. }
  613. #endif
  614. return false;
  615. }
  616. bool
  617. SiS_IsVAMode(struct SiS_Private *SiS_Pr)
  618. {
  619. #ifdef SIS315H
  620. unsigned short flag;
  621. if(SiS_Pr->ChipType >= SIS_315H) {
  622. flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
  623. if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
  624. }
  625. #endif
  626. return false;
  627. }
  628. #ifdef SIS315H
  629. static bool
  630. SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
  631. {
  632. if(SiS_IsVAMode(SiS_Pr)) return true;
  633. if(SiS_CRT2IsLCD(SiS_Pr)) return true;
  634. return false;
  635. }
  636. #endif
  637. static bool
  638. SiS_IsDualLink(struct SiS_Private *SiS_Pr)
  639. {
  640. #ifdef SIS315H
  641. if(SiS_Pr->ChipType >= SIS_315H) {
  642. if((SiS_CRT2IsLCD(SiS_Pr)) ||
  643. (SiS_IsVAMode(SiS_Pr))) {
  644. if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
  645. }
  646. }
  647. #endif
  648. return false;
  649. }
  650. #ifdef SIS315H
  651. static bool
  652. SiS_TVEnabled(struct SiS_Private *SiS_Pr)
  653. {
  654. if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
  655. if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
  656. if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
  657. }
  658. return false;
  659. }
  660. #endif
  661. #ifdef SIS315H
  662. static bool
  663. SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
  664. {
  665. if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
  666. return false;
  667. }
  668. #endif
  669. #ifdef SIS315H
  670. static bool
  671. SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
  672. {
  673. if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
  674. if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
  675. }
  676. return false;
  677. }
  678. #endif
  679. #ifdef SIS315H
  680. static bool
  681. SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
  682. {
  683. unsigned short flag;
  684. if(SiS_Pr->ChipType == SIS_650) {
  685. flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
  686. /* Check for revision != A0 only */
  687. if((flag == 0xe0) || (flag == 0xc0) ||
  688. (flag == 0xb0) || (flag == 0x90)) return false;
  689. } else if(SiS_Pr->ChipType >= SIS_661) return false;
  690. return true;
  691. }
  692. #endif
  693. #ifdef SIS315H
  694. static bool
  695. SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
  696. {
  697. if(SiS_Pr->ChipType >= SIS_315H) {
  698. /* YPrPb = 0x08 */
  699. if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
  700. }
  701. return false;
  702. }
  703. #endif
  704. #ifdef SIS315H
  705. static bool
  706. SiS_IsChScart(struct SiS_Private *SiS_Pr)
  707. {
  708. if(SiS_Pr->ChipType >= SIS_315H) {
  709. /* Scart = 0x04 */
  710. if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
  711. }
  712. return false;
  713. }
  714. #endif
  715. #ifdef SIS315H
  716. static bool
  717. SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
  718. {
  719. unsigned short flag;
  720. if(SiS_Pr->ChipType >= SIS_315H) {
  721. flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
  722. if(flag & SetCRT2ToTV) return true;
  723. flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
  724. if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
  725. if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
  726. } else {
  727. flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
  728. if(flag & SetCRT2ToTV) return true;
  729. }
  730. return false;
  731. }
  732. #endif
  733. #ifdef SIS315H
  734. static bool
  735. SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
  736. {
  737. unsigned short flag;
  738. if(SiS_Pr->ChipType >= SIS_315H) {
  739. flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
  740. if(flag & SetCRT2ToLCD) return true;
  741. flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
  742. if(flag & SetToLCDA) return true;
  743. } else {
  744. flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
  745. if(flag & SetCRT2ToLCD) return true;
  746. }
  747. return false;
  748. }
  749. #endif
  750. static bool
  751. SiS_HaveBridge(struct SiS_Private *SiS_Pr)
  752. {
  753. unsigned short flag;
  754. if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  755. return true;
  756. } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
  757. flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
  758. if((flag == 1) || (flag == 2)) return true;
  759. }
  760. return false;
  761. }
  762. static bool
  763. SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
  764. {
  765. unsigned short flag;
  766. if(SiS_HaveBridge(SiS_Pr)) {
  767. flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
  768. if(SiS_Pr->ChipType < SIS_315H) {
  769. flag &= 0xa0;
  770. if((flag == 0x80) || (flag == 0x20)) return true;
  771. } else {
  772. flag &= 0x50;
  773. if((flag == 0x40) || (flag == 0x10)) return true;
  774. }
  775. }
  776. return false;
  777. }
  778. static bool
  779. SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
  780. {
  781. unsigned short flag1;
  782. flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
  783. if(flag1 & (SetInSlaveMode >> 8)) return true;
  784. return false;
  785. }
  786. /*********************************************/
  787. /* GET VIDEO BRIDGE CONFIG INFO */
  788. /*********************************************/
  789. /* Setup general purpose IO for Chrontel communication */
  790. #ifdef SIS300
  791. void
  792. SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
  793. {
  794. unsigned int acpibase;
  795. unsigned short temp;
  796. if(!(SiS_Pr->SiS_ChSW)) return;
  797. #ifdef SIS_LINUX_KERNEL
  798. acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
  799. #else
  800. acpibase = pciReadLong(0x00000800, 0x74);
  801. #endif
  802. acpibase &= 0xFFFF;
  803. if(!acpibase) return;
  804. temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
  805. temp &= 0xFEFF;
  806. SiS_SetRegShort((acpibase + 0x3c), temp);
  807. temp = SiS_GetRegShort((acpibase + 0x3c));
  808. temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */
  809. temp &= 0xFEFF;
  810. if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
  811. SiS_SetRegShort((acpibase + 0x3a), temp);
  812. temp = SiS_GetRegShort((acpibase + 0x3a));
  813. }
  814. #endif
  815. void
  816. SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
  817. unsigned short ModeIdIndex, int checkcrt2mode)
  818. {
  819. unsigned short tempax, tempbx, temp;
  820. unsigned short modeflag, resinfo = 0;
  821. SiS_Pr->SiS_SetFlag = 0;
  822. modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
  823. SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
  824. if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
  825. resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  826. }
  827. tempbx = 0;
  828. if(SiS_HaveBridge(SiS_Pr)) {
  829. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
  830. tempbx |= temp;
  831. tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
  832. tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
  833. tempbx |= tempax;
  834. #ifdef SIS315H
  835. if(SiS_Pr->ChipType >= SIS_315H) {
  836. if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
  837. if(ModeNo == 0x03) {
  838. /* Mode 0x03 is never in driver mode */
  839. SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
  840. }
  841. if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
  842. /* Reset LCDA setting if not driver mode */
  843. SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
  844. }
  845. if(IS_SIS650) {
  846. if(SiS_Pr->SiS_UseLCDA) {
  847. if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
  848. if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
  849. SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
  850. }
  851. }
  852. }
  853. }
  854. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
  855. if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
  856. tempbx |= SetCRT2ToLCDA;
  857. }
  858. }
  859. if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
  860. tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
  861. if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
  862. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
  863. if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
  864. else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
  865. tempbx |= SetCRT2ToYPbPr525750;
  866. }
  867. }
  868. }
  869. if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  870. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
  871. if(temp & SetToLCDA) {
  872. tempbx |= SetCRT2ToLCDA;
  873. }
  874. if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  875. if(temp & EnableCHYPbPr) {
  876. tempbx |= SetCRT2ToCHYPbPr;
  877. }
  878. }
  879. }
  880. }
  881. #endif /* SIS315H */
  882. if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
  883. tempbx &= ~(SetCRT2ToRAMDAC);
  884. }
  885. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  886. temp = SetCRT2ToSVIDEO |
  887. SetCRT2ToAVIDEO |
  888. SetCRT2ToSCART |
  889. SetCRT2ToLCDA |
  890. SetCRT2ToLCD |
  891. SetCRT2ToRAMDAC |
  892. SetCRT2ToHiVision |
  893. SetCRT2ToYPbPr525750;
  894. } else {
  895. if(SiS_Pr->ChipType >= SIS_315H) {
  896. if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  897. temp = SetCRT2ToAVIDEO |
  898. SetCRT2ToSVIDEO |
  899. SetCRT2ToSCART |
  900. SetCRT2ToLCDA |
  901. SetCRT2ToLCD |
  902. SetCRT2ToCHYPbPr;
  903. } else {
  904. temp = SetCRT2ToLCDA |
  905. SetCRT2ToLCD;
  906. }
  907. } else {
  908. if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  909. temp = SetCRT2ToTV | SetCRT2ToLCD;
  910. } else {
  911. temp = SetCRT2ToLCD;
  912. }
  913. }
  914. }
  915. if(!(tempbx & temp)) {
  916. tempax = DisableCRT2Display;
  917. tempbx = 0;
  918. }
  919. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  920. unsigned short clearmask = ( DriverMode |
  921. DisableCRT2Display |
  922. LoadDACFlag |
  923. SetNotSimuMode |
  924. SetInSlaveMode |
  925. SetPALTV |
  926. SwitchCRT2 |
  927. SetSimuScanMode );
  928. if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
  929. if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
  930. if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
  931. if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
  932. if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
  933. if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
  934. } else {
  935. if(SiS_Pr->ChipType >= SIS_315H) {
  936. if(tempbx & SetCRT2ToLCDA) {
  937. tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
  938. }
  939. }
  940. if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  941. if(tempbx & SetCRT2ToTV) {
  942. tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
  943. }
  944. }
  945. if(tempbx & SetCRT2ToLCD) {
  946. tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
  947. }
  948. if(SiS_Pr->ChipType >= SIS_315H) {
  949. if(tempbx & SetCRT2ToLCDA) {
  950. tempbx |= SetCRT2ToLCD;
  951. }
  952. }
  953. }
  954. if(tempax & DisableCRT2Display) {
  955. if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
  956. tempbx = SetSimuScanMode | DisableCRT2Display;
  957. }
  958. }
  959. if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
  960. /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
  961. if(SiS_Pr->SiS_ModeType <= ModeVGA) {
  962. if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
  963. ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
  964. modeflag &= (~CRT2Mode);
  965. }
  966. }
  967. if(!(tempbx & SetSimuScanMode)) {
  968. if(tempbx & SwitchCRT2) {
  969. if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
  970. if(resinfo != SIS_RI_1600x1200) {
  971. tempbx |= SetSimuScanMode;
  972. }
  973. }
  974. } else {
  975. if(SiS_BridgeIsEnabled(SiS_Pr)) {
  976. if(!(tempbx & DriverMode)) {
  977. if(SiS_BridgeInSlavemode(SiS_Pr)) {
  978. tempbx |= SetSimuScanMode;
  979. }
  980. }
  981. }
  982. }
  983. }
  984. if(!(tempbx & DisableCRT2Display)) {
  985. if(tempbx & DriverMode) {
  986. if(tempbx & SetSimuScanMode) {
  987. if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
  988. if(resinfo != SIS_RI_1600x1200) {
  989. tempbx |= SetInSlaveMode;
  990. }
  991. }
  992. }
  993. } else {
  994. tempbx |= SetInSlaveMode;
  995. }
  996. }
  997. }
  998. SiS_Pr->SiS_VBInfo = tempbx;
  999. #ifdef SIS300
  1000. if(SiS_Pr->ChipType == SIS_630) {
  1001. SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
  1002. }
  1003. #endif
  1004. #ifdef SIS_LINUX_KERNEL
  1005. #if 0
  1006. printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
  1007. SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
  1008. #endif
  1009. #endif
  1010. #ifdef SIS_XORG_XF86
  1011. #ifdef TWDEBUG
  1012. xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
  1013. SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
  1014. #endif
  1015. #endif
  1016. }
  1017. /*********************************************/
  1018. /* DETERMINE YPbPr MODE */
  1019. /*********************************************/
  1020. void
  1021. SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
  1022. {
  1023. unsigned char temp;
  1024. /* Note: This variable is only used on 30xLV systems.
  1025. * CR38 has a different meaning on LVDS/CH7019 systems.
  1026. * On 661 and later, these bits moved to CR35.
  1027. *
  1028. * On 301, 301B, only HiVision 1080i is supported.
  1029. * On 30xLV, 301C, only YPbPr 1080i is supported.
  1030. */
  1031. SiS_Pr->SiS_YPbPr = 0;
  1032. if(SiS_Pr->ChipType >= SIS_661) return;
  1033. if(SiS_Pr->SiS_VBType) {
  1034. if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
  1035. SiS_Pr->SiS_YPbPr = YPbPrHiVision;
  1036. }
  1037. }
  1038. if(SiS_Pr->ChipType >= SIS_315H) {
  1039. if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
  1040. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
  1041. if(temp & 0x08) {
  1042. switch((temp >> 4)) {
  1043. case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break;
  1044. case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break;
  1045. case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break;
  1046. case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
  1047. }
  1048. }
  1049. }
  1050. }
  1051. }
  1052. /*********************************************/
  1053. /* DETERMINE TVMode flag */
  1054. /*********************************************/
  1055. void
  1056. SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  1057. {
  1058. unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
  1059. unsigned short temp, temp1, resinfo = 0, romindex = 0;
  1060. unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect;
  1061. SiS_Pr->SiS_TVMode = 0;
  1062. if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
  1063. if(SiS_Pr->UseCustomMode) return;
  1064. if(ModeNo > 0x13) {
  1065. resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  1066. }
  1067. if(SiS_Pr->ChipType < SIS_661) {
  1068. if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
  1069. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  1070. temp = 0;
  1071. if((SiS_Pr->ChipType == SIS_630) ||
  1072. (SiS_Pr->ChipType == SIS_730)) {
  1073. temp = 0x35;
  1074. romindex = 0xfe;
  1075. } else if(SiS_Pr->ChipType >= SIS_315H) {
  1076. temp = 0x38;
  1077. if(SiS_Pr->ChipType < XGI_20) {
  1078. romindex = 0xf3;
  1079. if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
  1080. }
  1081. }
  1082. if(temp) {
  1083. if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
  1084. OutputSelect = ROMAddr[romindex];
  1085. if(!(OutputSelect & EnablePALMN)) {
  1086. SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
  1087. }
  1088. }
  1089. temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
  1090. if(SiS_Pr->SiS_TVMode & TVSetPAL) {
  1091. if(temp1 & EnablePALM) { /* 0x40 */
  1092. SiS_Pr->SiS_TVMode |= TVSetPALM;
  1093. SiS_Pr->SiS_TVMode &= ~TVSetPAL;
  1094. } else if(temp1 & EnablePALN) { /* 0x80 */
  1095. SiS_Pr->SiS_TVMode |= TVSetPALN;
  1096. }
  1097. } else {
  1098. if(temp1 & EnableNTSCJ) { /* 0x40 */
  1099. SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
  1100. }
  1101. }
  1102. }
  1103. /* Translate HiVision/YPbPr to our new flags */
  1104. if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
  1105. if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
  1106. else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
  1107. else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
  1108. else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
  1109. if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
  1110. SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
  1111. SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
  1112. } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
  1113. SiS_Pr->SiS_TVMode |= TVSetPAL;
  1114. }
  1115. }
  1116. } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
  1117. if(SiS_Pr->SiS_CHOverScan) {
  1118. if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
  1119. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
  1120. if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
  1121. SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
  1122. }
  1123. } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
  1124. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
  1125. if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
  1126. SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
  1127. }
  1128. }
  1129. if(SiS_Pr->SiS_CHSOverScan) {
  1130. SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
  1131. }
  1132. }
  1133. if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
  1134. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
  1135. if(SiS_Pr->SiS_TVMode & TVSetPAL) {
  1136. if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM;
  1137. else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
  1138. } else {
  1139. if(temp & EnableNTSCJ) {
  1140. SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
  1141. }
  1142. }
  1143. }
  1144. }
  1145. } else { /* 661 and later */
  1146. temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
  1147. if(temp1 & 0x01) {
  1148. SiS_Pr->SiS_TVMode |= TVSetPAL;
  1149. if(temp1 & 0x08) {
  1150. SiS_Pr->SiS_TVMode |= TVSetPALN;
  1151. } else if(temp1 & 0x04) {
  1152. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  1153. SiS_Pr->SiS_TVMode &= ~TVSetPAL;
  1154. }
  1155. SiS_Pr->SiS_TVMode |= TVSetPALM;
  1156. }
  1157. } else {
  1158. if(temp1 & 0x02) {
  1159. SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
  1160. }
  1161. }
  1162. if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
  1163. if(SiS_Pr->SiS_CHOverScan) {
  1164. if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
  1165. SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
  1166. }
  1167. }
  1168. }
  1169. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  1170. if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
  1171. temp1 &= 0xe0;
  1172. if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
  1173. else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
  1174. else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
  1175. } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
  1176. SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
  1177. }
  1178. if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
  1179. if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
  1180. SiS_Pr->SiS_TVMode |= TVAspect169;
  1181. } else {
  1182. temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
  1183. if(temp1 & 0x02) {
  1184. if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
  1185. SiS_Pr->SiS_TVMode |= TVAspect169;
  1186. } else {
  1187. SiS_Pr->SiS_TVMode |= TVAspect43LB;
  1188. }
  1189. } else {
  1190. SiS_Pr->SiS_TVMode |= TVAspect43;
  1191. }
  1192. }
  1193. }
  1194. }
  1195. }
  1196. if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
  1197. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  1198. if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
  1199. SiS_Pr->SiS_TVMode |= TVSetPAL;
  1200. SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
  1201. } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
  1202. if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
  1203. SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
  1204. }
  1205. }
  1206. if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
  1207. if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
  1208. SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
  1209. }
  1210. }
  1211. if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
  1212. if(resinfo == SIS_RI_1024x768) {
  1213. if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
  1214. SiS_Pr->SiS_TVMode |= TVSet525p1024;
  1215. } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
  1216. SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
  1217. }
  1218. }
  1219. }
  1220. SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
  1221. if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
  1222. (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
  1223. SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
  1224. } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
  1225. SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
  1226. } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
  1227. if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
  1228. SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
  1229. }
  1230. }
  1231. }
  1232. SiS_Pr->SiS_VBInfo &= ~SetPALTV;
  1233. #ifdef SIS_XORG_XF86
  1234. #ifdef TWDEBUG
  1235. xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
  1236. #endif
  1237. #endif
  1238. }
  1239. /*********************************************/
  1240. /* GET LCD INFO */
  1241. /*********************************************/
  1242. static unsigned short
  1243. SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
  1244. {
  1245. unsigned short temp = SiS_Pr->SiS_LCDResInfo;
  1246. /* Translate my LCDResInfo to BIOS value */
  1247. switch(temp) {
  1248. case Panel_1280x768_2: temp = Panel_1280x768; break;
  1249. case Panel_1280x800_2: temp = Panel_1280x800; break;
  1250. case Panel_1280x854: temp = Panel661_1280x854; break;
  1251. }
  1252. return temp;
  1253. }
  1254. static void
  1255. SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
  1256. {
  1257. #ifdef SIS315H
  1258. unsigned char *ROMAddr;
  1259. unsigned short temp;
  1260. #ifdef SIS_XORG_XF86
  1261. #ifdef TWDEBUG
  1262. xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
  1263. SiS_Pr->PanelHT, SiS_Pr->PanelVT,
  1264. SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
  1265. SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
  1266. SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
  1267. SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
  1268. SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
  1269. #endif
  1270. #endif
  1271. if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
  1272. if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
  1273. SiS_Pr->SiS_NeedRomModeData = true;
  1274. SiS_Pr->PanelHT = temp;
  1275. }
  1276. if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
  1277. SiS_Pr->SiS_NeedRomModeData = true;
  1278. SiS_Pr->PanelVT = temp;
  1279. }
  1280. SiS_Pr->PanelHRS = SISGETROMW(10);
  1281. SiS_Pr->PanelHRE = SISGETROMW(12);
  1282. SiS_Pr->PanelVRS = SISGETROMW(14);
  1283. SiS_Pr->PanelVRE = SISGETROMW(16);
  1284. SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
  1285. SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
  1286. SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
  1287. SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
  1288. SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
  1289. SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
  1290. SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
  1291. #ifdef SIS_XORG_XF86
  1292. #ifdef TWDEBUG
  1293. xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
  1294. SiS_Pr->PanelHT, SiS_Pr->PanelVT,
  1295. SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
  1296. SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
  1297. SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
  1298. SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
  1299. SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
  1300. #endif
  1301. #endif
  1302. }
  1303. #endif
  1304. }
  1305. static void
  1306. SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
  1307. const unsigned char *nonscalingmodes)
  1308. {
  1309. int i = 0;
  1310. while(nonscalingmodes[i] != 0xff) {
  1311. if(nonscalingmodes[i++] == resinfo) {
  1312. if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
  1313. (SiS_Pr->UsePanelScaler == -1)) {
  1314. SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
  1315. }
  1316. break;
  1317. }
  1318. }
  1319. }
  1320. void
  1321. SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  1322. {
  1323. unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
  1324. bool panelcanscale = false;
  1325. #ifdef SIS300
  1326. unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
  1327. static const unsigned char SiS300SeriesLCDRes[] =
  1328. { 0, 1, 2, 3, 7, 4, 5, 8,
  1329. 0, 0, 10, 0, 0, 0, 0, 15 };
  1330. #endif
  1331. #ifdef SIS315H
  1332. unsigned char *myptr = NULL;
  1333. #endif
  1334. SiS_Pr->SiS_LCDResInfo = 0;
  1335. SiS_Pr->SiS_LCDTypeInfo = 0;
  1336. SiS_Pr->SiS_LCDInfo = 0;
  1337. SiS_Pr->PanelHRS = 999; /* HSync start */
  1338. SiS_Pr->PanelHRE = 999; /* HSync end */
  1339. SiS_Pr->PanelVRS = 999; /* VSync start */
  1340. SiS_Pr->PanelVRE = 999; /* VSync end */
  1341. SiS_Pr->SiS_NeedRomModeData = false;
  1342. /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
  1343. SiS_Pr->Alternate1600x1200 = false;
  1344. if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
  1345. modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
  1346. if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
  1347. resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  1348. modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
  1349. modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
  1350. }
  1351. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
  1352. /* For broken BIOSes: Assume 1024x768 */
  1353. if(temp == 0) temp = 0x02;
  1354. if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
  1355. SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
  1356. } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
  1357. SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
  1358. } else {
  1359. SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
  1360. }
  1361. temp &= 0x0f;
  1362. #ifdef SIS300
  1363. if(SiS_Pr->ChipType < SIS_315H) {
  1364. /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
  1365. if(SiS_Pr->SiS_VBType & VB_SIS301) {
  1366. if(temp < 0x0f) temp &= 0x07;
  1367. }
  1368. /* Translate 300 series LCDRes to 315 series for unified usage */
  1369. temp = SiS300SeriesLCDRes[temp];
  1370. }
  1371. #endif
  1372. /* Translate to our internal types */
  1373. #ifdef SIS315H
  1374. if(SiS_Pr->ChipType == SIS_550) {
  1375. if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
  1376. else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
  1377. else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
  1378. } else if(SiS_Pr->ChipType >= SIS_661) {
  1379. if(temp == Panel661_1280x854) temp = Panel_1280x854;
  1380. }
  1381. #endif
  1382. if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */
  1383. if(temp == Panel310_1280x768) {
  1384. temp = Panel_1280x768_2;
  1385. }
  1386. if(SiS_Pr->SiS_ROMNew) {
  1387. if(temp == Panel661_1280x800) {
  1388. temp = Panel_1280x800_2;
  1389. }
  1390. }
  1391. }
  1392. SiS_Pr->SiS_LCDResInfo = temp;
  1393. #ifdef SIS300
  1394. if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  1395. if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
  1396. SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
  1397. } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
  1398. SiS_Pr->SiS_LCDResInfo = Panel_848x480;
  1399. } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
  1400. SiS_Pr->SiS_LCDResInfo = Panel_856x480;
  1401. }
  1402. }
  1403. #endif
  1404. if(SiS_Pr->SiS_VBType & VB_SISVB) {
  1405. if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
  1406. SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
  1407. } else {
  1408. if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
  1409. SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
  1410. }
  1411. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
  1412. SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
  1413. /* Need temp below! */
  1414. /* These must/can't scale no matter what */
  1415. switch(SiS_Pr->SiS_LCDResInfo) {
  1416. case Panel_320x240_1:
  1417. case Panel_320x240_2:
  1418. case Panel_320x240_3:
  1419. case Panel_1280x960:
  1420. SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
  1421. break;
  1422. case Panel_640x480:
  1423. SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
  1424. }
  1425. panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
  1426. if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
  1427. else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
  1428. /* Dual link, Pass 1:1 BIOS default, etc. */
  1429. #ifdef SIS315H
  1430. if(SiS_Pr->ChipType >= SIS_661) {
  1431. if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
  1432. if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
  1433. }
  1434. if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
  1435. if(SiS_Pr->SiS_ROMNew) {
  1436. if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
  1437. } else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
  1438. if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
  1439. }
  1440. }
  1441. } else if(SiS_Pr->ChipType >= SIS_315H) {
  1442. if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
  1443. if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
  1444. }
  1445. if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
  1446. SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
  1447. temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
  1448. if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
  1449. if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
  1450. if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
  1451. }
  1452. } else if(!(SiS_Pr->SiS_ROMNew)) {
  1453. if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
  1454. if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
  1455. (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
  1456. SiS_Pr->SiS_LCDInfo |= LCDDualLink;
  1457. }
  1458. if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
  1459. (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
  1460. (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
  1461. (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
  1462. SiS_Pr->SiS_LCDInfo |= LCDDualLink;
  1463. }
  1464. }
  1465. }
  1466. }
  1467. #endif
  1468. /* Pass 1:1 */
  1469. if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
  1470. /* Always center screen on LVDS (if scaling is disabled) */
  1471. SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
  1472. } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
  1473. if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
  1474. /* Always center screen on SiS LVDS (if scaling is disabled) */
  1475. SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
  1476. } else {
  1477. /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
  1478. if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11;
  1479. if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
  1480. }
  1481. }
  1482. SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
  1483. SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
  1484. switch(SiS_Pr->SiS_LCDResInfo) {
  1485. case Panel_320x240_1:
  1486. case Panel_320x240_2:
  1487. case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
  1488. SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
  1489. SiS_Pr->PanelVCLKIdx300 = VCLK28;
  1490. SiS_Pr->PanelVCLKIdx315 = VCLK28;
  1491. break;
  1492. case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
  1493. SiS_Pr->PanelVRE = 3;
  1494. SiS_Pr->PanelVCLKIdx300 = VCLK28;
  1495. SiS_Pr->PanelVCLKIdx315 = VCLK28;
  1496. break;
  1497. case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
  1498. SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
  1499. SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
  1500. SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
  1501. SiS_Pr->PanelVCLKIdx300 = VCLK40;
  1502. SiS_Pr->PanelVCLKIdx315 = VCLK40;
  1503. break;
  1504. case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
  1505. SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
  1506. SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
  1507. SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
  1508. SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
  1509. SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
  1510. break;
  1511. case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
  1512. SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
  1513. SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
  1514. SiS_P

Large files files are truncated, but you can click here to view the full file