dvi.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. /*
  2. * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
  3. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License as published by the Free Software Foundation;
  7. * either version 2, or (at your option) any later version.
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
  10. * the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. * A PARTICULAR PURPOSE.See the GNU General Public License
  12. * for more details.
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc.,
  16. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "global.h"
  19. static void tmds_register_write(int index, u8 data);
  20. static int tmds_register_read(int index);
  21. static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
  22. static int dvi_get_panel_size_from_DDCv1(void);
  23. static int dvi_get_panel_size_from_DDCv2(void);
  24. static unsigned char dvi_get_panel_info(void);
  25. static int viafb_dvi_query_EDID(void);
  26. static int check_tmds_chip(int device_id_subaddr, int device_id)
  27. {
  28. if (tmds_register_read(device_id_subaddr) == device_id)
  29. return OK;
  30. else
  31. return FAIL;
  32. }
  33. void viafb_init_dvi_size(void)
  34. {
  35. DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
  36. DEBUG_MSG(KERN_INFO
  37. "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
  38. viaparinfo->tmds_setting_info->get_dvi_size_method);
  39. switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
  40. case GET_DVI_SIZE_BY_SYSTEM_BIOS:
  41. break;
  42. case GET_DVI_SZIE_BY_HW_STRAPPING:
  43. break;
  44. case GET_DVI_SIZE_BY_VGA_BIOS:
  45. default:
  46. dvi_get_panel_info();
  47. break;
  48. }
  49. return;
  50. }
  51. int viafb_tmds_trasmitter_identify(void)
  52. {
  53. unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
  54. /* Turn on ouputting pad */
  55. switch (viaparinfo->chip_info->gfx_chip_name) {
  56. case UNICHROME_K8M890:
  57. /*=* DFP Low Pad on *=*/
  58. sr2a = viafb_read_reg(VIASR, SR2A);
  59. viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
  60. break;
  61. case UNICHROME_P4M900:
  62. case UNICHROME_P4M890:
  63. /* DFP Low Pad on */
  64. sr2a = viafb_read_reg(VIASR, SR2A);
  65. viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
  66. /* DVP0 Pad on */
  67. sr1e = viafb_read_reg(VIASR, SR1E);
  68. viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
  69. break;
  70. default:
  71. /* DVP0/DVP1 Pad on */
  72. sr1e = viafb_read_reg(VIASR, SR1E);
  73. viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
  74. BIT5 + BIT6 + BIT7);
  75. /* SR3E[1]Multi-function selection:
  76. 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
  77. sr3e = viafb_read_reg(VIASR, SR3E);
  78. viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5);
  79. break;
  80. }
  81. /* Check for VT1632: */
  82. viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
  83. viaparinfo->chip_info->
  84. tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
  85. viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
  86. if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
  87. /*
  88. * Currently only support 12bits,dual edge,add 24bits mode later
  89. */
  90. tmds_register_write(0x08, 0x3b);
  91. DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
  92. DEBUG_MSG(KERN_INFO "\n %2d",
  93. viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
  94. DEBUG_MSG(KERN_INFO "\n %2d",
  95. viaparinfo->chip_info->tmds_chip_info.i2c_port);
  96. return OK;
  97. } else {
  98. viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
  99. if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
  100. != FAIL) {
  101. tmds_register_write(0x08, 0x3b);
  102. DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
  103. DEBUG_MSG(KERN_INFO "\n %2d",
  104. viaparinfo->chip_info->
  105. tmds_chip_info.tmds_chip_name);
  106. DEBUG_MSG(KERN_INFO "\n %2d",
  107. viaparinfo->chip_info->
  108. tmds_chip_info.i2c_port);
  109. return OK;
  110. }
  111. }
  112. viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
  113. if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
  114. ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
  115. (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
  116. DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
  117. return OK;
  118. }
  119. switch (viaparinfo->chip_info->gfx_chip_name) {
  120. case UNICHROME_K8M890:
  121. viafb_write_reg(SR2A, VIASR, sr2a);
  122. break;
  123. case UNICHROME_P4M900:
  124. case UNICHROME_P4M890:
  125. viafb_write_reg(SR2A, VIASR, sr2a);
  126. viafb_write_reg(SR1E, VIASR, sr1e);
  127. break;
  128. default:
  129. viafb_write_reg(SR1E, VIASR, sr1e);
  130. viafb_write_reg(SR3E, VIASR, sr3e);
  131. break;
  132. }
  133. viaparinfo->chip_info->
  134. tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
  135. viaparinfo->chip_info->tmds_chip_info.
  136. tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
  137. return FAIL;
  138. }
  139. static void tmds_register_write(int index, u8 data)
  140. {
  141. viaparinfo->shared->i2c_stuff.i2c_port =
  142. viaparinfo->chip_info->tmds_chip_info.i2c_port;
  143. viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
  144. tmds_chip_slave_addr, index,
  145. data);
  146. }
  147. static int tmds_register_read(int index)
  148. {
  149. u8 data;
  150. viaparinfo->shared->i2c_stuff.i2c_port =
  151. viaparinfo->chip_info->tmds_chip_info.i2c_port;
  152. viafb_i2c_readbyte((u8) viaparinfo->chip_info->
  153. tmds_chip_info.tmds_chip_slave_addr,
  154. (u8) index, &data);
  155. return data;
  156. }
  157. static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
  158. {
  159. viaparinfo->shared->i2c_stuff.i2c_port =
  160. viaparinfo->chip_info->tmds_chip_info.i2c_port;
  161. viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
  162. tmds_chip_slave_addr, (u8) index, buff, buff_len);
  163. return 0;
  164. }
  165. /* DVI Set Mode */
  166. void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp,
  167. int set_iga)
  168. {
  169. struct VideoModeTable *rb_mode;
  170. struct crt_mode_table *pDviTiming;
  171. unsigned long desirePixelClock, maxPixelClock;
  172. pDviTiming = mode->crtc;
  173. desirePixelClock = pDviTiming->clk / 1000000;
  174. maxPixelClock = (unsigned long)viaparinfo->
  175. tmds_setting_info->max_pixel_clock;
  176. DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
  177. if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
  178. rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr,
  179. mode->crtc[0].crtc.ver_addr);
  180. if (rb_mode) {
  181. mode = rb_mode;
  182. pDviTiming = rb_mode->crtc;
  183. }
  184. }
  185. viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga);
  186. viafb_set_output_path(DEVICE_DVI, set_iga,
  187. viaparinfo->chip_info->tmds_chip_info.output_interface);
  188. }
  189. /* Sense DVI Connector */
  190. int viafb_dvi_sense(void)
  191. {
  192. u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
  193. RegCR93 = 0, RegCR9B = 0, data;
  194. int ret = false;
  195. DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
  196. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
  197. /* DI1 Pad on */
  198. RegSR1E = viafb_read_reg(VIASR, SR1E);
  199. viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
  200. /* CR6B[0]VCK Input Selection: 1 = External clock. */
  201. RegCR6B = viafb_read_reg(VIACR, CR6B);
  202. viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
  203. /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
  204. [0] Software Control Power Sequence */
  205. RegCR91 = viafb_read_reg(VIACR, CR91);
  206. viafb_write_reg(CR91, VIACR, 0x1D);
  207. /* CR93[7] DI1 Data Source Selection: 1 = DSP2.
  208. CR93[5] DI1 Clock Source: 1 = internal.
  209. CR93[4] DI1 Clock Polarity.
  210. CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
  211. RegCR93 = viafb_read_reg(VIACR, CR93);
  212. viafb_write_reg(CR93, VIACR, 0x01);
  213. } else {
  214. /* DVP0/DVP1 Pad on */
  215. RegSR1E = viafb_read_reg(VIASR, SR1E);
  216. viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
  217. /* SR3E[1]Multi-function selection:
  218. 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
  219. RegSR3E = viafb_read_reg(VIASR, SR3E);
  220. viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
  221. /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
  222. [0] Software Control Power Sequence */
  223. RegCR91 = viafb_read_reg(VIACR, CR91);
  224. viafb_write_reg(CR91, VIACR, 0x1D);
  225. /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
  226. display.CR9B[2:0] DVP1 Clock Adjust */
  227. RegCR9B = viafb_read_reg(VIACR, CR9B);
  228. viafb_write_reg(CR9B, VIACR, 0x01);
  229. }
  230. data = (u8) tmds_register_read(0x09);
  231. if (data & 0x04)
  232. ret = true;
  233. if (ret == false) {
  234. if (viafb_dvi_query_EDID())
  235. ret = true;
  236. }
  237. /* Restore status */
  238. viafb_write_reg(SR1E, VIASR, RegSR1E);
  239. viafb_write_reg(CR91, VIACR, RegCR91);
  240. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
  241. viafb_write_reg(CR6B, VIACR, RegCR6B);
  242. viafb_write_reg(CR93, VIACR, RegCR93);
  243. } else {
  244. viafb_write_reg(SR3E, VIASR, RegSR3E);
  245. viafb_write_reg(CR9B, VIACR, RegCR9B);
  246. }
  247. return ret;
  248. }
  249. /* Query Flat Panel's EDID Table Version Through DVI Connector */
  250. static int viafb_dvi_query_EDID(void)
  251. {
  252. u8 data0, data1;
  253. int restore;
  254. DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
  255. restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
  256. viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
  257. data0 = (u8) tmds_register_read(0x00);
  258. data1 = (u8) tmds_register_read(0x01);
  259. if ((data0 == 0) && (data1 == 0xFF)) {
  260. viaparinfo->chip_info->
  261. tmds_chip_info.tmds_chip_slave_addr = restore;
  262. return EDID_VERSION_1; /* Found EDID1 Table */
  263. }
  264. data0 = (u8) tmds_register_read(0x00);
  265. viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
  266. if (data0 == 0x20)
  267. return EDID_VERSION_2; /* Found EDID2 Table */
  268. else
  269. return false;
  270. }
  271. /*
  272. *
  273. * int dvi_get_panel_size_from_DDCv1(void)
  274. *
  275. * - Get Panel Size Using EDID1 Table
  276. *
  277. * Return Type: int
  278. *
  279. */
  280. static int dvi_get_panel_size_from_DDCv1(void)
  281. {
  282. int i, max_h = 0, max_v = 0, tmp, restore;
  283. unsigned char rData;
  284. unsigned char EDID_DATA[18];
  285. DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
  286. restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
  287. viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
  288. rData = tmds_register_read(0x23);
  289. if (rData & 0x3C)
  290. max_h = 640;
  291. if (rData & 0xC0)
  292. max_h = 720;
  293. if (rData & 0x03)
  294. max_h = 800;
  295. rData = tmds_register_read(0x24);
  296. if (rData & 0xC0)
  297. max_h = 800;
  298. if (rData & 0x1E)
  299. max_h = 1024;
  300. if (rData & 0x01)
  301. max_h = 1280;
  302. for (i = 0x25; i < 0x6D; i++) {
  303. switch (i) {
  304. case 0x26:
  305. case 0x28:
  306. case 0x2A:
  307. case 0x2C:
  308. case 0x2E:
  309. case 0x30:
  310. case 0x32:
  311. case 0x34:
  312. rData = tmds_register_read(i);
  313. if (rData == 1)
  314. break;
  315. /* data = (data + 31) * 8 */
  316. tmp = (rData + 31) << 3;
  317. if (tmp > max_h)
  318. max_h = tmp;
  319. break;
  320. case 0x36:
  321. case 0x48:
  322. case 0x5A:
  323. case 0x6C:
  324. tmds_register_read_bytes(i, EDID_DATA, 10);
  325. if (!(EDID_DATA[0] || EDID_DATA[1])) {
  326. /* The first two byte must be zero. */
  327. if (EDID_DATA[3] == 0xFD) {
  328. /* To get max pixel clock. */
  329. viaparinfo->tmds_setting_info->
  330. max_pixel_clock = EDID_DATA[9] * 10;
  331. }
  332. }
  333. break;
  334. default:
  335. break;
  336. }
  337. }
  338. switch (max_h) {
  339. case 640:
  340. viaparinfo->tmds_setting_info->dvi_panel_size =
  341. VIA_RES_640X480;
  342. break;
  343. case 800:
  344. viaparinfo->tmds_setting_info->dvi_panel_size =
  345. VIA_RES_800X600;
  346. break;
  347. case 1024:
  348. viaparinfo->tmds_setting_info->dvi_panel_size =
  349. VIA_RES_1024X768;
  350. break;
  351. case 1280:
  352. viaparinfo->tmds_setting_info->dvi_panel_size =
  353. VIA_RES_1280X1024;
  354. break;
  355. case 1400:
  356. viaparinfo->tmds_setting_info->dvi_panel_size =
  357. VIA_RES_1400X1050;
  358. break;
  359. case 1440:
  360. viaparinfo->tmds_setting_info->dvi_panel_size =
  361. VIA_RES_1440X1050;
  362. break;
  363. case 1600:
  364. viaparinfo->tmds_setting_info->dvi_panel_size =
  365. VIA_RES_1600X1200;
  366. break;
  367. case 1920:
  368. if (max_v == 1200) {
  369. viaparinfo->tmds_setting_info->dvi_panel_size =
  370. VIA_RES_1920X1200;
  371. } else {
  372. viaparinfo->tmds_setting_info->dvi_panel_size =
  373. VIA_RES_1920X1080;
  374. }
  375. break;
  376. default:
  377. viaparinfo->tmds_setting_info->dvi_panel_size =
  378. VIA_RES_1024X768;
  379. DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d !\
  380. set default panel size.\n", max_h);
  381. break;
  382. }
  383. DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
  384. viaparinfo->tmds_setting_info->max_pixel_clock);
  385. viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
  386. return viaparinfo->tmds_setting_info->dvi_panel_size;
  387. }
  388. /*
  389. *
  390. * int dvi_get_panel_size_from_DDCv2(void)
  391. *
  392. * - Get Panel Size Using EDID2 Table
  393. *
  394. * Return Type: int
  395. *
  396. */
  397. static int dvi_get_panel_size_from_DDCv2(void)
  398. {
  399. int HSize = 0, restore;
  400. unsigned char R_Buffer[2];
  401. DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
  402. restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
  403. viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
  404. /* Horizontal: 0x76, 0x77 */
  405. tmds_register_read_bytes(0x76, R_Buffer, 2);
  406. HSize = R_Buffer[0];
  407. HSize += R_Buffer[1] << 8;
  408. switch (HSize) {
  409. case 640:
  410. viaparinfo->tmds_setting_info->dvi_panel_size =
  411. VIA_RES_640X480;
  412. break;
  413. case 800:
  414. viaparinfo->tmds_setting_info->dvi_panel_size =
  415. VIA_RES_800X600;
  416. break;
  417. case 1024:
  418. viaparinfo->tmds_setting_info->dvi_panel_size =
  419. VIA_RES_1024X768;
  420. break;
  421. case 1280:
  422. viaparinfo->tmds_setting_info->dvi_panel_size =
  423. VIA_RES_1280X1024;
  424. break;
  425. case 1400:
  426. viaparinfo->tmds_setting_info->dvi_panel_size =
  427. VIA_RES_1400X1050;
  428. break;
  429. case 1440:
  430. viaparinfo->tmds_setting_info->dvi_panel_size =
  431. VIA_RES_1440X1050;
  432. break;
  433. case 1600:
  434. viaparinfo->tmds_setting_info->dvi_panel_size =
  435. VIA_RES_1600X1200;
  436. break;
  437. default:
  438. viaparinfo->tmds_setting_info->dvi_panel_size =
  439. VIA_RES_1024X768;
  440. DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d!\
  441. set default panel size.\n", HSize);
  442. break;
  443. }
  444. viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
  445. return viaparinfo->tmds_setting_info->dvi_panel_size;
  446. }
  447. /*
  448. *
  449. * unsigned char dvi_get_panel_info(void)
  450. *
  451. * - Get Panel Size
  452. *
  453. * Return Type: unsigned char
  454. */
  455. static unsigned char dvi_get_panel_info(void)
  456. {
  457. unsigned char dvipanelsize;
  458. DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
  459. viafb_dvi_sense();
  460. switch (viafb_dvi_query_EDID()) {
  461. case 1:
  462. dvi_get_panel_size_from_DDCv1();
  463. break;
  464. case 2:
  465. dvi_get_panel_size_from_DDCv2();
  466. break;
  467. default:
  468. break;
  469. }
  470. DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
  471. viaparinfo->tmds_setting_info->dvi_panel_size);
  472. dvipanelsize = (unsigned char)(viaparinfo->
  473. tmds_setting_info->dvi_panel_size);
  474. return dvipanelsize;
  475. }
  476. /* If Disable DVI, turn off pad */
  477. void viafb_dvi_disable(void)
  478. {
  479. if (viaparinfo->chip_info->
  480. tmds_chip_info.output_interface == INTERFACE_DVP0)
  481. viafb_write_reg(SR1E, VIASR,
  482. viafb_read_reg(VIASR, SR1E) & (~0xC0));
  483. if (viaparinfo->chip_info->
  484. tmds_chip_info.output_interface == INTERFACE_DVP1)
  485. viafb_write_reg(SR1E, VIASR,
  486. viafb_read_reg(VIASR, SR1E) & (~0x30));
  487. if (viaparinfo->chip_info->
  488. tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
  489. viafb_write_reg(SR2A, VIASR,
  490. viafb_read_reg(VIASR, SR2A) & (~0x0C));
  491. if (viaparinfo->chip_info->
  492. tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
  493. viafb_write_reg(SR2A, VIASR,
  494. viafb_read_reg(VIASR, SR2A) & (~0x03));
  495. if (viaparinfo->chip_info->
  496. tmds_chip_info.output_interface == INTERFACE_TMDS)
  497. /* Turn off TMDS power. */
  498. viafb_write_reg(CRD2, VIACR,
  499. viafb_read_reg(VIACR, CRD2) | 0x08);
  500. }
  501. /* If Enable DVI, turn off pad */
  502. void viafb_dvi_enable(void)
  503. {
  504. u8 data;
  505. if (viaparinfo->chip_info->
  506. tmds_chip_info.output_interface == INTERFACE_DVP0) {
  507. viafb_write_reg(SR1E, VIASR,
  508. viafb_read_reg(VIASR, SR1E) | 0xC0);
  509. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
  510. tmds_register_write(0x88, 0x3b);
  511. else
  512. /*clear CR91[5] to direct on display period
  513. in the secondary diplay path */
  514. viafb_write_reg(CR91, VIACR,
  515. viafb_read_reg(VIACR, CR91) & 0xDF);
  516. }
  517. if (viaparinfo->chip_info->
  518. tmds_chip_info.output_interface == INTERFACE_DVP1) {
  519. viafb_write_reg(SR1E, VIASR,
  520. viafb_read_reg(VIASR, SR1E) | 0x30);
  521. /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
  522. if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
  523. tmds_register_write(0x88, 0x3b);
  524. } else {
  525. /*clear CR91[5] to direct on display period
  526. in the secondary diplay path */
  527. viafb_write_reg(CR91, VIACR,
  528. viafb_read_reg(VIACR, CR91) & 0xDF);
  529. }
  530. /*fix DVI cannot enable on EPIA-M board */
  531. if (viafb_platform_epia_dvi == 1) {
  532. viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
  533. viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
  534. if (viafb_bus_width == 24) {
  535. if (viafb_device_lcd_dualedge == 1)
  536. data = 0x3F;
  537. else
  538. data = 0x37;
  539. viafb_i2c_writebyte(viaparinfo->chip_info->
  540. tmds_chip_info.
  541. tmds_chip_slave_addr,
  542. 0x08, data);
  543. }
  544. }
  545. }
  546. if (viaparinfo->chip_info->
  547. tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
  548. viafb_write_reg(SR2A, VIASR,
  549. viafb_read_reg(VIASR, SR2A) | 0x0C);
  550. viafb_write_reg(CR91, VIACR,
  551. viafb_read_reg(VIACR, CR91) & 0xDF);
  552. }
  553. if (viaparinfo->chip_info->
  554. tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
  555. viafb_write_reg(SR2A, VIASR,
  556. viafb_read_reg(VIASR, SR2A) | 0x03);
  557. viafb_write_reg(CR91, VIACR,
  558. viafb_read_reg(VIACR, CR91) & 0xDF);
  559. }
  560. if (viaparinfo->chip_info->
  561. tmds_chip_info.output_interface == INTERFACE_TMDS) {
  562. /* Turn on Display period in the panel path. */
  563. viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
  564. /* Turn on TMDS power. */
  565. viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
  566. }
  567. }