3 * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
5 * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
7 * Portions Copyright (c) 2001 Matrox Graphics Inc.
9 * Version: 1.65 2002/08/14
11 * See matroxfb_base.c for contributors.
15 /* make checkconfig does not walk through include tree :-( */
16 #include <linux/config.h>
18 #include "matroxfb_DAC1064.h"
19 #include "matroxfb_misc.h"
20 #include "matroxfb_accel.h"
22 #include <linux/matroxfb.h>
25 #define outDAC1064 matroxfb_DAC_out
26 #define inDAC1064 matroxfb_DAC_in
28 #define DAC1064_OPT_SCLK_PCI 0x00
29 #define DAC1064_OPT_SCLK_PLL 0x01
30 #define DAC1064_OPT_SCLK_EXT 0x02
31 #define DAC1064_OPT_SCLK_MASK 0x03
32 #define DAC1064_OPT_GDIV1 0x04 /* maybe it is GDIV2 on G100 ?! */
33 #define DAC1064_OPT_GDIV3 0x00
34 #define DAC1064_OPT_MDIV1 0x08
35 #define DAC1064_OPT_MDIV2 0x00
36 #define DAC1064_OPT_RESERVED 0x10
38 static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {
44 /* only for devices older than G450 */
46 fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p);
51 else if (fvco <= 140000)
53 else if (fvco <= 180000)
60 /* they must be in POS order */
61 static const unsigned char MGA1064_DAC_regs[] = {
62 M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
63 M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
64 M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
65 M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,
66 DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,
68 M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,
70 M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
72 static const unsigned char MGA1064_DAC[] = {
73 0x00, 0x00, M1064_XCURCTRL_DIS,
74 0x00, 0x00, 0x00, /* black */
75 0xFF, 0xFF, 0xFF, /* white */
76 0xFF, 0x00, 0x00, /* red */
78 M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,
79 M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,
80 M1064_XMISCCTRL_DAC_8BIT,
81 0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,
83 0x00, 0x00, 0xFF, 0xFF};
85 static void DAC1064_setpclk(WPMINFO unsigned long fout) {
90 DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
91 ACCESS_FBINFO(hw).DACclk[0] = m;
92 ACCESS_FBINFO(hw).DACclk[1] = n;
93 ACCESS_FBINFO(hw).DACclk[2] = p;
96 static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
98 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
102 if (ACCESS_FBINFO(devflags.noinit)) {
103 /* read MCLK and give up... */
104 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
105 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
106 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
109 mx = hw->MXoptionReg | 0x00000004;
110 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
112 if (oscinfo & DAC1064_OPT_GDIV1)
114 if (oscinfo & DAC1064_OPT_MDIV1)
116 if (oscinfo & DAC1064_OPT_RESERVED)
118 if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {
119 /* select PCI clock until we have setup oscilator... */
121 unsigned int m, n, p;
123 /* powerup system PLL, select PCI clock */
125 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
127 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
129 /* !!! you must not access device if MCLK is not running !!!
130 Doing so cause immediate PCI lockup :-( Maybe they should
131 generate ABORT or I/O (parity...) error and Linux should
132 recover from this... (kill driver/process). But world is not
134 /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
135 select PLL... because of PLL can be stopped at this time) */
136 DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
137 outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m);
138 outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n);
139 outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p);
140 for (clk = 65536; clk; --clk) {
141 if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40)
145 printk(KERN_ERR "matroxfb: aiee, SYSPLL not locked\n");
149 /* select specified system clock source */
150 mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
152 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
154 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
155 hw->MXoptionReg = mx;
158 #ifdef CONFIG_FB_MATROX_G450
159 static void g450_set_plls(WPMINFO2) {
162 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
166 c2_ctl = hw->crtc2.ctl & ~0x4007; /* Clear PLL + enable for CRTC2 */
167 c2_ctl |= 0x0001; /* Enable CRTC2 */
168 hw->DACreg[POS1064_XPWRCTRL] &= ~0x02; /* Stop VIDEO PLL */
169 pixelmnp = ACCESS_FBINFO(crtc1).mnp;
170 videomnp = ACCESS_FBINFO(crtc2).mnp;
172 c2_ctl &= ~0x0001; /* Disable CRTC2 */
173 hw->DACreg[POS1064_XPWRCTRL] &= ~0x10; /* Powerdown CRTC2 */
174 } else if (ACCESS_FBINFO(crtc2).pixclock == ACCESS_FBINFO(features).pll.ref_freq) {
175 c2_ctl |= 0x4002; /* Use reference directly */
176 } else if (videomnp == pixelmnp) {
177 c2_ctl |= 0x0004; /* Use pixel PLL */
179 if (0 == ((videomnp ^ pixelmnp) & 0xFFFFFF00)) {
180 /* PIXEL and VIDEO PLL must not use same frequency. We modify N
181 of PIXEL PLL in such case because of VIDEO PLL may be source
182 of TVO clocks, and chroma subcarrier is derived from its
184 pixelmnp += 0x000100;
186 c2_ctl |= 0x0006; /* Use video PLL */
187 hw->DACreg[POS1064_XPWRCTRL] |= 0x02;
189 outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
190 matroxfb_g450_setpll_cond(PMINFO videomnp, M_VIDEO_PLL);
193 hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP;
195 hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP;
197 outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
198 matroxfb_g450_setpll_cond(PMINFO pixelmnp, M_PIXEL_PLL_C);
200 if (c2_ctl != hw->crtc2.ctl) {
201 hw->crtc2.ctl = c2_ctl;
202 mga_outl(0x3C10, c2_ctl);
205 pxc = ACCESS_FBINFO(crtc1).pixclock;
206 if (pxc == 0 || ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC2) {
207 pxc = ACCESS_FBINFO(crtc2).pixclock;
209 if (ACCESS_FBINFO(chip) == MGA_G550) {
211 hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-50 */
212 } else if (pxc < 55000) {
213 hw->DACreg[POS1064_XPANMODE] = 0x08; /* 34-62 */
214 } else if (pxc < 70000) {
215 hw->DACreg[POS1064_XPANMODE] = 0x10; /* 42-78 */
216 } else if (pxc < 85000) {
217 hw->DACreg[POS1064_XPANMODE] = 0x18; /* 62-92 */
218 } else if (pxc < 100000) {
219 hw->DACreg[POS1064_XPANMODE] = 0x20; /* 74-108 */
220 } else if (pxc < 115000) {
221 hw->DACreg[POS1064_XPANMODE] = 0x28; /* 94-122 */
222 } else if (pxc < 125000) {
223 hw->DACreg[POS1064_XPANMODE] = 0x30; /* 108-132 */
225 hw->DACreg[POS1064_XPANMODE] = 0x38; /* 120-168 */
230 hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-54 */
231 } else if (pxc < 65000) {
232 hw->DACreg[POS1064_XPANMODE] = 0x08; /* 38-70 */
233 } else if (pxc < 85000) {
234 hw->DACreg[POS1064_XPANMODE] = 0x10; /* 56-96 */
235 } else if (pxc < 105000) {
236 hw->DACreg[POS1064_XPANMODE] = 0x18; /* 80-114 */
237 } else if (pxc < 135000) {
238 hw->DACreg[POS1064_XPANMODE] = 0x20; /* 102-144 */
239 } else if (pxc < 160000) {
240 hw->DACreg[POS1064_XPANMODE] = 0x28; /* 132-166 */
241 } else if (pxc < 175000) {
242 hw->DACreg[POS1064_XPANMODE] = 0x30; /* 154-182 */
244 hw->DACreg[POS1064_XPANMODE] = 0x38; /* 170-204 */
250 void DAC1064_global_init(WPMINFO2) {
251 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
253 hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
254 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
255 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
256 #ifdef CONFIG_FB_MATROX_G450
257 if (ACCESS_FBINFO(devflags.g450dac)) {
258 hw->DACreg[POS1064_XPWRCTRL] = 0x1F; /* powerup everything */
259 hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */
260 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
261 switch (ACCESS_FBINFO(outputs[0]).src) {
262 case MATROXFB_SRC_CRTC1:
263 case MATROXFB_SRC_CRTC2:
264 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01; /* enable output; CRTC1/2 selection is in CRTC2 ctl */
266 case MATROXFB_SRC_NONE:
267 hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN;
270 switch (ACCESS_FBINFO(outputs[1]).src) {
271 case MATROXFB_SRC_CRTC1:
272 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04;
274 case MATROXFB_SRC_CRTC2:
275 if (ACCESS_FBINFO(outputs[1]).mode == MATROXFB_OUTPUT_MODE_MONITOR) {
276 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08;
278 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C;
281 case MATROXFB_SRC_NONE:
282 hw->DACreg[POS1064_XPWRCTRL] &= ~0x01; /* Poweroff DAC2 */
285 switch (ACCESS_FBINFO(outputs[2]).src) {
286 case MATROXFB_SRC_CRTC1:
287 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20;
289 case MATROXFB_SRC_CRTC2:
290 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x40;
292 case MATROXFB_SRC_NONE:
294 /* HELP! If we boot without DFP connected to DVI, we can
295 poweroff TMDS. But if we boot with DFP connected,
296 TMDS generated clocks are used instead of ALL pixclocks
297 available... If someone knows which register
298 handles it, please reveal this secret to me... */
299 hw->DACreg[POS1064_XPWRCTRL] &= ~0x04; /* Poweroff TMDS */
303 /* Now set timming related variables... */
304 g450_set_plls(PMINFO2);
308 if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) {
309 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
310 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
311 } else if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) {
312 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
313 } else if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1)
314 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;
316 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;
318 if (ACCESS_FBINFO(outputs[0]).src != MATROXFB_SRC_NONE)
319 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
323 void DAC1064_global_restore(WPMINFO2) {
324 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
326 outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
327 outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
328 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
329 outDAC1064(PMINFO 0x20, 0x04);
330 outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type));
331 if (ACCESS_FBINFO(devflags.g450dac)) {
332 outDAC1064(PMINFO M1064_XSYNCCTRL, 0xCC);
333 outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
334 outDAC1064(PMINFO M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]);
335 outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
340 static int DAC1064_init_1(WPMINFO struct my_timming* m) {
341 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
345 memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
346 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) {
347 /* case 4: not supported by MGA1064 DAC */
349 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
352 if (ACCESS_FBINFO(fbcon).var.green.length == 5)
353 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
355 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
358 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
361 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
364 return 1; /* unsupported depth */
366 hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl);
367 hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
368 hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
369 hw->DACreg[POS1064_XCURADDL] = 0;
370 hw->DACreg[POS1064_XCURADDH] = 0;
372 DAC1064_global_init(PMINFO2);
376 static int DAC1064_init_2(WPMINFO struct my_timming* m) {
377 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
381 if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 16) { /* 256 entries */
384 for (i = 0; i < 256; i++) {
385 hw->DACpal[i * 3 + 0] = i;
386 hw->DACpal[i * 3 + 1] = i;
387 hw->DACpal[i * 3 + 2] = i;
389 } else if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 8) {
390 if (ACCESS_FBINFO(fbcon).var.green.length == 5) { /* 0..31, 128..159 */
393 for (i = 0; i < 32; i++) {
395 hw->DACpal[i * 3 + 0] = i << 3;
396 hw->DACpal[i * 3 + 1] = i << 3;
397 hw->DACpal[i * 3 + 2] = i << 3;
399 hw->DACpal[(i + 128) * 3 + 0] = i << 3;
400 hw->DACpal[(i + 128) * 3 + 1] = i << 3;
401 hw->DACpal[(i + 128) * 3 + 2] = i << 3;
406 for (i = 0; i < 64; i++) { /* 0..63 */
407 hw->DACpal[i * 3 + 0] = i << 3;
408 hw->DACpal[i * 3 + 1] = i << 2;
409 hw->DACpal[i * 3 + 2] = i << 3;
413 memset(hw->DACpal, 0, 768);
418 static void DAC1064_restore_1(WPMINFO2) {
419 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
427 if ((inDAC1064(PMINFO DAC1064_XSYSPLLM) != hw->DACclk[3]) ||
428 (inDAC1064(PMINFO DAC1064_XSYSPLLN) != hw->DACclk[4]) ||
429 (inDAC1064(PMINFO DAC1064_XSYSPLLP) != hw->DACclk[5])) {
430 outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
431 outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
432 outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
437 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
438 if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))
439 outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);
443 DAC1064_global_restore(PMINFO2);
448 static void DAC1064_restore_2(WPMINFO2) {
456 dprintk(KERN_DEBUG "DAC1064regs ");
457 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
458 dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]);
459 if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
461 dprintk("\n" KERN_DEBUG "DAC1064clk ");
462 for (i = 0; i < 6; i++)
463 dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]);
468 static int m1064_compute(void* out, struct my_timming* m) {
469 #define minfo ((struct matrox_fb_info*)out)
475 DAC1064_setpclk(PMINFO m->pixclock);
479 for (i = 0; i < 3; i++)
480 outDAC1064(PMINFO M1064_XPIXPLLCM + i, ACCESS_FBINFO(hw).DACclk[i]);
481 for (tmout = 500000; tmout; tmout--) {
482 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
490 printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
496 static struct matrox_altout m1064 = {
497 .name = "Primary output",
498 .compute = m1064_compute,
501 #ifdef CONFIG_FB_MATROX_G450
502 static int g450_compute(void* out, struct my_timming* m) {
503 #define minfo ((struct matrox_fb_info*)out)
505 m->mnp = matroxfb_g450_setclk(PMINFO m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
507 m->pixclock = g450_mnp2f(PMINFO m->mnp);
514 static struct matrox_altout g450out = {
515 .name = "Primary output",
516 .compute = g450_compute,
520 #endif /* NEED_DAC1064 */
522 #ifdef CONFIG_FB_MATROX_MYSTIQUE
523 static int MGA1064_init(WPMINFO struct my_timming* m) {
524 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
528 if (DAC1064_init_1(PMINFO m)) return 1;
529 if (matroxfb_vgaHWinit(PMINFO m)) return 1;
531 hw->MiscOutReg = 0xCB;
532 if (m->sync & FB_SYNC_HOR_HIGH_ACT)
533 hw->MiscOutReg &= ~0x40;
534 if (m->sync & FB_SYNC_VERT_HIGH_ACT)
535 hw->MiscOutReg &= ~0x80;
536 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
537 hw->CRTCEXT[3] |= 0x40;
539 if (DAC1064_init_2(PMINFO m)) return 1;
544 #ifdef CONFIG_FB_MATROX_G100
545 static int MGAG100_init(WPMINFO struct my_timming* m) {
546 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
550 if (DAC1064_init_1(PMINFO m)) return 1;
551 hw->MXoptionReg &= ~0x2000;
552 if (matroxfb_vgaHWinit(PMINFO m)) return 1;
554 hw->MiscOutReg = 0xEF;
555 if (m->sync & FB_SYNC_HOR_HIGH_ACT)
556 hw->MiscOutReg &= ~0x40;
557 if (m->sync & FB_SYNC_VERT_HIGH_ACT)
558 hw->MiscOutReg &= ~0x80;
559 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
560 hw->CRTCEXT[3] |= 0x40;
562 if (DAC1064_init_2(PMINFO m)) return 1;
567 #ifdef CONFIG_FB_MATROX_MYSTIQUE
568 static void MGA1064_ramdac_init(WPMINFO2) {
572 /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */
573 ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
574 ACCESS_FBINFO(features.pll.ref_freq) = 14318;
575 ACCESS_FBINFO(features.pll.feed_div_min) = 100;
576 ACCESS_FBINFO(features.pll.feed_div_max) = 127;
577 ACCESS_FBINFO(features.pll.in_div_min) = 1;
578 ACCESS_FBINFO(features.pll.in_div_max) = 31;
579 ACCESS_FBINFO(features.pll.post_shift_max) = 3;
580 ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL;
581 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
582 DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
586 #ifdef CONFIG_FB_MATROX_G100
588 static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
589 /* G100 wants 0x10, G200 SGRAM does not care... */
591 static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
594 static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p) {
601 outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
602 M1064_XPIXCLKCTRL_PLL_UP);
604 case 0: reg = M1064_XPIXPLLAM; break;
605 case 1: reg = M1064_XPIXPLLBM; break;
606 default: reg = M1064_XPIXPLLCM; break;
608 outDAC1064(PMINFO reg++, m);
609 outDAC1064(PMINFO reg++, n);
610 outDAC1064(PMINFO reg, p);
611 selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
612 /* there should be flags & 0x03 & case 0/1/else */
613 /* and we should first select source and after that we should wait for PLL */
614 /* and we are waiting for PLL with oscilator disabled... Is it right? */
615 switch (flags & 0x03) {
617 case 0x01: selClk |= 4; break;
618 default: selClk |= 0x0C; break;
620 mga_outb(M_MISC_REG, selClk);
621 for (clk = 500000; clk; clk--) {
622 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
627 printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
628 selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
629 switch (flags & 0x0C) {
630 case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
631 case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
632 default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
634 outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk);
635 outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
638 static void MGAG100_setPixClock(CPMINFO int flags, int freq) {
639 unsigned int m, n, p;
643 DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
644 MGAG100_progPixClock(PMINFO flags, m, n, p);
648 #ifdef CONFIG_FB_MATROX_MYSTIQUE
649 static int MGA1064_preinit(WPMINFO2) {
650 static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960,
651 1024, 1152, 1280, 1600, 1664, 1920,
653 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
657 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
658 ACCESS_FBINFO(capable.text) = 1;
659 ACCESS_FBINFO(capable.vxres) = vxres_mystique;
660 ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
662 ACCESS_FBINFO(outputs[0]).output = &m1064;
663 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
664 ACCESS_FBINFO(outputs[0]).data = MINFO;
665 ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
667 if (ACCESS_FBINFO(devflags.noinit))
668 return 0; /* do not modify settings */
669 hw->MXoptionReg &= 0xC0000100;
670 hw->MXoptionReg |= 0x00094E20;
671 if (ACCESS_FBINFO(devflags.novga))
672 hw->MXoptionReg &= ~0x00000100;
673 if (ACCESS_FBINFO(devflags.nobios))
674 hw->MXoptionReg &= ~0x40000000;
675 if (ACCESS_FBINFO(devflags.nopciretry))
676 hw->MXoptionReg |= 0x20000000;
677 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
678 mga_setr(M_SEQ_INDEX, 0x01, 0x20);
679 mga_outl(M_CTLWTST, 0x00000000);
681 mga_outl(M_MACCESS, 0x00008000);
683 mga_outl(M_MACCESS, 0x0000C000);
687 static void MGA1064_reset(WPMINFO2) {
691 MGA1064_ramdac_init(PMINFO2);
695 #ifdef CONFIG_FB_MATROX_G100
696 #ifdef CONFIG_FB_MATROX_G450
697 static void g450_mclk_init(WPMINFO2) {
698 /* switch all clocks to PCI source */
699 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
700 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3 & ~0x00300C03);
701 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
703 if (((ACCESS_FBINFO(values).reg.opt3 & 0x000003) == 0x000003) ||
704 ((ACCESS_FBINFO(values).reg.opt3 & 0x000C00) == 0x000C00) ||
705 ((ACCESS_FBINFO(values).reg.opt3 & 0x300000) == 0x300000)) {
706 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.video), M_VIDEO_PLL);
711 matroxfb_DAC_lock_irqsave(flags);
712 pwr = inDAC1064(PMINFO M1064_XPWRCTRL) & ~0x02;
713 outDAC1064(PMINFO M1064_XPWRCTRL, pwr);
714 matroxfb_DAC_unlock_irqrestore(flags);
716 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.system), M_SYSTEM_PLL);
718 /* switch clocks to their real PLL source(s) */
719 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
720 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3);
721 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
725 static void g450_memory_init(WPMINFO2) {
726 /* disable memory refresh */
727 ACCESS_FBINFO(hw).MXoptionReg &= ~0x001F8000;
728 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
730 /* set memory interface parameters */
731 ACCESS_FBINFO(hw).MXoptionReg &= ~0x00207E00;
732 ACCESS_FBINFO(hw).MXoptionReg |= 0x00207E00 & ACCESS_FBINFO(values).reg.opt;
733 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
734 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ACCESS_FBINFO(values).reg.opt2);
736 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
738 /* first set up memory interface with disabled memory interface clocks */
739 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc & ~0x80000000U);
740 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
741 mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess);
742 /* start memory clocks */
743 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc | 0x80000000U);
747 if (ACCESS_FBINFO(values).memory.ddr && (!ACCESS_FBINFO(values).memory.emrswen || !ACCESS_FBINFO(values).memory.dll)) {
748 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk & ~0x1000);
750 mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess | 0x8000);
754 ACCESS_FBINFO(hw).MXoptionReg |= 0x001F8000 & ACCESS_FBINFO(values).reg.opt;
755 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
757 /* value is written to memory chips only if old != new */
758 mga_outl(M_PLNWT, 0);
759 mga_outl(M_PLNWT, ~0);
761 if (ACCESS_FBINFO(values).reg.mctlwtst != ACCESS_FBINFO(values).reg.mctlwtst_core) {
762 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst_core);
767 static void g450_preinit(WPMINFO2) {
772 /* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */
773 ACCESS_FBINFO(hw).MXoptionReg &= 0xC0000100;
774 ACCESS_FBINFO(hw).MXoptionReg |= 0x00000020;
775 if (ACCESS_FBINFO(devflags.novga))
776 ACCESS_FBINFO(hw).MXoptionReg &= ~0x00000100;
777 if (ACCESS_FBINFO(devflags.nobios))
778 ACCESS_FBINFO(hw).MXoptionReg &= ~0x40000000;
779 if (ACCESS_FBINFO(devflags.nopciretry))
780 ACCESS_FBINFO(hw).MXoptionReg |= 0x20000000;
781 ACCESS_FBINFO(hw).MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x03400040;
782 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
784 /* Init system clocks */
787 c2ctl = mga_inl(M_C2CTL);
788 mga_outl(M_C2CTL, c2ctl & ~1);
790 curctl = inDAC1064(PMINFO M1064_XCURCTRL);
791 outDAC1064(PMINFO M1064_XCURCTRL, 0);
793 c1ctl = mga_readr(M_SEQ_INDEX, 1);
794 mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20);
796 g450_mclk_init(PMINFO2);
797 g450_memory_init(PMINFO2);
799 /* set legacy VGA clock sources for DOSEmu or VMware... */
800 matroxfb_g450_setclk(PMINFO 25175, M_PIXEL_PLL_A);
801 matroxfb_g450_setclk(PMINFO 28322, M_PIXEL_PLL_B);
804 mga_setr(M_SEQ_INDEX, 1, c1ctl);
807 outDAC1064(PMINFO M1064_XCURCTRL, curctl);
810 mga_outl(M_C2CTL, c2ctl);
815 static inline void g450_preinit(WPMINFO2) {
819 static int MGAG100_preinit(WPMINFO2) {
820 static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960,
821 1024, 1152, 1280, 1600, 1664, 1920,
823 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
832 /* there are some instabilities if in_div > 19 && vco < 61000 */
833 if (ACCESS_FBINFO(devflags.g450dac)) {
834 ACCESS_FBINFO(features.pll.vco_freq_min) = 130000; /* my sample: >118 */
836 ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
838 if (!ACCESS_FBINFO(features.pll.ref_freq)) {
839 ACCESS_FBINFO(features.pll.ref_freq) = 27000;
841 ACCESS_FBINFO(features.pll.feed_div_min) = 7;
842 ACCESS_FBINFO(features.pll.feed_div_max) = 127;
843 ACCESS_FBINFO(features.pll.in_div_min) = 1;
844 ACCESS_FBINFO(features.pll.in_div_max) = 31;
845 ACCESS_FBINFO(features.pll.post_shift_max) = 3;
846 ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT;
847 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
848 ACCESS_FBINFO(capable.text) = 1;
849 ACCESS_FBINFO(capable.vxres) = vxres_g100;
850 ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
851 ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
852 ? ACCESS_FBINFO(devflags.sgram) : 1;
854 #ifdef CONFIG_FB_MATROX_G450
855 if (ACCESS_FBINFO(devflags.g450dac)) {
856 ACCESS_FBINFO(outputs[0]).output = &g450out;
860 ACCESS_FBINFO(outputs[0]).output = &m1064;
862 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
863 ACCESS_FBINFO(outputs[0]).data = MINFO;
864 ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
866 if (ACCESS_FBINFO(devflags.g450dac)) {
867 /* we must do this always, BIOS does not do it for us
868 and accelerator dies without it */
871 if (ACCESS_FBINFO(devflags.noinit))
873 if (ACCESS_FBINFO(devflags.g450dac)) {
874 g450_preinit(PMINFO2);
877 hw->MXoptionReg &= 0xC0000100;
878 hw->MXoptionReg |= 0x00000020;
879 if (ACCESS_FBINFO(devflags.novga))
880 hw->MXoptionReg &= ~0x00000100;
881 if (ACCESS_FBINFO(devflags.nobios))
882 hw->MXoptionReg &= ~0x40000000;
883 if (ACCESS_FBINFO(devflags.nopciretry))
884 hw->MXoptionReg |= 0x20000000;
885 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
886 DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
888 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
889 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50);
891 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
893 hw->MXoptionReg |= 0x1080;
894 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
895 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
897 mga_outb(0x1C05, 0x00);
898 mga_outb(0x1C05, 0x80);
900 mga_outb(0x1C05, 0x40);
901 mga_outb(0x1C05, 0xC0);
905 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
906 /* it should help with G100 */
907 mga_outb(M_GRAPHICS_INDEX, 6);
908 mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
909 mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
910 mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
911 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA);
912 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55);
913 mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55);
915 if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) {
916 hw->MXoptionReg &= ~0x1000;
919 hw->MXoptionReg |= 0x00078020;
920 } else if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) {
921 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50);
923 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
925 if (ACCESS_FBINFO(devflags.memtype) == -1)
926 hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
928 hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
929 if (ACCESS_FBINFO(devflags.sgram))
930 hw->MXoptionReg |= 0x4000;
931 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
932 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
934 mga_outl(M_MACCESS, 0x00000000);
935 mga_outl(M_MACCESS, 0x00008000);
937 mga_outw(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
938 hw->MXoptionReg |= 0x00078020;
940 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50);
941 reg50 &= ~0x00000100;
943 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
945 if (ACCESS_FBINFO(devflags.memtype) == -1)
946 hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
948 hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
949 if (ACCESS_FBINFO(devflags.sgram))
950 hw->MXoptionReg |= 0x4000;
951 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
952 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
954 mga_outl(M_MACCESS, 0x00000000);
955 mga_outl(M_MACCESS, 0x00008000);
957 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
958 hw->MXoptionReg |= 0x00040020;
960 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
964 static void MGAG100_reset(WPMINFO2) {
966 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
971 #ifdef G100_BROKEN_IBM_82351
974 find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
975 pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
976 if (b == ACCESS_FBINFO(pcidev)->bus->number) {
977 pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */
978 pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */
979 pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */
980 pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */
983 if (!ACCESS_FBINFO(devflags.noinit)) {
985 hw->MXoptionReg |= 0x40; /* FIXME... */
986 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
988 mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
991 if (ACCESS_FBINFO(devflags.g450dac)) {
992 /* either leave MCLK as is... or they were set in preinit */
993 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
994 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
995 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
997 DAC1064_setmclk(PMINFO DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
999 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
1000 if (ACCESS_FBINFO(devflags.dfp_type) == -1) {
1001 ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F);
1004 if (ACCESS_FBINFO(devflags.noinit))
1006 if (ACCESS_FBINFO(devflags.g450dac)) {
1008 MGAG100_setPixClock(PMINFO 4, 25175);
1009 MGAG100_setPixClock(PMINFO 5, 28322);
1011 b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
1012 outDAC1064(PMINFO M1064_XGENIODATA, b);
1013 b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
1014 outDAC1064(PMINFO M1064_XGENIOCTRL, b);
1020 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1021 static void MGA1064_restore(WPMINFO2) {
1023 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
1031 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
1032 mga_outb(M_IEN, 0x00);
1033 mga_outb(M_CACHEFLUSH, 0x00);
1037 DAC1064_restore_1(PMINFO2);
1038 matroxfb_vgaHWrestore(PMINFO2);
1039 ACCESS_FBINFO(crtc1.panpos) = -1;
1040 for (i = 0; i < 6; i++)
1041 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1042 DAC1064_restore_2(PMINFO2);
1046 #ifdef CONFIG_FB_MATROX_G100
1047 static void MGAG100_restore(WPMINFO2) {
1049 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
1057 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
1060 DAC1064_restore_1(PMINFO2);
1061 matroxfb_vgaHWrestore(PMINFO2);
1062 #ifdef CONFIG_FB_MATROX_32MB
1063 if (ACCESS_FBINFO(devflags.support32MB))
1064 mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
1066 ACCESS_FBINFO(crtc1.panpos) = -1;
1067 for (i = 0; i < 6; i++)
1068 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1069 DAC1064_restore_2(PMINFO2);
1073 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1074 struct matrox_switch matrox_mystique = {
1075 MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore,
1077 EXPORT_SYMBOL(matrox_mystique);
1080 #ifdef CONFIG_FB_MATROX_G100
1081 struct matrox_switch matrox_G100 = {
1082 MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore,
1084 EXPORT_SYMBOL(matrox_G100);
1088 EXPORT_SYMBOL(DAC1064_global_init);
1089 EXPORT_SYMBOL(DAC1064_global_restore);
1091 MODULE_LICENSE("GPL");