matroxfb_DAC1064.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:29k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
  4.  *
  5.  * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
  6.  *
  7.  * Version: 1.54 2001/09/09
  8.  *
  9.  * See matroxfb_base.c for contributors.
  10.  *
  11.  */
  12. /* make checkconfig does not walk through include tree :-( */
  13. #include <linux/config.h>
  14. #include "matroxfb_DAC1064.h"
  15. #include "matroxfb_misc.h"
  16. #include "matroxfb_accel.h"
  17. #include <linux/matroxfb.h>
  18. #ifdef NEED_DAC1064
  19. #define outDAC1064 matroxfb_DAC_out
  20. #define inDAC1064 matroxfb_DAC_in
  21. #define DAC1064_OPT_SCLK_PCI 0x00
  22. #define DAC1064_OPT_SCLK_PLL 0x01
  23. #define DAC1064_OPT_SCLK_EXT 0x02
  24. #define DAC1064_OPT_SCLK_MASK 0x03
  25. #define DAC1064_OPT_GDIV1 0x04 /* maybe it is GDIV2 on G100 ?! */
  26. #define DAC1064_OPT_GDIV3 0x00
  27. #define DAC1064_OPT_MDIV1 0x08
  28. #define DAC1064_OPT_MDIV2 0x00
  29. #define DAC1064_OPT_RESERVED 0x10
  30. static void matroxfb_DAC1064_flashcursor(unsigned long ptr) {
  31. unsigned long flags;
  32. #define minfo ((struct matrox_fb_info*)ptr)
  33. matroxfb_DAC_lock_irqsave(flags);
  34. outDAC1064(PMINFO M1064_XCURCTRL, inDAC1064(PMINFO M1064_XCURCTRL) ^ M1064_XCURCTRL_DIS ^ M1064_XCURCTRL_XGA);
  35. ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
  36. add_timer(&ACCESS_FBINFO(cursor.timer));
  37. matroxfb_DAC_unlock_irqrestore(flags);
  38. #undef minfo
  39. }
  40. static void matroxfb_DAC1064_createcursor(WPMINFO struct display* p) {
  41. vaddr_t cursorbase;
  42. u_int32_t xline;
  43. unsigned int i;
  44. unsigned int h, to;
  45. CRITFLAGS
  46. if (ACCESS_FBINFO(currcon_display) != p)
  47. return;
  48. matroxfb_createcursorshape(PMINFO p, p->var.vmode);
  49. xline = (~0) << (32 - ACCESS_FBINFO(cursor.w));
  50. cursorbase = ACCESS_FBINFO(video.vbase);
  51. h = ACCESS_FBINFO(features.DAC1064.cursorimage);
  52. CRITBEGIN
  53. #ifdef __BIG_ENDIAN
  54. WaitTillIdle();
  55. mga_outl(M_OPMODE, M_OPMODE_32BPP);
  56. #endif
  57. to = ACCESS_FBINFO(cursor.u);
  58. for (i = 0; i < to; i++) {
  59. mga_writel(cursorbase, h, 0);
  60. mga_writel(cursorbase, h+4, 0);
  61. mga_writel(cursorbase, h+8, ~0);
  62. mga_writel(cursorbase, h+12, ~0);
  63. h += 16;
  64. }
  65. to = ACCESS_FBINFO(cursor.d);
  66. for (; i < to; i++) {
  67. mga_writel(cursorbase, h, 0);
  68. mga_writel(cursorbase, h+4, xline);
  69. mga_writel(cursorbase, h+8, ~0);
  70. mga_writel(cursorbase, h+12, ~0);
  71. h += 16;
  72. }
  73. for (; i < 64; i++) {
  74. mga_writel(cursorbase, h, 0);
  75. mga_writel(cursorbase, h+4, 0);
  76. mga_writel(cursorbase, h+8, ~0);
  77. mga_writel(cursorbase, h+12, ~0);
  78. h += 16;
  79. }
  80. #ifdef __BIG_ENDIAN
  81. mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
  82. #endif
  83. CRITEND
  84. }
  85. static void matroxfb_DAC1064_cursor(struct display* p, int mode, int x, int y) {
  86. unsigned long flags;
  87. MINFO_FROM_DISP(p);
  88. if (ACCESS_FBINFO(currcon_display) != p)
  89. return;
  90. if (mode == CM_ERASE) {
  91. if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
  92. del_timer_sync(&ACCESS_FBINFO(cursor.timer));
  93. matroxfb_DAC_lock_irqsave(flags);
  94. ACCESS_FBINFO(cursor.state) = CM_ERASE;
  95. outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_DIS);
  96. matroxfb_DAC_unlock_irqrestore(flags);
  97. }
  98. return;
  99. }
  100. if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))
  101. matroxfb_DAC1064_createcursor(PMINFO p);
  102. x *= fontwidth(p);
  103. y *= fontheight(p);
  104. y -= p->var.yoffset;
  105. if (p->var.vmode & FB_VMODE_DOUBLE)
  106. y *= 2;
  107. del_timer_sync(&ACCESS_FBINFO(cursor.timer));
  108. matroxfb_DAC_lock_irqsave(flags);
  109. if ((x != ACCESS_FBINFO(cursor.x)) || (y != ACCESS_FBINFO(cursor.y)) || ACCESS_FBINFO(cursor.redraw)) {
  110. ACCESS_FBINFO(cursor.redraw) = 0;
  111. ACCESS_FBINFO(cursor.x) = x;
  112. ACCESS_FBINFO(cursor.y) = y;
  113. x += 64;
  114. y += 64;
  115. outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_DIS);
  116. mga_outb(M_RAMDAC_BASE+M1064_CURPOSXL, x);
  117. mga_outb(M_RAMDAC_BASE+M1064_CURPOSXH, x >> 8);
  118. mga_outb(M_RAMDAC_BASE+M1064_CURPOSYL, y);
  119. mga_outb(M_RAMDAC_BASE+M1064_CURPOSYH, y >> 8);
  120. }
  121. ACCESS_FBINFO(cursor.state) = CM_DRAW;
  122. if (ACCESS_FBINFO(devflags.blink))
  123. mod_timer(&ACCESS_FBINFO(cursor.timer), jiffies + HZ/2);
  124. outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_XGA);
  125. matroxfb_DAC_unlock_irqrestore(flags);
  126. }
  127. static int matroxfb_DAC1064_setfont(struct display* p, int width, int height) {
  128. if (p && p->conp)
  129. matroxfb_DAC1064_createcursor(PMXINFO(p) p);
  130. return 0;
  131. }
  132. static int DAC1064_selhwcursor(WPMINFO struct display* p) {
  133. ACCESS_FBINFO(dispsw.cursor) = matroxfb_DAC1064_cursor;
  134. ACCESS_FBINFO(dispsw.set_font) = matroxfb_DAC1064_setfont;
  135. return 0;
  136. }
  137. static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {
  138. unsigned int fvco;
  139. unsigned int p;
  140. DBG("DAC1064_calcclock")
  141. fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p);
  142. if (ACCESS_FBINFO(devflags.g450dac)) {
  143. if (fvco <= 300000) /* 276-324 */
  144. ;
  145. else if (fvco <= 400000) /* 378-438 */
  146. p |= 0x08;
  147. else if (fvco <= 550000) /* 540-567 */
  148. p |= 0x10;
  149. else if (fvco <= 690000) /* 675-695 */
  150. p |= 0x18;
  151. else if (fvco <= 800000) /* 776-803 */
  152. p |= 0x20;
  153. else if (fvco <= 891000) /* 891-891 */
  154. p |= 0x28;
  155. else if (fvco <= 940000) /* 931-945 */
  156. p |= 0x30;
  157. else /* <959 */
  158. p |= 0x38;
  159. } else {
  160. p = (1 << p) - 1;
  161. if (fvco <= 100000)
  162. ;
  163. else if (fvco <= 140000)
  164. p |= 0x08;
  165. else if (fvco <= 180000)
  166. p |= 0x10;
  167. else
  168. p |= 0x18;
  169. }
  170. *post = p;
  171. }
  172. /* they must be in POS order */
  173. static const unsigned char MGA1064_DAC_regs[] = {
  174. M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
  175. M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
  176. M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
  177. M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,
  178. DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,
  179. M1064_XMISCCTRL,
  180. M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,
  181. M1064_XCRCBITSEL,
  182. M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
  183. static const unsigned char MGA1064_DAC[] = {
  184. 0x00, 0x00, M1064_XCURCTRL_DIS,
  185. 0x00, 0x00, 0x00,  /* black */
  186. 0xFF, 0xFF, 0xFF, /* white */
  187. 0xFF, 0x00, 0x00, /* red */
  188. 0x00, 0,
  189. M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,
  190. M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,
  191. M1064_XMISCCTRL_DAC_8BIT,
  192. 0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,
  193. 0x00,
  194. 0x00, 0x00, 0xFF, 0xFF};
  195. static void DAC1064_setpclk(CPMINFO struct matrox_hw_state* hw, unsigned long fout) {
  196. unsigned int m, n, p;
  197. DBG("DAC1064_setpclk")
  198. DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
  199. hw->DACclk[0] = m;
  200. hw->DACclk[1] = n;
  201. hw->DACclk[2] = p;
  202. }
  203. static void DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem){
  204. u_int32_t mx;
  205. DBG("DAC1064_setmclk")
  206. if (ACCESS_FBINFO(devflags.noinit)) {
  207. /* read MCLK and give up... */
  208. hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
  209. hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
  210. hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
  211. return;
  212. }
  213. mx = hw->MXoptionReg | 0x00000004;
  214. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
  215. mx &= ~0x000000BB;
  216. if (oscinfo & DAC1064_OPT_GDIV1)
  217. mx |= 0x00000008;
  218. if (oscinfo & DAC1064_OPT_MDIV1)
  219. mx |= 0x00000010;
  220. if (oscinfo & DAC1064_OPT_RESERVED)
  221. mx |= 0x00000080;
  222. if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {
  223. /* select PCI clock until we have setup oscilator... */
  224. int clk;
  225. unsigned int m, n, p;
  226. /* powerup system PLL, select PCI clock */
  227. mx |= 0x00000020;
  228. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
  229. mx &= ~0x00000004;
  230. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
  231. /* !!! you must not access device if MCLK is not running !!!
  232.    Doing so cause immediate PCI lockup :-( Maybe they should
  233.    generate ABORT or I/O (parity...) error and Linux should
  234.    recover from this... (kill driver/process). But world is not
  235.    perfect... */
  236. /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
  237.    select PLL... because of PLL can be stopped at this time) */
  238. DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
  239. outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m);
  240. outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n);
  241. outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p);
  242. for (clk = 65536; clk; --clk) {
  243. if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40)
  244. break;
  245. }
  246. if (!clk)
  247. printk(KERN_ERR "matroxfb: aiee, SYSPLL not lockedn");
  248. /* select PLL */
  249. mx |= 0x00000005;
  250. } else {
  251. /* select specified system clock source */
  252. mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
  253. }
  254. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
  255. mx &= ~0x00000004;
  256. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
  257. hw->MXoptionReg = mx;
  258. }
  259. void DAC1064_global_init(CPMINFO struct matrox_hw_state* hw) {
  260. hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
  261. hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
  262. hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
  263. hw->DACreg[POS1064_XOUTPUTCONN] = 0x01; /* output #1 enabled */
  264. if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {
  265. if (ACCESS_FBINFO(devflags.g450dac)) {
  266. hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL2;
  267. hw->DACreg[POS1064_XOUTPUTCONN] = 0x05; /* output #1 enabled; CRTC1 connected to output #2 */
  268. } else {
  269. hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
  270. hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
  271. }
  272. } else if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
  273. hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
  274. hw->DACreg[POS1064_XOUTPUTCONN] = 0x09; /* output #1 enabled; CRTC2 connected to output #2 */
  275. } else if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)
  276. hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;
  277. else
  278. hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;
  279. if ((ACCESS_FBINFO(output.ph) | ACCESS_FBINFO(output.sh)) & MATROXFB_OUTPUT_CONN_PRIMARY)
  280. hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
  281. }
  282. void DAC1064_global_restore(CPMINFO const struct matrox_hw_state* hw) {
  283. outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
  284. outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
  285. if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
  286. outDAC1064(PMINFO 0x20, 0x04);
  287. outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type));
  288. if (ACCESS_FBINFO(devflags.g450dac)) {
  289. outDAC1064(PMINFO M1064_XSYNCCTRL, 0xCC); /* only matrox know... */
  290. outDAC1064(PMINFO M1064_XPWRCTRL, 0x1F); /* powerup everything */
  291. outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
  292. }
  293. }
  294. }
  295. static int DAC1064_init_1(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display *p) {
  296. DBG("DAC1064_init_1")
  297. memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
  298. if (p->type == FB_TYPE_TEXT) {
  299. hw->DACreg[POS1064_XMISCCTRL] = M1064_XMISCCTRL_DAC_6BIT;
  300. hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP
  301.      | M1064_XMULCTRL_GRAPHICS_PALETIZED;
  302. } else {
  303. switch (p->var.bits_per_pixel) {
  304. /* case 4: not supported by MGA1064 DAC */
  305. case 8:
  306. hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
  307. break;
  308. case 16:
  309. if (p->var.green.length == 5)
  310. hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
  311. else
  312. hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
  313. break;
  314. case 24:
  315. hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
  316. break;
  317. case 32:
  318. hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
  319. break;
  320. default:
  321. return 1; /* unsupported depth */
  322. }
  323. }
  324. DAC1064_global_init(PMINFO hw);
  325. hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl);
  326. hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
  327. hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
  328. hw->DACreg[POS1064_XCURADDL] = ACCESS_FBINFO(features.DAC1064.cursorimage) >> 10;
  329. hw->DACreg[POS1064_XCURADDH] = ACCESS_FBINFO(features.DAC1064.cursorimage) >> 18;
  330. return 0;
  331. }
  332. static int DAC1064_init_2(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
  333. DBG("DAC1064_init_2")
  334. if (p->var.bits_per_pixel > 16) { /* 256 entries */
  335. int i;
  336. for (i = 0; i < 256; i++) {
  337. hw->DACpal[i * 3 + 0] = i;
  338. hw->DACpal[i * 3 + 1] = i;
  339. hw->DACpal[i * 3 + 2] = i;
  340. }
  341. } else if (p->var.bits_per_pixel > 8) {
  342. if (p->var.green.length == 5) { /* 0..31, 128..159 */
  343. int i;
  344. for (i = 0; i < 32; i++) {
  345. /* with p15 == 0 */
  346. hw->DACpal[i * 3 + 0] = i << 3;
  347. hw->DACpal[i * 3 + 1] = i << 3;
  348. hw->DACpal[i * 3 + 2] = i << 3;
  349. /* with p15 == 1 */
  350. hw->DACpal[(i + 128) * 3 + 0] = i << 3;
  351. hw->DACpal[(i + 128) * 3 + 1] = i << 3;
  352. hw->DACpal[(i + 128) * 3 + 2] = i << 3;
  353. }
  354. } else {
  355. int i;
  356. for (i = 0; i < 64; i++) { /* 0..63 */
  357. hw->DACpal[i * 3 + 0] = i << 3;
  358. hw->DACpal[i * 3 + 1] = i << 2;
  359. hw->DACpal[i * 3 + 2] = i << 3;
  360. }
  361. }
  362. } else {
  363. memset(hw->DACpal, 0, 768);
  364. }
  365. return 0;
  366. }
  367. static void DAC1064_restore_1(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw) {
  368. CRITFLAGS
  369. DBG("DAC1064_restore_1")
  370. CRITBEGIN
  371. outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
  372. outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
  373. outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
  374. /*
  375.  * We must ALWAYS reprogram hardware due to broken XF4 matrox drivers...
  376.  *
  377.  * if (!oldhw || memcmp(hw->DACreg, oldhw->DACreg, sizeof(MGA1064_DAC_regs))) 
  378.  */
  379. {
  380. unsigned int i;
  381. for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
  382. if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))
  383. outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);
  384. }
  385. }
  386. DAC1064_global_restore(PMINFO hw);
  387. CRITEND
  388. };
  389. static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw, struct display* p) {
  390. #ifdef DEBUG
  391. unsigned int i;
  392. #endif
  393. DBG("DAC1064_restore_2")
  394. matrox_init_putc(PMINFO p, matroxfb_DAC1064_createcursor);
  395. #ifdef DEBUG
  396. dprintk(KERN_DEBUG "DAC1064regs ");
  397. for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
  398. dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], hw->DACreg[i]);
  399. if ((i & 0x7) == 0x7) dprintk("n" KERN_DEBUG "continuing... ");
  400. }
  401. dprintk("n" KERN_DEBUG "DAC1064clk ");
  402. for (i = 0; i < 6; i++)
  403. dprintk("C%02X=%02X ", i, hw->DACclk[i]);
  404. dprintk("n");
  405. #endif
  406. }
  407. static int m1064_compute(void* outdev, struct my_timming* m, struct matrox_hw_state* hw) {
  408. #define minfo ((struct matrox_fb_info*)outdev)
  409. DAC1064_setpclk(PMINFO hw, m->pixclock);
  410. #undef minfo
  411. return 0;
  412. }
  413. static int m1064_program(void* outdev, const struct matrox_hw_state* hw) {
  414. #define minfo ((struct matrox_fb_info*)outdev)
  415. int i;
  416. int tmout;
  417. CRITFLAGS
  418. CRITBEGIN
  419. for (i = 0; i < 3; i++)
  420. outDAC1064(PMINFO M1064_XPIXPLLCM + i, hw->DACclk[i]);
  421. for (tmout = 500000; tmout; tmout--) {
  422. if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
  423. break;
  424. udelay(10);
  425. };
  426. CRITEND
  427. if (!tmout)
  428. printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secsn");
  429. #undef minfo
  430. return 0;
  431. }
  432. static int m1064_start(void* outdev) {
  433. /* nothing */
  434. return 0;
  435. }
  436. static void m1064_incuse(void* outdev) {
  437. /* nothing yet; MODULE_INC_USE in future... */
  438. }
  439. static void m1064_decuse(void* outdev) {
  440. /* nothing yet; MODULE_DEC_USE in future... */
  441. }
  442. static int m1064_setmode(void* outdev, u_int32_t mode) {
  443. if (mode != MATROXFB_OUTPUT_MODE_MONITOR)
  444. return -EINVAL;
  445. return 0;
  446. }
  447. static struct matrox_altout m1064 = {
  448. m1064_compute,
  449. m1064_program,
  450. m1064_start,
  451. m1064_incuse,
  452. m1064_decuse,
  453. m1064_setmode
  454. };
  455. #endif /* NEED_DAC1064 */
  456. #ifdef CONFIG_FB_MATROX_MYSTIQUE
  457. static int MGA1064_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
  458. DBG("MGA1064_init")
  459. if (DAC1064_init_1(PMINFO hw, m, p)) return 1;
  460. if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1;
  461. hw->MiscOutReg = 0xCB;
  462. if (m->sync & FB_SYNC_HOR_HIGH_ACT)
  463. hw->MiscOutReg &= ~0x40;
  464. if (m->sync & FB_SYNC_VERT_HIGH_ACT)
  465. hw->MiscOutReg &= ~0x80;
  466. if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
  467. hw->CRTCEXT[3] |= 0x40;
  468. if (DAC1064_init_2(PMINFO hw, m, p)) return 1;
  469. return 0;
  470. }
  471. #endif
  472. #ifdef CONFIG_FB_MATROX_G100
  473. static int MGAG100_init(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {
  474. DBG("MGAG100_init")
  475. if (DAC1064_init_1(PMINFO hw, m, p)) return 1;
  476. hw->MXoptionReg &= ~0x2000;
  477. if (matroxfb_vgaHWinit(PMINFO hw, m, p)) return 1;
  478. hw->MiscOutReg = 0xEF;
  479. if (m->sync & FB_SYNC_HOR_HIGH_ACT)
  480. hw->MiscOutReg &= ~0x40;
  481. if (m->sync & FB_SYNC_VERT_HIGH_ACT)
  482. hw->MiscOutReg &= ~0x80;
  483. if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
  484. hw->CRTCEXT[3] |= 0x40;
  485. if (DAC1064_init_2(PMINFO hw, m, p)) return 1;
  486. return 0;
  487. }
  488. #endif /* G100 */
  489. #ifdef CONFIG_FB_MATROX_MYSTIQUE
  490. static void MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw){
  491. DBG("MGA1064_ramdac_init");
  492. /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */
  493. ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
  494. ACCESS_FBINFO(features.pll.ref_freq)  = 14318;
  495. ACCESS_FBINFO(features.pll.feed_div_min) = 100;
  496. ACCESS_FBINFO(features.pll.feed_div_max) = 127;
  497. ACCESS_FBINFO(features.pll.in_div_min)  = 1;
  498. ACCESS_FBINFO(features.pll.in_div_max)  = 31;
  499. ACCESS_FBINFO(features.pll.post_shift_max) = 3;
  500. ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL;
  501. /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
  502. DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
  503. }
  504. #endif
  505. #ifdef CONFIG_FB_MATROX_G100
  506. /* BIOS environ */
  507. static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
  508. /* G100 wants 0x10, G200 SGRAM does not care... */
  509. #if 0
  510. static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
  511. #endif
  512. static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p){
  513. int reg;
  514. int selClk;
  515. int clk;
  516. DBG("MGAG100_progPixClock")
  517. outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
  518.    M1064_XPIXCLKCTRL_PLL_UP);
  519. switch (flags & 3) {
  520. case 0: reg = M1064_XPIXPLLAM; break;
  521. case 1: reg = M1064_XPIXPLLBM; break;
  522. default: reg = M1064_XPIXPLLCM; break;
  523. }
  524. outDAC1064(PMINFO reg++, m);
  525. outDAC1064(PMINFO reg++, n);
  526. outDAC1064(PMINFO reg, p);
  527. selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
  528. /* there should be flags & 0x03 & case 0/1/else */
  529. /* and we should first select source and after that we should wait for PLL */
  530. /* and we are waiting for PLL with oscilator disabled... Is it right? */
  531. switch (flags & 0x03) {
  532. case 0x00: break;
  533. case 0x01: selClk |= 4; break;
  534. default: selClk |= 0x0C; break;
  535. }
  536. mga_outb(M_MISC_REG, selClk);
  537. for (clk = 500000; clk; clk--) {
  538. if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
  539. break;
  540. udelay(10);
  541. };
  542. if (!clk)
  543. printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual timen", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
  544. selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
  545. switch (flags & 0x0C) {
  546. case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
  547. case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
  548. default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
  549. }
  550. outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk);
  551. outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
  552. }
  553. static void MGAG100_setPixClock(CPMINFO int flags, int freq){
  554. unsigned int m, n, p;
  555. DBG("MGAG100_setPixClock")
  556. DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
  557. MGAG100_progPixClock(PMINFO flags, m, n, p);
  558. }
  559. #endif
  560. #ifdef CONFIG_FB_MATROX_MYSTIQUE
  561. static int MGA1064_preinit(WPMINFO struct matrox_hw_state* hw){
  562. static const int vxres_mystique[] = { 512,        640, 768,  800,  832,  960,
  563.      1024, 1152, 1280,      1600, 1664, 1920,
  564.      2048,    0};
  565. DBG("MGA1064_preinit")
  566. /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
  567. ACCESS_FBINFO(capable.text) = 1;
  568. ACCESS_FBINFO(capable.vxres) = vxres_mystique;
  569. ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
  570. ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
  571. ACCESS_FBINFO(primout) = &m1064;
  572. if (ACCESS_FBINFO(devflags.noinit))
  573. return 0; /* do not modify settings */
  574. hw->MXoptionReg &= 0xC0000100;
  575. hw->MXoptionReg |= 0x00094E20;
  576. if (ACCESS_FBINFO(devflags.novga))
  577. hw->MXoptionReg &= ~0x00000100;
  578. if (ACCESS_FBINFO(devflags.nobios))
  579. hw->MXoptionReg &= ~0x40000000;
  580. if (ACCESS_FBINFO(devflags.nopciretry))
  581. hw->MXoptionReg |=  0x20000000;
  582. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
  583. mga_setr(M_SEQ_INDEX, 0x01, 0x20);
  584. mga_outl(M_CTLWTST, 0x00000000);
  585. udelay(200);
  586. mga_outl(M_MACCESS, 0x00008000);
  587. udelay(100);
  588. mga_outl(M_MACCESS, 0x0000C000);
  589. return 0;
  590. }
  591. static void MGA1064_reset(WPMINFO struct matrox_hw_state* hw){
  592. DBG("MGA1064_reset");
  593. ACCESS_FBINFO(features.DAC1064.cursorimage) = ACCESS_FBINFO(video.len_usable) - 1024;
  594. if (ACCESS_FBINFO(devflags.hwcursor))
  595. ACCESS_FBINFO(video.len_usable) -= 1024;
  596. matroxfb_fastfont_init(MINFO);
  597. MGA1064_ramdac_init(PMINFO hw);
  598. }
  599. #endif
  600. #ifdef CONFIG_FB_MATROX_G100
  601. static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw){
  602. static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
  603.                                           1024, 1152, 1280,      1600, 1664, 1920,
  604.                                           2048, 0};
  605.         u_int32_t reg50;
  606. #if 0
  607. u_int32_t q;
  608. #endif
  609. DBG("MGAG100_preinit")
  610. /* there are some instabilities if in_div > 19 && vco < 61000 */
  611. if (ACCESS_FBINFO(devflags.g450dac)) {
  612. ACCESS_FBINFO(features.pll.vco_freq_min) = 130000; /* my sample: >118 */
  613. } else {
  614. ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
  615. }
  616. ACCESS_FBINFO(features.pll.ref_freq)  = 27000;
  617. ACCESS_FBINFO(features.pll.feed_div_min) = 7;
  618. ACCESS_FBINFO(features.pll.feed_div_max) = 127;
  619. ACCESS_FBINFO(features.pll.in_div_min)  = 1;
  620. ACCESS_FBINFO(features.pll.in_div_max)  = 31;
  621. ACCESS_FBINFO(features.pll.post_shift_max) = 3;
  622. ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT;
  623. /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
  624. ACCESS_FBINFO(capable.text) = 1;
  625. ACCESS_FBINFO(capable.vxres) = vxres_g100;
  626. ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
  627. ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
  628. ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
  629. ? ACCESS_FBINFO(devflags.sgram) : 1;
  630. ACCESS_FBINFO(primout) = &m1064;
  631. if (ACCESS_FBINFO(devflags.g450dac)) {
  632. /* we must do this always, BIOS does not do it for us
  633.    and accelerator dies without it */
  634. mga_outl(0x1C0C, 0);
  635. }
  636. if (ACCESS_FBINFO(devflags.noinit))
  637. return 0;
  638. hw->MXoptionReg &= 0xC0000100;
  639. hw->MXoptionReg |= 0x00000020;
  640. if (ACCESS_FBINFO(devflags.novga))
  641. hw->MXoptionReg &= ~0x00000100;
  642. if (ACCESS_FBINFO(devflags.nobios))
  643. hw->MXoptionReg &= ~0x40000000;
  644. if (ACCESS_FBINFO(devflags.nopciretry))
  645. hw->MXoptionReg |=  0x20000000;
  646. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
  647. DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
  648. if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
  649. pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
  650. reg50 &= ~0x3000;
  651. pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
  652. hw->MXoptionReg |= 0x1080;
  653. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
  654. mga_outl(M_CTLWTST, 0x00000300);
  655. /* mga_outl(M_CTLWTST, 0x03258A31); */
  656. udelay(100);
  657. mga_outb(0x1C05, 0x00);
  658. mga_outb(0x1C05, 0x80);
  659. udelay(100);
  660. mga_outb(0x1C05, 0x40);
  661. mga_outb(0x1C05, 0xC0);
  662. udelay(100);
  663. reg50 &= ~0xFF;
  664. reg50 |=  0x07;
  665. pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
  666. /* it should help with G100 */
  667. mga_outb(M_GRAPHICS_INDEX, 6);
  668. mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
  669. mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
  670. mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
  671. mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA);
  672. mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55);
  673. mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55);
  674. #if 0
  675. if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) {
  676. hw->MXoptionReg &= ~0x1000;
  677. }
  678. #endif
  679. hw->MXoptionReg |= 0x00078020;
  680. } else  if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) {
  681. pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
  682. reg50 &= ~0x3000;
  683. pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
  684. if (ACCESS_FBINFO(devflags.memtype) == -1)
  685. ACCESS_FBINFO(devflags.memtype) = 3;
  686. hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
  687. if (ACCESS_FBINFO(devflags.sgram))
  688. hw->MXoptionReg |= 0x4000;
  689. mga_outl(M_CTLWTST, 0x042450A1);
  690. mga_outl(M_MEMRDBK, 0x00000108);
  691. udelay(200);
  692. mga_outl(M_MACCESS, 0x00000000);
  693. mga_outl(M_MACCESS, 0x00008000);
  694. udelay(100);
  695. mga_outw(M_MEMRDBK, 0x00000108);
  696. hw->MXoptionReg |= 0x00078020;
  697. } else {
  698. pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
  699. reg50 &= ~0x00000100;
  700. reg50 |=  0x00000000;
  701. pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
  702. if (ACCESS_FBINFO(devflags.memtype) == -1)
  703. ACCESS_FBINFO(devflags.memtype) = 0;
  704. hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
  705. if (ACCESS_FBINFO(devflags.sgram))
  706. hw->MXoptionReg |= 0x4000;
  707. mga_outl(M_CTLWTST, 0x042450A1);
  708. mga_outl(M_MEMRDBK, 0x00000108);
  709. udelay(200);
  710. mga_outl(M_MACCESS, 0x00000000);
  711. mga_outl(M_MACCESS, 0x00008000);
  712. udelay(100);
  713. mga_outl(M_MEMRDBK, 0x00000108);
  714. hw->MXoptionReg |= 0x00040020;
  715. }
  716. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
  717. return 0;
  718. }
  719. static void MGAG100_reset(WPMINFO struct matrox_hw_state* hw){
  720. u_int8_t b;
  721. DBG("MGAG100_reset")
  722. ACCESS_FBINFO(features.DAC1064.cursorimage) = ACCESS_FBINFO(video.len_usable) - 1024;
  723. if (ACCESS_FBINFO(devflags.hwcursor))
  724. ACCESS_FBINFO(video.len_usable) -= 1024;
  725. matroxfb_fastfont_init(MINFO);
  726. {
  727. #ifdef G100_BROKEN_IBM_82351
  728. u_int32_t d;
  729. find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
  730. pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
  731. if (b == ACCESS_FBINFO(pcidev)->bus->number) {
  732. pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */
  733. pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */
  734. pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */
  735. pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */
  736. }
  737. #endif
  738. if (!ACCESS_FBINFO(devflags.noinit)) {
  739. if (x7AF4 & 8) {
  740. hw->MXoptionReg |= 0x40;
  741. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
  742. }
  743. mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
  744. }
  745. }
  746. DAC1064_setmclk(PMINFO hw, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
  747. if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
  748. if (ACCESS_FBINFO(devflags.dfp_type) == -1) {
  749. ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F);
  750. }
  751. }
  752. if (ACCESS_FBINFO(devflags.noinit))
  753. return;
  754. MGAG100_setPixClock(PMINFO 4, 25175);
  755. MGAG100_setPixClock(PMINFO 5, 28322);
  756. if (x7AF4 & 0x10) {
  757. b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
  758. outDAC1064(PMINFO M1064_XGENIODATA, b);
  759. b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
  760. outDAC1064(PMINFO M1064_XGENIOCTRL, b);
  761. }
  762. }
  763. #endif
  764. #ifdef CONFIG_FB_MATROX_MYSTIQUE
  765. static void MGA1064_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
  766. int i;
  767. CRITFLAGS
  768. DBG("MGA1064_restore")
  769. CRITBEGIN
  770. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
  771. mga_outb(M_IEN, 0x00);
  772. mga_outb(M_CACHEFLUSH, 0x00);
  773. CRITEND
  774. DAC1064_restore_1(PMINFO hw, oldhw);
  775. matroxfb_vgaHWrestore(PMINFO hw, oldhw);
  776. for (i = 0; i < 6; i++)
  777. mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
  778. DAC1064_restore_2(PMINFO hw, oldhw, p);
  779. }
  780. #endif
  781. #ifdef CONFIG_FB_MATROX_G100
  782. static void MGAG100_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_state* oldhw, struct display* p) {
  783. int i;
  784. CRITFLAGS
  785. DBG("MGAG100_restore")
  786. CRITBEGIN
  787. pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
  788. CRITEND
  789. DAC1064_restore_1(PMINFO hw, oldhw);
  790. matroxfb_vgaHWrestore(PMINFO hw, oldhw);
  791. #ifdef CONFIG_FB_MATROX_32MB
  792. if (ACCESS_FBINFO(devflags.support32MB))
  793. mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
  794. #endif
  795. for (i = 0; i < 6; i++)
  796. mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
  797. DAC1064_restore_2(PMINFO hw, oldhw, p);
  798. }
  799. #endif
  800. #ifdef CONFIG_FB_MATROX_MYSTIQUE
  801. struct matrox_switch matrox_mystique = {
  802. MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore, DAC1064_selhwcursor
  803. };
  804. EXPORT_SYMBOL(matrox_mystique);
  805. #endif
  806. #ifdef CONFIG_FB_MATROX_G100
  807. struct matrox_switch matrox_G100 = {
  808. MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore, DAC1064_selhwcursor
  809. };
  810. EXPORT_SYMBOL(matrox_G100);
  811. #endif
  812. #ifdef NEED_DAC1064
  813. EXPORT_SYMBOL(DAC1064_global_init);
  814. EXPORT_SYMBOL(DAC1064_global_restore);
  815. #endif
  816. MODULE_LICENSE("GPL");