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.
16 #include "matroxfb_DAC1064.h"
17 #include "matroxfb_misc.h"
18 #include "matroxfb_accel.h"
20 #include <linux/matroxfb.h>
23 #define outDAC1064 matroxfb_DAC_out
24 #define inDAC1064 matroxfb_DAC_in
26 #define DAC1064_OPT_SCLK_PCI 0x00
27 #define DAC1064_OPT_SCLK_PLL 0x01
28 #define DAC1064_OPT_SCLK_EXT 0x02
29 #define DAC1064_OPT_SCLK_MASK 0x03
30 #define DAC1064_OPT_GDIV1 0x04 /* maybe it is GDIV2 on G100 ?! */
31 #define DAC1064_OPT_GDIV3 0x00
32 #define DAC1064_OPT_MDIV1 0x08
33 #define DAC1064_OPT_MDIV2 0x00
34 #define DAC1064_OPT_RESERVED 0x10
36 static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {
42 /* only for devices older than G450 */
44 fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p);
49 else if (fvco <= 140000)
51 else if (fvco <= 180000)
58 /* they must be in POS order */
59 static const unsigned char MGA1064_DAC_regs[] = {
60 M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
61 M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
62 M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
63 M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,
64 DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,
66 M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,
68 M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
70 static const unsigned char MGA1064_DAC[] = {
71 0x00, 0x00, M1064_XCURCTRL_DIS,
72 0x00, 0x00, 0x00, /* black */
73 0xFF, 0xFF, 0xFF, /* white */
74 0xFF, 0x00, 0x00, /* red */
76 M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,
77 M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,
78 M1064_XMISCCTRL_DAC_8BIT,
79 0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,
81 0x00, 0x00, 0xFF, 0xFF};
83 static void DAC1064_setpclk(WPMINFO unsigned long fout) {
88 DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
89 ACCESS_FBINFO(hw).DACclk[0] = m;
90 ACCESS_FBINFO(hw).DACclk[1] = n;
91 ACCESS_FBINFO(hw).DACclk[2] = p;
94 static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
96 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
100 if (ACCESS_FBINFO(devflags.noinit)) {
101 /* read MCLK and give up... */
102 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
103 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
104 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
107 mx = hw->MXoptionReg | 0x00000004;
108 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
110 if (oscinfo & DAC1064_OPT_GDIV1)
112 if (oscinfo & DAC1064_OPT_MDIV1)
114 if (oscinfo & DAC1064_OPT_RESERVED)
116 if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {
117 /* select PCI clock until we have setup oscilator... */
119 unsigned int m, n, p;
121 /* powerup system PLL, select PCI clock */
123 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
125 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
127 /* !!! you must not access device if MCLK is not running !!!
128 Doing so cause immediate PCI lockup :-( Maybe they should
129 generate ABORT or I/O (parity...) error and Linux should
130 recover from this... (kill driver/process). But world is not
132 /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
133 select PLL... because of PLL can be stopped at this time) */
134 DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
135 outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m);
136 outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n);
137 outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p);
138 for (clk = 65536; clk; --clk) {
139 if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40)
143 printk(KERN_ERR "matroxfb: aiee, SYSPLL not locked\n");
147 /* select specified system clock source */
148 mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
150 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
152 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
153 hw->MXoptionReg = mx;
156 #ifdef CONFIG_FB_MATROX_G
157 static void g450_set_plls(WPMINFO2) {
160 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
164 c2_ctl = hw->crtc2.ctl & ~0x4007; /* Clear PLL + enable for CRTC2 */
165 c2_ctl |= 0x0001; /* Enable CRTC2 */
166 hw->DACreg[POS1064_XPWRCTRL] &= ~0x02; /* Stop VIDEO PLL */
167 pixelmnp = ACCESS_FBINFO(crtc1).mnp;
168 videomnp = ACCESS_FBINFO(crtc2).mnp;
170 c2_ctl &= ~0x0001; /* Disable CRTC2 */
171 hw->DACreg[POS1064_XPWRCTRL] &= ~0x10; /* Powerdown CRTC2 */
172 } else if (ACCESS_FBINFO(crtc2).pixclock == ACCESS_FBINFO(features).pll.ref_freq) {
173 c2_ctl |= 0x4002; /* Use reference directly */
174 } else if (videomnp == pixelmnp) {
175 c2_ctl |= 0x0004; /* Use pixel PLL */
177 if (0 == ((videomnp ^ pixelmnp) & 0xFFFFFF00)) {
178 /* PIXEL and VIDEO PLL must not use same frequency. We modify N
179 of PIXEL PLL in such case because of VIDEO PLL may be source
180 of TVO clocks, and chroma subcarrier is derived from its
182 pixelmnp += 0x000100;
184 c2_ctl |= 0x0006; /* Use video PLL */
185 hw->DACreg[POS1064_XPWRCTRL] |= 0x02;
187 outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
188 matroxfb_g450_setpll_cond(PMINFO videomnp, M_VIDEO_PLL);
191 hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP;
193 hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP;
195 outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
196 matroxfb_g450_setpll_cond(PMINFO pixelmnp, M_PIXEL_PLL_C);
198 if (c2_ctl != hw->crtc2.ctl) {
199 hw->crtc2.ctl = c2_ctl;
200 mga_outl(0x3C10, c2_ctl);
203 pxc = ACCESS_FBINFO(crtc1).pixclock;
204 if (pxc == 0 || ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC2) {
205 pxc = ACCESS_FBINFO(crtc2).pixclock;
207 if (ACCESS_FBINFO(chip) == MGA_G550) {
209 hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-50 */
210 } else if (pxc < 55000) {
211 hw->DACreg[POS1064_XPANMODE] = 0x08; /* 34-62 */
212 } else if (pxc < 70000) {
213 hw->DACreg[POS1064_XPANMODE] = 0x10; /* 42-78 */
214 } else if (pxc < 85000) {
215 hw->DACreg[POS1064_XPANMODE] = 0x18; /* 62-92 */
216 } else if (pxc < 100000) {
217 hw->DACreg[POS1064_XPANMODE] = 0x20; /* 74-108 */
218 } else if (pxc < 115000) {
219 hw->DACreg[POS1064_XPANMODE] = 0x28; /* 94-122 */
220 } else if (pxc < 125000) {
221 hw->DACreg[POS1064_XPANMODE] = 0x30; /* 108-132 */
223 hw->DACreg[POS1064_XPANMODE] = 0x38; /* 120-168 */
228 hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-54 */
229 } else if (pxc < 65000) {
230 hw->DACreg[POS1064_XPANMODE] = 0x08; /* 38-70 */
231 } else if (pxc < 85000) {
232 hw->DACreg[POS1064_XPANMODE] = 0x10; /* 56-96 */
233 } else if (pxc < 105000) {
234 hw->DACreg[POS1064_XPANMODE] = 0x18; /* 80-114 */
235 } else if (pxc < 135000) {
236 hw->DACreg[POS1064_XPANMODE] = 0x20; /* 102-144 */
237 } else if (pxc < 160000) {
238 hw->DACreg[POS1064_XPANMODE] = 0x28; /* 132-166 */
239 } else if (pxc < 175000) {
240 hw->DACreg[POS1064_XPANMODE] = 0x30; /* 154-182 */
242 hw->DACreg[POS1064_XPANMODE] = 0x38; /* 170-204 */
248 void DAC1064_global_init(WPMINFO2) {
249 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
251 hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
252 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
253 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
254 #ifdef CONFIG_FB_MATROX_G
255 if (ACCESS_FBINFO(devflags.g450dac)) {
256 hw->DACreg[POS1064_XPWRCTRL] = 0x1F; /* powerup everything */
257 hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */
258 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
259 switch (ACCESS_FBINFO(outputs[0]).src) {
260 case MATROXFB_SRC_CRTC1:
261 case MATROXFB_SRC_CRTC2:
262 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01; /* enable output; CRTC1/2 selection is in CRTC2 ctl */
264 case MATROXFB_SRC_NONE:
265 hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN;
268 switch (ACCESS_FBINFO(outputs[1]).src) {
269 case MATROXFB_SRC_CRTC1:
270 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04;
272 case MATROXFB_SRC_CRTC2:
273 if (ACCESS_FBINFO(outputs[1]).mode == MATROXFB_OUTPUT_MODE_MONITOR) {
274 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08;
276 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C;
279 case MATROXFB_SRC_NONE:
280 hw->DACreg[POS1064_XPWRCTRL] &= ~0x01; /* Poweroff DAC2 */
283 switch (ACCESS_FBINFO(outputs[2]).src) {
284 case MATROXFB_SRC_CRTC1:
285 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20;
287 case MATROXFB_SRC_CRTC2:
288 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x40;
290 case MATROXFB_SRC_NONE:
292 /* HELP! If we boot without DFP connected to DVI, we can
293 poweroff TMDS. But if we boot with DFP connected,
294 TMDS generated clocks are used instead of ALL pixclocks
295 available... If someone knows which register
296 handles it, please reveal this secret to me... */
297 hw->DACreg[POS1064_XPWRCTRL] &= ~0x04; /* Poweroff TMDS */
301 /* Now set timming related variables... */
302 g450_set_plls(PMINFO2);
306 if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) {
307 hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
308 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
309 } else if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) {
310 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
311 } else if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1)
312 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;
314 hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;
316 if (ACCESS_FBINFO(outputs[0]).src != MATROXFB_SRC_NONE)
317 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
321 void DAC1064_global_restore(WPMINFO2) {
322 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
324 outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
325 outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
326 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
327 outDAC1064(PMINFO 0x20, 0x04);
328 outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type));
329 if (ACCESS_FBINFO(devflags.g450dac)) {
330 outDAC1064(PMINFO M1064_XSYNCCTRL, 0xCC);
331 outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
332 outDAC1064(PMINFO M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]);
333 outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
338 static int DAC1064_init_1(WPMINFO struct my_timming* m) {
339 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
343 memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
344 switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) {
345 /* case 4: not supported by MGA1064 DAC */
347 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
350 if (ACCESS_FBINFO(fbcon).var.green.length == 5)
351 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
353 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
356 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
359 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
362 return 1; /* unsupported depth */
364 hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl);
365 hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
366 hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
367 hw->DACreg[POS1064_XCURADDL] = 0;
368 hw->DACreg[POS1064_XCURADDH] = 0;
370 DAC1064_global_init(PMINFO2);
374 static int DAC1064_init_2(WPMINFO struct my_timming* m) {
375 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
379 if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 16) { /* 256 entries */
382 for (i = 0; i < 256; i++) {
383 hw->DACpal[i * 3 + 0] = i;
384 hw->DACpal[i * 3 + 1] = i;
385 hw->DACpal[i * 3 + 2] = i;
387 } else if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 8) {
388 if (ACCESS_FBINFO(fbcon).var.green.length == 5) { /* 0..31, 128..159 */
391 for (i = 0; i < 32; i++) {
393 hw->DACpal[i * 3 + 0] = i << 3;
394 hw->DACpal[i * 3 + 1] = i << 3;
395 hw->DACpal[i * 3 + 2] = i << 3;
397 hw->DACpal[(i + 128) * 3 + 0] = i << 3;
398 hw->DACpal[(i + 128) * 3 + 1] = i << 3;
399 hw->DACpal[(i + 128) * 3 + 2] = i << 3;
404 for (i = 0; i < 64; i++) { /* 0..63 */
405 hw->DACpal[i * 3 + 0] = i << 3;
406 hw->DACpal[i * 3 + 1] = i << 2;
407 hw->DACpal[i * 3 + 2] = i << 3;
411 memset(hw->DACpal, 0, 768);
416 static void DAC1064_restore_1(WPMINFO2) {
417 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
425 if ((inDAC1064(PMINFO DAC1064_XSYSPLLM) != hw->DACclk[3]) ||
426 (inDAC1064(PMINFO DAC1064_XSYSPLLN) != hw->DACclk[4]) ||
427 (inDAC1064(PMINFO DAC1064_XSYSPLLP) != hw->DACclk[5])) {
428 outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
429 outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
430 outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
435 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
436 if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))
437 outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);
441 DAC1064_global_restore(PMINFO2);
446 static void DAC1064_restore_2(WPMINFO2) {
454 dprintk(KERN_DEBUG "DAC1064regs ");
455 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
456 dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]);
457 if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
459 dprintk("\n" KERN_DEBUG "DAC1064clk ");
460 for (i = 0; i < 6; i++)
461 dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]);
466 static int m1064_compute(void* out, struct my_timming* m) {
467 #define minfo ((struct matrox_fb_info*)out)
473 DAC1064_setpclk(PMINFO m->pixclock);
477 for (i = 0; i < 3; i++)
478 outDAC1064(PMINFO M1064_XPIXPLLCM + i, ACCESS_FBINFO(hw).DACclk[i]);
479 for (tmout = 500000; tmout; tmout--) {
480 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
488 printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
494 static struct matrox_altout m1064 = {
495 .name = "Primary output",
496 .compute = m1064_compute,
499 #ifdef CONFIG_FB_MATROX_G
500 static int g450_compute(void* out, struct my_timming* m) {
501 #define minfo ((struct matrox_fb_info*)out)
503 m->mnp = matroxfb_g450_setclk(PMINFO m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
505 m->pixclock = g450_mnp2f(PMINFO m->mnp);
512 static struct matrox_altout g450out = {
513 .name = "Primary output",
514 .compute = g450_compute,
518 #endif /* NEED_DAC1064 */
520 #ifdef CONFIG_FB_MATROX_MYSTIQUE
521 static int MGA1064_init(WPMINFO struct my_timming* m) {
522 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
526 if (DAC1064_init_1(PMINFO m)) return 1;
527 if (matroxfb_vgaHWinit(PMINFO m)) return 1;
529 hw->MiscOutReg = 0xCB;
530 if (m->sync & FB_SYNC_HOR_HIGH_ACT)
531 hw->MiscOutReg &= ~0x40;
532 if (m->sync & FB_SYNC_VERT_HIGH_ACT)
533 hw->MiscOutReg &= ~0x80;
534 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
535 hw->CRTCEXT[3] |= 0x40;
537 if (DAC1064_init_2(PMINFO m)) return 1;
542 #ifdef CONFIG_FB_MATROX_G
543 static int MGAG100_init(WPMINFO struct my_timming* m) {
544 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
548 if (DAC1064_init_1(PMINFO m)) return 1;
549 hw->MXoptionReg &= ~0x2000;
550 if (matroxfb_vgaHWinit(PMINFO m)) return 1;
552 hw->MiscOutReg = 0xEF;
553 if (m->sync & FB_SYNC_HOR_HIGH_ACT)
554 hw->MiscOutReg &= ~0x40;
555 if (m->sync & FB_SYNC_VERT_HIGH_ACT)
556 hw->MiscOutReg &= ~0x80;
557 if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
558 hw->CRTCEXT[3] |= 0x40;
560 if (DAC1064_init_2(PMINFO m)) return 1;
565 #ifdef CONFIG_FB_MATROX_MYSTIQUE
566 static void MGA1064_ramdac_init(WPMINFO2) {
570 /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */
571 ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
572 ACCESS_FBINFO(features.pll.ref_freq) = 14318;
573 ACCESS_FBINFO(features.pll.feed_div_min) = 100;
574 ACCESS_FBINFO(features.pll.feed_div_max) = 127;
575 ACCESS_FBINFO(features.pll.in_div_min) = 1;
576 ACCESS_FBINFO(features.pll.in_div_max) = 31;
577 ACCESS_FBINFO(features.pll.post_shift_max) = 3;
578 ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL;
579 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
580 DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
584 #ifdef CONFIG_FB_MATROX_G
586 static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
587 /* G100 wants 0x10, G200 SGRAM does not care... */
589 static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
592 static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p) {
599 outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
600 M1064_XPIXCLKCTRL_PLL_UP);
602 case 0: reg = M1064_XPIXPLLAM; break;
603 case 1: reg = M1064_XPIXPLLBM; break;
604 default: reg = M1064_XPIXPLLCM; break;
606 outDAC1064(PMINFO reg++, m);
607 outDAC1064(PMINFO reg++, n);
608 outDAC1064(PMINFO reg, p);
609 selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
610 /* there should be flags & 0x03 & case 0/1/else */
611 /* and we should first select source and after that we should wait for PLL */
612 /* and we are waiting for PLL with oscilator disabled... Is it right? */
613 switch (flags & 0x03) {
615 case 0x01: selClk |= 4; break;
616 default: selClk |= 0x0C; break;
618 mga_outb(M_MISC_REG, selClk);
619 for (clk = 500000; clk; clk--) {
620 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
625 printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
626 selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
627 switch (flags & 0x0C) {
628 case 0x00: selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
629 case 0x04: selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
630 default: selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
632 outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk);
633 outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
636 static void MGAG100_setPixClock(CPMINFO int flags, int freq) {
637 unsigned int m, n, p;
641 DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
642 MGAG100_progPixClock(PMINFO flags, m, n, p);
646 #ifdef CONFIG_FB_MATROX_MYSTIQUE
647 static int MGA1064_preinit(WPMINFO2) {
648 static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960,
649 1024, 1152, 1280, 1600, 1664, 1920,
651 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
655 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
656 ACCESS_FBINFO(capable.text) = 1;
657 ACCESS_FBINFO(capable.vxres) = vxres_mystique;
659 ACCESS_FBINFO(outputs[0]).output = &m1064;
660 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
661 ACCESS_FBINFO(outputs[0]).data = MINFO;
662 ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
664 if (ACCESS_FBINFO(devflags.noinit))
665 return 0; /* do not modify settings */
666 hw->MXoptionReg &= 0xC0000100;
667 hw->MXoptionReg |= 0x00094E20;
668 if (ACCESS_FBINFO(devflags.novga))
669 hw->MXoptionReg &= ~0x00000100;
670 if (ACCESS_FBINFO(devflags.nobios))
671 hw->MXoptionReg &= ~0x40000000;
672 if (ACCESS_FBINFO(devflags.nopciretry))
673 hw->MXoptionReg |= 0x20000000;
674 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
675 mga_setr(M_SEQ_INDEX, 0x01, 0x20);
676 mga_outl(M_CTLWTST, 0x00000000);
678 mga_outl(M_MACCESS, 0x00008000);
680 mga_outl(M_MACCESS, 0x0000C000);
684 static void MGA1064_reset(WPMINFO2) {
688 MGA1064_ramdac_init(PMINFO2);
692 #ifdef CONFIG_FB_MATROX_G
693 static void g450_mclk_init(WPMINFO2) {
694 /* switch all clocks to PCI source */
695 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
696 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3 & ~0x00300C03);
697 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
699 if (((ACCESS_FBINFO(values).reg.opt3 & 0x000003) == 0x000003) ||
700 ((ACCESS_FBINFO(values).reg.opt3 & 0x000C00) == 0x000C00) ||
701 ((ACCESS_FBINFO(values).reg.opt3 & 0x300000) == 0x300000)) {
702 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.video), M_VIDEO_PLL);
707 matroxfb_DAC_lock_irqsave(flags);
708 pwr = inDAC1064(PMINFO M1064_XPWRCTRL) & ~0x02;
709 outDAC1064(PMINFO M1064_XPWRCTRL, pwr);
710 matroxfb_DAC_unlock_irqrestore(flags);
712 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.system), M_SYSTEM_PLL);
714 /* switch clocks to their real PLL source(s) */
715 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
716 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3);
717 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
721 static void g450_memory_init(WPMINFO2) {
722 /* disable memory refresh */
723 ACCESS_FBINFO(hw).MXoptionReg &= ~0x001F8000;
724 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
726 /* set memory interface parameters */
727 ACCESS_FBINFO(hw).MXoptionReg &= ~0x00207E00;
728 ACCESS_FBINFO(hw).MXoptionReg |= 0x00207E00 & ACCESS_FBINFO(values).reg.opt;
729 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
730 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ACCESS_FBINFO(values).reg.opt2);
732 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
734 /* first set up memory interface with disabled memory interface clocks */
735 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc & ~0x80000000U);
736 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
737 mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess);
738 /* start memory clocks */
739 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc | 0x80000000U);
743 if (ACCESS_FBINFO(values).memory.ddr && (!ACCESS_FBINFO(values).memory.emrswen || !ACCESS_FBINFO(values).memory.dll)) {
744 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk & ~0x1000);
746 mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess | 0x8000);
750 ACCESS_FBINFO(hw).MXoptionReg |= 0x001F8000 & ACCESS_FBINFO(values).reg.opt;
751 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
753 /* value is written to memory chips only if old != new */
754 mga_outl(M_PLNWT, 0);
755 mga_outl(M_PLNWT, ~0);
757 if (ACCESS_FBINFO(values).reg.mctlwtst != ACCESS_FBINFO(values).reg.mctlwtst_core) {
758 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst_core);
763 static void g450_preinit(WPMINFO2) {
768 /* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */
769 ACCESS_FBINFO(hw).MXoptionReg &= 0xC0000100;
770 ACCESS_FBINFO(hw).MXoptionReg |= 0x00000020;
771 if (ACCESS_FBINFO(devflags.novga))
772 ACCESS_FBINFO(hw).MXoptionReg &= ~0x00000100;
773 if (ACCESS_FBINFO(devflags.nobios))
774 ACCESS_FBINFO(hw).MXoptionReg &= ~0x40000000;
775 if (ACCESS_FBINFO(devflags.nopciretry))
776 ACCESS_FBINFO(hw).MXoptionReg |= 0x20000000;
777 ACCESS_FBINFO(hw).MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x03400040;
778 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
780 /* Init system clocks */
783 c2ctl = mga_inl(M_C2CTL);
784 mga_outl(M_C2CTL, c2ctl & ~1);
786 curctl = inDAC1064(PMINFO M1064_XCURCTRL);
787 outDAC1064(PMINFO M1064_XCURCTRL, 0);
789 c1ctl = mga_readr(M_SEQ_INDEX, 1);
790 mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20);
792 g450_mclk_init(PMINFO2);
793 g450_memory_init(PMINFO2);
795 /* set legacy VGA clock sources for DOSEmu or VMware... */
796 matroxfb_g450_setclk(PMINFO 25175, M_PIXEL_PLL_A);
797 matroxfb_g450_setclk(PMINFO 28322, M_PIXEL_PLL_B);
800 mga_setr(M_SEQ_INDEX, 1, c1ctl);
803 outDAC1064(PMINFO M1064_XCURCTRL, curctl);
806 mga_outl(M_C2CTL, c2ctl);
811 static int MGAG100_preinit(WPMINFO2) {
812 static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960,
813 1024, 1152, 1280, 1600, 1664, 1920,
815 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
824 /* there are some instabilities if in_div > 19 && vco < 61000 */
825 if (ACCESS_FBINFO(devflags.g450dac)) {
826 ACCESS_FBINFO(features.pll.vco_freq_min) = 130000; /* my sample: >118 */
828 ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
830 if (!ACCESS_FBINFO(features.pll.ref_freq)) {
831 ACCESS_FBINFO(features.pll.ref_freq) = 27000;
833 ACCESS_FBINFO(features.pll.feed_div_min) = 7;
834 ACCESS_FBINFO(features.pll.feed_div_max) = 127;
835 ACCESS_FBINFO(features.pll.in_div_min) = 1;
836 ACCESS_FBINFO(features.pll.in_div_max) = 31;
837 ACCESS_FBINFO(features.pll.post_shift_max) = 3;
838 ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT;
839 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
840 ACCESS_FBINFO(capable.text) = 1;
841 ACCESS_FBINFO(capable.vxres) = vxres_g100;
842 ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
843 ? ACCESS_FBINFO(devflags.sgram) : 1;
845 #ifdef CONFIG_FB_MATROX_G
846 if (ACCESS_FBINFO(devflags.g450dac)) {
847 ACCESS_FBINFO(outputs[0]).output = &g450out;
851 ACCESS_FBINFO(outputs[0]).output = &m1064;
853 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
854 ACCESS_FBINFO(outputs[0]).data = MINFO;
855 ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
857 if (ACCESS_FBINFO(devflags.g450dac)) {
858 /* we must do this always, BIOS does not do it for us
859 and accelerator dies without it */
862 if (ACCESS_FBINFO(devflags.noinit))
864 if (ACCESS_FBINFO(devflags.g450dac)) {
865 g450_preinit(PMINFO2);
868 hw->MXoptionReg &= 0xC0000100;
869 hw->MXoptionReg |= 0x00000020;
870 if (ACCESS_FBINFO(devflags.novga))
871 hw->MXoptionReg &= ~0x00000100;
872 if (ACCESS_FBINFO(devflags.nobios))
873 hw->MXoptionReg &= ~0x40000000;
874 if (ACCESS_FBINFO(devflags.nopciretry))
875 hw->MXoptionReg |= 0x20000000;
876 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
877 DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
879 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
880 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50);
882 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
884 hw->MXoptionReg |= 0x1080;
885 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
886 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
888 mga_outb(0x1C05, 0x00);
889 mga_outb(0x1C05, 0x80);
891 mga_outb(0x1C05, 0x40);
892 mga_outb(0x1C05, 0xC0);
896 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
897 /* it should help with G100 */
898 mga_outb(M_GRAPHICS_INDEX, 6);
899 mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
900 mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
901 mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
902 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA);
903 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55);
904 mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55);
906 if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) {
907 hw->MXoptionReg &= ~0x1000;
910 hw->MXoptionReg |= 0x00078020;
911 } else if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) {
912 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50);
914 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
916 if (ACCESS_FBINFO(devflags.memtype) == -1)
917 hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
919 hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
920 if (ACCESS_FBINFO(devflags.sgram))
921 hw->MXoptionReg |= 0x4000;
922 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
923 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
925 mga_outl(M_MACCESS, 0x00000000);
926 mga_outl(M_MACCESS, 0x00008000);
928 mga_outw(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
929 hw->MXoptionReg |= 0x00078020;
931 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ®50);
932 reg50 &= ~0x00000100;
934 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
936 if (ACCESS_FBINFO(devflags.memtype) == -1)
937 hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
939 hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
940 if (ACCESS_FBINFO(devflags.sgram))
941 hw->MXoptionReg |= 0x4000;
942 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
943 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
945 mga_outl(M_MACCESS, 0x00000000);
946 mga_outl(M_MACCESS, 0x00008000);
948 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
949 hw->MXoptionReg |= 0x00040020;
951 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
955 static void MGAG100_reset(WPMINFO2) {
957 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
962 #ifdef G100_BROKEN_IBM_82351
965 find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
966 pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
967 if (b == ACCESS_FBINFO(pcidev)->bus->number) {
968 pci_write_config_byte(ibm, PCI_COMMAND+1, 0); /* disable back-to-back & SERR */
969 pci_write_config_byte(ibm, 0x41, 0xF4); /* ??? */
970 pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0); /* ??? */
971 pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */
974 if (!ACCESS_FBINFO(devflags.noinit)) {
976 hw->MXoptionReg |= 0x40; /* FIXME... */
977 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
979 mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
982 if (ACCESS_FBINFO(devflags.g450dac)) {
983 /* either leave MCLK as is... or they were set in preinit */
984 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
985 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
986 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
988 DAC1064_setmclk(PMINFO DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
990 if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
991 if (ACCESS_FBINFO(devflags.dfp_type) == -1) {
992 ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F);
995 if (ACCESS_FBINFO(devflags.noinit))
997 if (ACCESS_FBINFO(devflags.g450dac)) {
999 MGAG100_setPixClock(PMINFO 4, 25175);
1000 MGAG100_setPixClock(PMINFO 5, 28322);
1002 b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
1003 outDAC1064(PMINFO M1064_XGENIODATA, b);
1004 b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
1005 outDAC1064(PMINFO M1064_XGENIOCTRL, b);
1011 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1012 static void MGA1064_restore(WPMINFO2) {
1014 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
1022 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
1023 mga_outb(M_IEN, 0x00);
1024 mga_outb(M_CACHEFLUSH, 0x00);
1028 DAC1064_restore_1(PMINFO2);
1029 matroxfb_vgaHWrestore(PMINFO2);
1030 ACCESS_FBINFO(crtc1.panpos) = -1;
1031 for (i = 0; i < 6; i++)
1032 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1033 DAC1064_restore_2(PMINFO2);
1037 #ifdef CONFIG_FB_MATROX_G
1038 static void MGAG100_restore(WPMINFO2) {
1040 struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
1048 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
1051 DAC1064_restore_1(PMINFO2);
1052 matroxfb_vgaHWrestore(PMINFO2);
1053 #ifdef CONFIG_FB_MATROX_32MB
1054 if (ACCESS_FBINFO(devflags.support32MB))
1055 mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
1057 ACCESS_FBINFO(crtc1.panpos) = -1;
1058 for (i = 0; i < 6; i++)
1059 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1060 DAC1064_restore_2(PMINFO2);
1064 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1065 struct matrox_switch matrox_mystique = {
1066 MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore,
1068 EXPORT_SYMBOL(matrox_mystique);
1071 #ifdef CONFIG_FB_MATROX_G
1072 struct matrox_switch matrox_G100 = {
1073 MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore,
1075 EXPORT_SYMBOL(matrox_G100);
1079 EXPORT_SYMBOL(DAC1064_global_init);
1080 EXPORT_SYMBOL(DAC1064_global_restore);
1082 MODULE_LICENSE("GPL");