TI.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. /*
  2. * Copyright 1998 by Alan Hourihane, Wigan, England.
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that
  7. * copyright notice and this permission notice appear in supporting
  8. * documentation, and that the name of Alan Hourihane not be used in
  9. * advertising or publicity pertaining to distribution of the software without
  10. * specific, written prior permission. Alan Hourihane makes no representations
  11. * about the suitability of this software for any purpose. It is provided
  12. * "as is" without express or implied warranty.
  13. *
  14. * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  20. * PERFORMANCE OF THIS SOFTWARE.
  21. *
  22. * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
  23. *
  24. * Modified from IBM.c to support TI RAMDAC routines
  25. * by Jens Owen, <jens@tungstengraphics.com>.
  26. */
  27. #ifdef HAVE_XORG_CONFIG_H
  28. #include <xorg-config.h>
  29. #endif
  30. #include "xf86.h"
  31. #include "xf86_OSproc.h"
  32. #include "xf86Cursor.h"
  33. #define INIT_TI_RAMDAC_INFO
  34. #include "TIPriv.h"
  35. #include "xf86RamDacPriv.h"
  36. /* The following values are in kHz */
  37. #define TI_MIN_VCO_FREQ 110000
  38. #define TI_MAX_VCO_FREQ 220000
  39. unsigned long
  40. TIramdacCalculateMNPForClock(unsigned long RefClock, /* In 100Hz units */
  41. unsigned long ReqClock, /* In 100Hz units */
  42. char IsPixClock, /* boolean, is this the pixel or the sys clock */
  43. unsigned long MinClock, /* Min VCO rating */
  44. unsigned long MaxClock, /* Max VCO rating */
  45. unsigned long *rM, /* M Out */
  46. unsigned long *rN, /* N Out */
  47. unsigned long *rP /* Min P In, P Out */
  48. )
  49. {
  50. unsigned long n, p;
  51. unsigned long best_m = 0, best_n = 0;
  52. double VCO, IntRef = (double) RefClock;
  53. double m_err, inc_m, calc_m;
  54. unsigned long ActualClock;
  55. /* Make sure that MinClock <= ReqClock <= MaxClock */
  56. if (ReqClock < MinClock)
  57. ReqClock = MinClock;
  58. if (ReqClock > MaxClock)
  59. ReqClock = MaxClock;
  60. /*
  61. * ActualClock = VCO / 2 ^ p
  62. * Choose p so that TI_MIN_VCO_FREQ <= VCO <= TI_MAX_VCO_FREQ
  63. * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ
  64. * we don't have to bother checking for this maximum limit.
  65. */
  66. VCO = (double) ReqClock;
  67. for (p = 0; p < 3 && VCO < TI_MIN_VCO_FREQ; (p)++)
  68. VCO *= 2.0;
  69. /*
  70. * We avoid doing multiplications by ( 65 - n ),
  71. * and add an increment instead - this keeps any error small.
  72. */
  73. inc_m = VCO / (IntRef * 8.0);
  74. /* Initial value of calc_m for the loop */
  75. calc_m = inc_m + inc_m + inc_m;
  76. /* Initial amount of error for an integer - impossibly large */
  77. m_err = 2.0;
  78. /* Search for the closest INTEGER value of ( 65 - m ) */
  79. for (n = 3; n <= 25; (n)++, calc_m += inc_m) {
  80. /* Ignore values of ( 65 - m ) which we can't use */
  81. if (calc_m < 3.0 || calc_m > 64.0)
  82. continue;
  83. /*
  84. * Pick the closest INTEGER (has smallest fractional part).
  85. * The optimizer should clean this up for us.
  86. */
  87. if ((calc_m - (int) calc_m) < m_err) {
  88. m_err = calc_m - (int) calc_m;
  89. best_m = (int) calc_m;
  90. best_n = n;
  91. }
  92. }
  93. /* 65 - ( 65 - x ) = x */
  94. *rM = 65 - best_m;
  95. *rN = 65 - best_n;
  96. *rP = p;
  97. /* Now all the calculations can be completed */
  98. VCO = 8.0 * IntRef * best_m / best_n;
  99. ActualClock = VCO / (1 << p);
  100. DebugF("f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n",
  101. ActualClock, VCO, *rN, *rM, *rP);
  102. return ActualClock;
  103. }
  104. void
  105. TIramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
  106. RamDacRegRecPtr ramdacReg)
  107. {
  108. int i;
  109. unsigned long status;
  110. /* Here we pass a short, so that we can evaluate a mask too
  111. * So that the mask is the high byte and the data the low byte
  112. * Order is important
  113. */
  114. TIRESTORE(TIDAC_latch_ctrl);
  115. TIRESTORE(TIDAC_true_color_ctrl);
  116. TIRESTORE(TIDAC_multiplex_ctrl);
  117. TIRESTORE(TIDAC_clock_select);
  118. TIRESTORE(TIDAC_palette_page);
  119. TIRESTORE(TIDAC_general_ctrl);
  120. TIRESTORE(TIDAC_misc_ctrl);
  121. /* 0x2A & 0x2B are reserved */
  122. TIRESTORE(TIDAC_key_over_low);
  123. TIRESTORE(TIDAC_key_over_high);
  124. TIRESTORE(TIDAC_key_red_low);
  125. TIRESTORE(TIDAC_key_red_high);
  126. TIRESTORE(TIDAC_key_green_low);
  127. TIRESTORE(TIDAC_key_green_high);
  128. TIRESTORE(TIDAC_key_blue_low);
  129. TIRESTORE(TIDAC_key_blue_high);
  130. TIRESTORE(TIDAC_key_ctrl);
  131. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_clock_ctrl, 0, 0x30);
  132. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_clock_ctrl, 0, 0x38);
  133. TIRESTORE(TIDAC_clock_ctrl);
  134. TIRESTORE(TIDAC_sense_test);
  135. TIRESTORE(TIDAC_ind_curs_ctrl);
  136. /* only restore clocks if they were valid to begin with */
  137. if (ramdacReg->DacRegs[TIDAC_PIXEL_VALID]) {
  138. /* Reset pixel clock */
  139. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0x22);
  140. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_pixel_data, 0, 0x3c);
  141. /* Restore N, M & P values for pixel clocks */
  142. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0);
  143. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_pixel_data, 0,
  144. ramdacReg->DacRegs[TIDAC_PIXEL_N]);
  145. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_pixel_data, 0,
  146. ramdacReg->DacRegs[TIDAC_PIXEL_M]);
  147. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_pixel_data, 0,
  148. ramdacReg->DacRegs[TIDAC_PIXEL_P]);
  149. /* wait for pixel clock to lock */
  150. i = 1000000;
  151. do {
  152. status = (*ramdacPtr->ReadDAC) (pScrn, TIDAC_pll_pixel_data);
  153. } while ((!(status & 0x40)) && (--i));
  154. if (!(status & 0x40)) {
  155. xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
  156. "Pixel clock setup timed out\n");
  157. return;
  158. }
  159. }
  160. if (ramdacReg->DacRegs[TIDAC_LOOP_VALID]) {
  161. /* Reset loop clock */
  162. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0x22);
  163. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_loop_data, 0, 0x70);
  164. /* Restore N, M & P values for pixel clocks */
  165. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0);
  166. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_loop_data, 0,
  167. ramdacReg->DacRegs[TIDAC_LOOP_N]);
  168. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_loop_data, 0,
  169. ramdacReg->DacRegs[TIDAC_LOOP_M]);
  170. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_loop_data, 0,
  171. ramdacReg->DacRegs[TIDAC_LOOP_P]);
  172. /* wait for loop clock to lock */
  173. i = 1000000;
  174. do {
  175. status = (*ramdacPtr->ReadDAC) (pScrn, TIDAC_pll_loop_data);
  176. } while ((!(status & 0x40)) && (--i));
  177. if (!(status & 0x40)) {
  178. xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
  179. "Loop clock setup timed out\n");
  180. return;
  181. }
  182. }
  183. /* restore palette */
  184. (*ramdacPtr->WriteAddress) (pScrn, 0);
  185. #ifndef NOT_DONE
  186. for (i = 0; i < 768; i++)
  187. (*ramdacPtr->WriteData) (pScrn, ramdacReg->DAC[i]);
  188. #else
  189. (*ramdacPtr->WriteData) (pScrn, 0);
  190. (*ramdacPtr->WriteData) (pScrn, 0);
  191. (*ramdacPtr->WriteData) (pScrn, 0);
  192. for (i = 0; i < 765; i++)
  193. (*ramdacPtr->WriteData) (pScrn, 0xff);
  194. #endif
  195. }
  196. void
  197. TIramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
  198. RamDacRegRecPtr ramdacReg)
  199. {
  200. int i;
  201. (*ramdacPtr->ReadAddress) (pScrn, 0);
  202. for (i = 0; i < 768; i++)
  203. ramdacReg->DAC[i] = (*ramdacPtr->ReadData) (pScrn);
  204. /* Read back N,M and P values for pixel clock */
  205. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0);
  206. ramdacReg->DacRegs[TIDAC_PIXEL_N] =
  207. (*ramdacPtr->ReadDAC) (pScrn, TIDAC_pll_pixel_data);
  208. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0x11);
  209. ramdacReg->DacRegs[TIDAC_PIXEL_M] =
  210. (*ramdacPtr->ReadDAC) (pScrn, TIDAC_pll_pixel_data);
  211. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0x22);
  212. ramdacReg->DacRegs[TIDAC_PIXEL_P] =
  213. (*ramdacPtr->ReadDAC) (pScrn, TIDAC_pll_pixel_data);
  214. /* Read back N,M and P values for loop clock */
  215. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0);
  216. ramdacReg->DacRegs[TIDAC_LOOP_N] =
  217. (*ramdacPtr->ReadDAC) (pScrn, TIDAC_pll_loop_data);
  218. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0x11);
  219. ramdacReg->DacRegs[TIDAC_LOOP_M] =
  220. (*ramdacPtr->ReadDAC) (pScrn, TIDAC_pll_loop_data);
  221. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_pll_addr, 0, 0x22);
  222. ramdacReg->DacRegs[TIDAC_LOOP_P] =
  223. (*ramdacPtr->ReadDAC) (pScrn, TIDAC_pll_loop_data);
  224. /* Order is important */
  225. TISAVE(TIDAC_latch_ctrl);
  226. TISAVE(TIDAC_true_color_ctrl);
  227. TISAVE(TIDAC_multiplex_ctrl);
  228. TISAVE(TIDAC_clock_select);
  229. TISAVE(TIDAC_palette_page);
  230. TISAVE(TIDAC_general_ctrl);
  231. TISAVE(TIDAC_misc_ctrl);
  232. /* 0x2A & 0x2B are reserved */
  233. TISAVE(TIDAC_key_over_low);
  234. TISAVE(TIDAC_key_over_high);
  235. TISAVE(TIDAC_key_red_low);
  236. TISAVE(TIDAC_key_red_high);
  237. TISAVE(TIDAC_key_green_low);
  238. TISAVE(TIDAC_key_green_high);
  239. TISAVE(TIDAC_key_blue_low);
  240. TISAVE(TIDAC_key_blue_high);
  241. TISAVE(TIDAC_key_ctrl);
  242. TISAVE(TIDAC_clock_ctrl);
  243. TISAVE(TIDAC_sense_test);
  244. TISAVE(TIDAC_ind_curs_ctrl);
  245. }
  246. RamDacHelperRecPtr
  247. TIramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs)
  248. {
  249. RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
  250. RamDacHelperRecPtr ramdacHelperPtr = NULL;
  251. Bool RamDacIsSupported = FALSE;
  252. int TIramdac_ID = -1;
  253. int i;
  254. unsigned char id, rev, rev2, id2;
  255. /* read ID and revision */
  256. rev = (*ramdacPtr->ReadDAC) (pScrn, TIDAC_rev);
  257. id = (*ramdacPtr->ReadDAC) (pScrn, TIDAC_id);
  258. /* check if ID and revision are read only */
  259. (*ramdacPtr->WriteDAC) (pScrn, ~rev, 0, TIDAC_rev);
  260. (*ramdacPtr->WriteDAC) (pScrn, ~id, 0, TIDAC_id);
  261. rev2 = (*ramdacPtr->ReadDAC) (pScrn, TIDAC_rev);
  262. id2 = (*ramdacPtr->ReadDAC) (pScrn, TIDAC_id);
  263. switch (id) {
  264. case TIDAC_TVP_3030_ID:
  265. if (id == id2 && rev == rev2) /* check for READ ONLY */
  266. TIramdac_ID = TI3030_RAMDAC;
  267. break;
  268. case TIDAC_TVP_3026_ID:
  269. if (id == id2 && rev == rev2) /* check for READ ONLY */
  270. TIramdac_ID = TI3026_RAMDAC;
  271. break;
  272. }
  273. (*ramdacPtr->WriteDAC) (pScrn, rev, 0, TIDAC_rev);
  274. (*ramdacPtr->WriteDAC) (pScrn, id, 0, TIDAC_id);
  275. if (TIramdac_ID == -1) {
  276. xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
  277. "Cannot determine TI RAMDAC type, aborting\n");
  278. return NULL;
  279. }
  280. else {
  281. xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
  282. "Attached RAMDAC is %s\n",
  283. TIramdacDeviceInfo[TIramdac_ID & 0xFFFF].DeviceName);
  284. }
  285. for (i = 0; ramdacs[i].token != -1; i++) {
  286. if (ramdacs[i].token == TIramdac_ID)
  287. RamDacIsSupported = TRUE;
  288. }
  289. if (!RamDacIsSupported) {
  290. xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
  291. "This TI RAMDAC is NOT supported by this driver, aborting\n");
  292. return NULL;
  293. }
  294. ramdacHelperPtr = RamDacHelperCreateInfoRec();
  295. switch (TIramdac_ID) {
  296. case TI3030_RAMDAC:
  297. ramdacHelperPtr->SetBpp = TIramdac3030SetBpp;
  298. ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit;
  299. break;
  300. case TI3026_RAMDAC:
  301. ramdacHelperPtr->SetBpp = TIramdac3026SetBpp;
  302. ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit;
  303. break;
  304. }
  305. ramdacPtr->RamDacType = TIramdac_ID;
  306. ramdacHelperPtr->RamDacType = TIramdac_ID;
  307. ramdacHelperPtr->Save = TIramdacSave;
  308. ramdacHelperPtr->Restore = TIramdacRestore;
  309. return ramdacHelperPtr;
  310. }
  311. void
  312. TIramdac3026SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
  313. {
  314. switch (pScrn->bitsPerPixel) {
  315. case 32:
  316. /* order is important */
  317. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
  318. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
  319. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5c;
  320. ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
  321. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  322. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
  323. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
  324. /* 0x2A & 0x2B are reserved */
  325. ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
  326. ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
  327. ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
  328. ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
  329. ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
  330. ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
  331. ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
  332. ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
  333. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
  334. ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
  335. if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
  336. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
  337. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
  338. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
  339. }
  340. ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
  341. break;
  342. case 24:
  343. /* order is important */
  344. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
  345. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
  346. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
  347. ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
  348. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  349. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
  350. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
  351. /* 0x2A & 0x2B are reserved */
  352. ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
  353. ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
  354. ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
  355. ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
  356. ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
  357. ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
  358. ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
  359. ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
  360. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
  361. ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
  362. ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
  363. break;
  364. case 16:
  365. /* order is important */
  366. #if 0
  367. /* Matrox driver uses this */
  368. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
  369. #else
  370. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
  371. #endif
  372. if (pScrn->depth == 16) {
  373. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
  374. }
  375. else {
  376. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
  377. }
  378. #if 0
  379. /* Matrox driver uses this */
  380. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
  381. ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
  382. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  383. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
  384. #else
  385. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x54;
  386. ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
  387. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  388. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
  389. #endif
  390. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
  391. /* 0x2A & 0x2B are reserved */
  392. ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
  393. ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
  394. ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
  395. ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
  396. ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
  397. ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
  398. ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
  399. ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
  400. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
  401. ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
  402. ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
  403. break;
  404. case 8:
  405. /* order is important */
  406. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
  407. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
  408. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4c;
  409. ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
  410. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  411. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
  412. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
  413. /* 0x2A & 0x2B are reserved */
  414. ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
  415. ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
  416. ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
  417. ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
  418. ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
  419. ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
  420. ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00;
  421. ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
  422. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
  423. ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
  424. ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
  425. break;
  426. }
  427. }
  428. void
  429. TIramdac3030SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
  430. {
  431. switch (pScrn->bitsPerPixel) {
  432. case 32:
  433. /* order is important */
  434. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
  435. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
  436. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5D;
  437. ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
  438. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  439. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
  440. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
  441. /* 0x2A & 0x2B are reserved */
  442. ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
  443. ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
  444. ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
  445. ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
  446. ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
  447. ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
  448. ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
  449. ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
  450. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
  451. ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
  452. if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
  453. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
  454. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
  455. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
  456. }
  457. ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
  458. break;
  459. case 24:
  460. /* order is important */
  461. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
  462. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
  463. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
  464. ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
  465. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  466. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
  467. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
  468. /* 0x2A & 0x2B are reserved */
  469. ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
  470. ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
  471. ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
  472. ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
  473. ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
  474. ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
  475. ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
  476. ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
  477. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
  478. ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
  479. ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
  480. break;
  481. case 16:
  482. /* order is important */
  483. #if 0
  484. /* Matrox driver uses this */
  485. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
  486. #else
  487. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
  488. #endif
  489. if (pScrn->depth == 16) {
  490. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
  491. }
  492. else {
  493. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
  494. }
  495. #if 0
  496. /* Matrox driver uses this */
  497. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
  498. ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
  499. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  500. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
  501. #else
  502. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x55;
  503. ramdacReg->DacRegs[TIDAC_clock_select] = 0x85;
  504. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  505. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
  506. #endif
  507. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
  508. /* 0x2A & 0x2B are reserved */
  509. ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
  510. ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
  511. ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
  512. ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
  513. ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
  514. ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
  515. ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
  516. ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
  517. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
  518. ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
  519. ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
  520. break;
  521. case 8:
  522. /* order is important */
  523. ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
  524. ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
  525. ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4d;
  526. ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
  527. ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
  528. ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
  529. ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
  530. /* 0x2A & 0x2B are reserved */
  531. ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
  532. ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
  533. ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
  534. ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
  535. ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
  536. ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
  537. ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00;
  538. ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
  539. ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
  540. ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
  541. ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
  542. break;
  543. }
  544. }
  545. static void
  546. TIramdacShowCursor(ScrnInfoPtr pScrn)
  547. {
  548. RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
  549. /* Enable cursor - X11 mode */
  550. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_ind_curs_ctrl, 0, 0x03);
  551. }
  552. static void
  553. TIramdacHideCursor(ScrnInfoPtr pScrn)
  554. {
  555. RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
  556. /* Disable cursor - X11 mode */
  557. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_ind_curs_ctrl, 0, 0x00);
  558. }
  559. static void
  560. TIramdacSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
  561. {
  562. RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
  563. x += 64;
  564. y += 64;
  565. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_XLOW, 0, x & 0xff);
  566. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_XHIGH, 0, (x >> 8) & 0x0f);
  567. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_YLOW, 0, y & 0xff);
  568. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_YHIGH, 0, (y >> 8) & 0x0f);
  569. }
  570. static void
  571. TIramdacSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
  572. {
  573. RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
  574. /* Background color */
  575. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_WRITE_ADDR, 0, 1);
  576. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_COLOR, 0,
  577. ((bg & 0x00ff0000) >> 16));
  578. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_COLOR, 0,
  579. ((bg & 0x0000ff00) >> 8));
  580. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_COLOR, 0, (bg & 0x000000ff));
  581. /* Foreground color */
  582. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_WRITE_ADDR, 0, 2);
  583. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_COLOR, 0,
  584. ((fg & 0x00ff0000) >> 16));
  585. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_COLOR, 0,
  586. ((fg & 0x0000ff00) >> 8));
  587. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_COLOR, 0, (fg & 0x000000ff));
  588. }
  589. static Bool
  590. TIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
  591. {
  592. RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
  593. int i = 1024;
  594. /* reset A9,A8 */
  595. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_ind_curs_ctrl, 0, 0x00);
  596. /* reset cursor RAM load address A7..A0 */
  597. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_INDEX, 0x00, 0x00);
  598. while (i--) {
  599. /* NOT_DONE: might need a delay here */
  600. (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_RAM_DATA, 0, *(src++));
  601. }
  602. return TRUE;
  603. }
  604. static Bool
  605. TIramdacUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
  606. {
  607. return TRUE;
  608. }
  609. void
  610. TIramdacHWCursorInit(xf86CursorInfoPtr infoPtr)
  611. {
  612. infoPtr->MaxWidth = 64;
  613. infoPtr->MaxHeight = 64;
  614. infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
  615. HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
  616. HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
  617. infoPtr->SetCursorColors = TIramdacSetCursorColors;
  618. infoPtr->SetCursorPosition = TIramdacSetCursorPosition;
  619. infoPtr->LoadCursorImageCheck = TIramdacLoadCursorImage;
  620. infoPtr->HideCursor = TIramdacHideCursor;
  621. infoPtr->ShowCursor = TIramdacShowCursor;
  622. infoPtr->UseHWCursor = TIramdacUseHWCursor;
  623. }
  624. void
  625. TIramdacLoadPalette(ScrnInfoPtr pScrn,
  626. int numColors,
  627. int *indices, LOCO * colors, VisualPtr pVisual)
  628. {
  629. RamDacRecPtr hwp = RAMDACSCRPTR(pScrn);
  630. int i, index, shift;
  631. if (pScrn->depth == 16) {
  632. for (i = 0; i < numColors; i++) {
  633. index = indices[i];
  634. (*hwp->WriteAddress) (pScrn, index << 2);
  635. (*hwp->WriteData) (pScrn, colors[index >> 1].red);
  636. (*hwp->WriteData) (pScrn, colors[index].green);
  637. (*hwp->WriteData) (pScrn, colors[index >> 1].blue);
  638. if (index <= 31) {
  639. (*hwp->WriteAddress) (pScrn, index << 3);
  640. (*hwp->WriteData) (pScrn, colors[index].red);
  641. (*hwp->WriteData) (pScrn, colors[(index << 1) + 1].green);
  642. (*hwp->WriteData) (pScrn, colors[index].blue);
  643. }
  644. }
  645. }
  646. else {
  647. shift = (pScrn->depth == 15) ? 3 : 0;
  648. for (i = 0; i < numColors; i++) {
  649. index = indices[i];
  650. (*hwp->WriteAddress) (pScrn, index << shift);
  651. (*hwp->WriteData) (pScrn, colors[index].red);
  652. (*hwp->WriteData) (pScrn, colors[index].green);
  653. (*hwp->WriteData) (pScrn, colors[index].blue);
  654. }
  655. }
  656. }
  657. TIramdacLoadPaletteProc *
  658. TIramdacLoadPaletteWeak(void)
  659. {
  660. return TIramdacLoadPalette;
  661. }