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(const struct matrox_fb_info
*minfo
,
37 unsigned int freq
, unsigned int fmax
,
38 unsigned int *in
, unsigned int *feed
,
46 /* only for devices older than G450 */
48 fvco
= PLL_calcclock(minfo
, freq
, fmax
, in
, feed
, &p
);
53 else if (fvco
<= 140000)
55 else if (fvco
<= 180000)
62 /* they must be in POS order */
63 static const unsigned char MGA1064_DAC_regs
[] = {
64 M1064_XCURADDL
, M1064_XCURADDH
, M1064_XCURCTRL
,
65 M1064_XCURCOL0RED
, M1064_XCURCOL0GREEN
, M1064_XCURCOL0BLUE
,
66 M1064_XCURCOL1RED
, M1064_XCURCOL1GREEN
, M1064_XCURCOL1BLUE
,
67 M1064_XCURCOL2RED
, M1064_XCURCOL2GREEN
, M1064_XCURCOL2BLUE
,
68 DAC1064_XVREFCTRL
, M1064_XMULCTRL
, M1064_XPIXCLKCTRL
, M1064_XGENCTRL
,
70 M1064_XGENIOCTRL
, M1064_XGENIODATA
, M1064_XZOOMCTRL
, M1064_XSENSETEST
,
72 M1064_XCOLKEYMASKL
, M1064_XCOLKEYMASKH
, M1064_XCOLKEYL
, M1064_XCOLKEYH
};
74 static const unsigned char MGA1064_DAC
[] = {
75 0x00, 0x00, M1064_XCURCTRL_DIS
,
76 0x00, 0x00, 0x00, /* black */
77 0xFF, 0xFF, 0xFF, /* white */
78 0xFF, 0x00, 0x00, /* red */
80 M1064_XPIXCLKCTRL_PLL_UP
| M1064_XPIXCLKCTRL_EN
| M1064_XPIXCLKCTRL_SRC_PLL
,
81 M1064_XGENCTRL_VS_0
| M1064_XGENCTRL_ALPHA_DIS
| M1064_XGENCTRL_BLACK_0IRE
| M1064_XGENCTRL_NO_SYNC_ON_GREEN
,
82 M1064_XMISCCTRL_DAC_8BIT
,
83 0x00, 0x00, M1064_XZOOMCTRL_1
, M1064_XSENSETEST_BCOMP
| M1064_XSENSETEST_GCOMP
| M1064_XSENSETEST_RCOMP
| M1064_XSENSETEST_PDOWN
,
85 0x00, 0x00, 0xFF, 0xFF};
87 static void DAC1064_setpclk(struct matrox_fb_info
*minfo
, unsigned long fout
)
93 DAC1064_calcclock(minfo
, fout
, minfo
->max_pixel_clock
, &m
, &n
, &p
);
94 minfo
->hw
.DACclk
[0] = m
;
95 minfo
->hw
.DACclk
[1] = n
;
96 minfo
->hw
.DACclk
[2] = p
;
99 static void DAC1064_setmclk(struct matrox_fb_info
*minfo
, int oscinfo
,
103 struct matrox_hw_state
*hw
= &minfo
->hw
;
107 if (minfo
->devflags
.noinit
) {
108 /* read MCLK and give up... */
109 hw
->DACclk
[3] = inDAC1064(minfo
, DAC1064_XSYSPLLM
);
110 hw
->DACclk
[4] = inDAC1064(minfo
, DAC1064_XSYSPLLN
);
111 hw
->DACclk
[5] = inDAC1064(minfo
, DAC1064_XSYSPLLP
);
114 mx
= hw
->MXoptionReg
| 0x00000004;
115 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, mx
);
117 if (oscinfo
& DAC1064_OPT_GDIV1
)
119 if (oscinfo
& DAC1064_OPT_MDIV1
)
121 if (oscinfo
& DAC1064_OPT_RESERVED
)
123 if ((oscinfo
& DAC1064_OPT_SCLK_MASK
) == DAC1064_OPT_SCLK_PLL
) {
124 /* select PCI clock until we have setup oscilator... */
126 unsigned int m
, n
, p
;
128 /* powerup system PLL, select PCI clock */
130 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, mx
);
132 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, mx
);
134 /* !!! you must not access device if MCLK is not running !!!
135 Doing so cause immediate PCI lockup :-( Maybe they should
136 generate ABORT or I/O (parity...) error and Linux should
137 recover from this... (kill driver/process). But world is not
139 /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
140 select PLL... because of PLL can be stopped at this time) */
141 DAC1064_calcclock(minfo
, fmem
, minfo
->max_pixel_clock
, &m
, &n
, &p
);
142 outDAC1064(minfo
, DAC1064_XSYSPLLM
, hw
->DACclk
[3] = m
);
143 outDAC1064(minfo
, DAC1064_XSYSPLLN
, hw
->DACclk
[4] = n
);
144 outDAC1064(minfo
, DAC1064_XSYSPLLP
, hw
->DACclk
[5] = p
);
145 for (clk
= 65536; clk
; --clk
) {
146 if (inDAC1064(minfo
, DAC1064_XSYSPLLSTAT
) & 0x40)
150 printk(KERN_ERR
"matroxfb: aiee, SYSPLL not locked\n");
154 /* select specified system clock source */
155 mx
|= oscinfo
& DAC1064_OPT_SCLK_MASK
;
157 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, mx
);
159 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, mx
);
160 hw
->MXoptionReg
= mx
;
163 #ifdef CONFIG_FB_MATROX_G
164 static void g450_set_plls(struct matrox_fb_info
*minfo
)
168 struct matrox_hw_state
*hw
= &minfo
->hw
;
172 c2_ctl
= hw
->crtc2
.ctl
& ~0x4007; /* Clear PLL + enable for CRTC2 */
173 c2_ctl
|= 0x0001; /* Enable CRTC2 */
174 hw
->DACreg
[POS1064_XPWRCTRL
] &= ~0x02; /* Stop VIDEO PLL */
175 pixelmnp
= minfo
->crtc1
.mnp
;
176 videomnp
= minfo
->crtc2
.mnp
;
178 c2_ctl
&= ~0x0001; /* Disable CRTC2 */
179 hw
->DACreg
[POS1064_XPWRCTRL
] &= ~0x10; /* Powerdown CRTC2 */
180 } else if (minfo
->crtc2
.pixclock
== minfo
->features
.pll
.ref_freq
) {
181 c2_ctl
|= 0x4002; /* Use reference directly */
182 } else if (videomnp
== pixelmnp
) {
183 c2_ctl
|= 0x0004; /* Use pixel PLL */
185 if (0 == ((videomnp
^ pixelmnp
) & 0xFFFFFF00)) {
186 /* PIXEL and VIDEO PLL must not use same frequency. We modify N
187 of PIXEL PLL in such case because of VIDEO PLL may be source
188 of TVO clocks, and chroma subcarrier is derived from its
190 pixelmnp
+= 0x000100;
192 c2_ctl
|= 0x0006; /* Use video PLL */
193 hw
->DACreg
[POS1064_XPWRCTRL
] |= 0x02;
195 outDAC1064(minfo
, M1064_XPWRCTRL
, hw
->DACreg
[POS1064_XPWRCTRL
]);
196 matroxfb_g450_setpll_cond(minfo
, videomnp
, M_VIDEO_PLL
);
199 hw
->DACreg
[POS1064_XPIXCLKCTRL
] &= ~M1064_XPIXCLKCTRL_PLL_UP
;
201 hw
->DACreg
[POS1064_XPIXCLKCTRL
] |= M1064_XPIXCLKCTRL_PLL_UP
;
203 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, hw
->DACreg
[POS1064_XPIXCLKCTRL
]);
204 matroxfb_g450_setpll_cond(minfo
, pixelmnp
, M_PIXEL_PLL_C
);
206 if (c2_ctl
!= hw
->crtc2
.ctl
) {
207 hw
->crtc2
.ctl
= c2_ctl
;
208 mga_outl(0x3C10, c2_ctl
);
211 pxc
= minfo
->crtc1
.pixclock
;
212 if (pxc
== 0 || minfo
->outputs
[2].src
== MATROXFB_SRC_CRTC2
) {
213 pxc
= minfo
->crtc2
.pixclock
;
215 if (minfo
->chip
== MGA_G550
) {
217 hw
->DACreg
[POS1064_XPANMODE
] = 0x00; /* 0-50 */
218 } else if (pxc
< 55000) {
219 hw
->DACreg
[POS1064_XPANMODE
] = 0x08; /* 34-62 */
220 } else if (pxc
< 70000) {
221 hw
->DACreg
[POS1064_XPANMODE
] = 0x10; /* 42-78 */
222 } else if (pxc
< 85000) {
223 hw
->DACreg
[POS1064_XPANMODE
] = 0x18; /* 62-92 */
224 } else if (pxc
< 100000) {
225 hw
->DACreg
[POS1064_XPANMODE
] = 0x20; /* 74-108 */
226 } else if (pxc
< 115000) {
227 hw
->DACreg
[POS1064_XPANMODE
] = 0x28; /* 94-122 */
228 } else if (pxc
< 125000) {
229 hw
->DACreg
[POS1064_XPANMODE
] = 0x30; /* 108-132 */
231 hw
->DACreg
[POS1064_XPANMODE
] = 0x38; /* 120-168 */
236 hw
->DACreg
[POS1064_XPANMODE
] = 0x00; /* 0-54 */
237 } else if (pxc
< 65000) {
238 hw
->DACreg
[POS1064_XPANMODE
] = 0x08; /* 38-70 */
239 } else if (pxc
< 85000) {
240 hw
->DACreg
[POS1064_XPANMODE
] = 0x10; /* 56-96 */
241 } else if (pxc
< 105000) {
242 hw
->DACreg
[POS1064_XPANMODE
] = 0x18; /* 80-114 */
243 } else if (pxc
< 135000) {
244 hw
->DACreg
[POS1064_XPANMODE
] = 0x20; /* 102-144 */
245 } else if (pxc
< 160000) {
246 hw
->DACreg
[POS1064_XPANMODE
] = 0x28; /* 132-166 */
247 } else if (pxc
< 175000) {
248 hw
->DACreg
[POS1064_XPANMODE
] = 0x30; /* 154-182 */
250 hw
->DACreg
[POS1064_XPANMODE
] = 0x38; /* 170-204 */
256 void DAC1064_global_init(struct matrox_fb_info
*minfo
)
258 struct matrox_hw_state
*hw
= &minfo
->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 #ifdef CONFIG_FB_MATROX_G
264 if (minfo
->devflags
.g450dac
) {
265 hw
->DACreg
[POS1064_XPWRCTRL
] = 0x1F; /* powerup everything */
266 hw
->DACreg
[POS1064_XOUTPUTCONN
] = 0x00; /* disable outputs */
267 hw
->DACreg
[POS1064_XMISCCTRL
] |= M1064_XMISCCTRL_DAC_EN
;
268 switch (minfo
->outputs
[0].src
) {
269 case MATROXFB_SRC_CRTC1
:
270 case MATROXFB_SRC_CRTC2
:
271 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x01; /* enable output; CRTC1/2 selection is in CRTC2 ctl */
273 case MATROXFB_SRC_NONE
:
274 hw
->DACreg
[POS1064_XMISCCTRL
] &= ~M1064_XMISCCTRL_DAC_EN
;
277 switch (minfo
->outputs
[1].src
) {
278 case MATROXFB_SRC_CRTC1
:
279 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x04;
281 case MATROXFB_SRC_CRTC2
:
282 if (minfo
->outputs
[1].mode
== MATROXFB_OUTPUT_MODE_MONITOR
) {
283 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x08;
285 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x0C;
288 case MATROXFB_SRC_NONE
:
289 hw
->DACreg
[POS1064_XPWRCTRL
] &= ~0x01; /* Poweroff DAC2 */
292 switch (minfo
->outputs
[2].src
) {
293 case MATROXFB_SRC_CRTC1
:
294 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x20;
296 case MATROXFB_SRC_CRTC2
:
297 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x40;
299 case MATROXFB_SRC_NONE
:
302 /* Now set timming related variables... */
303 g450_set_plls(minfo
);
307 if (minfo
->outputs
[1].src
== MATROXFB_SRC_CRTC1
) {
308 hw
->DACreg
[POS1064_XPIXCLKCTRL
] = M1064_XPIXCLKCTRL_PLL_UP
| M1064_XPIXCLKCTRL_EN
| M1064_XPIXCLKCTRL_SRC_EXT
;
309 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_MAFC
| G400_XMISCCTRL_VDO_MAFC12
;
310 } else if (minfo
->outputs
[1].src
== MATROXFB_SRC_CRTC2
) {
311 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_MAFC
| G400_XMISCCTRL_VDO_C2_MAFC12
;
312 } else if (minfo
->outputs
[2].src
== MATROXFB_SRC_CRTC1
)
313 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_PANELLINK
| G400_XMISCCTRL_VDO_MAFC12
;
315 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_DIS
;
317 if (minfo
->outputs
[0].src
!= MATROXFB_SRC_NONE
)
318 hw
->DACreg
[POS1064_XMISCCTRL
] |= M1064_XMISCCTRL_DAC_EN
;
322 void DAC1064_global_restore(struct matrox_fb_info
*minfo
)
324 struct matrox_hw_state
*hw
= &minfo
->hw
;
326 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, hw
->DACreg
[POS1064_XPIXCLKCTRL
]);
327 outDAC1064(minfo
, M1064_XMISCCTRL
, hw
->DACreg
[POS1064_XMISCCTRL
]);
328 if (minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG400
) {
329 outDAC1064(minfo
, 0x20, 0x04);
330 outDAC1064(minfo
, 0x1F, minfo
->devflags
.dfp_type
);
331 if (minfo
->devflags
.g450dac
) {
332 outDAC1064(minfo
, M1064_XSYNCCTRL
, 0xCC);
333 outDAC1064(minfo
, M1064_XPWRCTRL
, hw
->DACreg
[POS1064_XPWRCTRL
]);
334 outDAC1064(minfo
, M1064_XPANMODE
, hw
->DACreg
[POS1064_XPANMODE
]);
335 outDAC1064(minfo
, M1064_XOUTPUTCONN
, hw
->DACreg
[POS1064_XOUTPUTCONN
]);
340 static int DAC1064_init_1(struct matrox_fb_info
*minfo
, struct my_timming
*m
)
342 struct matrox_hw_state
*hw
= &minfo
->hw
;
346 memcpy(hw
->DACreg
, MGA1064_DAC
, sizeof(MGA1064_DAC_regs
));
347 switch (minfo
->fbcon
.var
.bits_per_pixel
) {
348 /* case 4: not supported by MGA1064 DAC */
350 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_8BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
353 if (minfo
->fbcon
.var
.green
.length
== 5)
354 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_15BPP_1BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
356 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_16BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
359 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_24BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
362 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_32BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
365 return 1; /* unsupported depth */
367 hw
->DACreg
[POS1064_XVREFCTRL
] = minfo
->features
.DAC1064
.xvrefctrl
;
368 hw
->DACreg
[POS1064_XGENCTRL
] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK
;
369 hw
->DACreg
[POS1064_XGENCTRL
] |= (m
->sync
& FB_SYNC_ON_GREEN
)?M1064_XGENCTRL_SYNC_ON_GREEN
:M1064_XGENCTRL_NO_SYNC_ON_GREEN
;
370 hw
->DACreg
[POS1064_XCURADDL
] = 0;
371 hw
->DACreg
[POS1064_XCURADDH
] = 0;
373 DAC1064_global_init(minfo
);
377 static int DAC1064_init_2(struct matrox_fb_info
*minfo
, struct my_timming
*m
)
379 struct matrox_hw_state
*hw
= &minfo
->hw
;
383 if (minfo
->fbcon
.var
.bits_per_pixel
> 16) { /* 256 entries */
386 for (i
= 0; i
< 256; i
++) {
387 hw
->DACpal
[i
* 3 + 0] = i
;
388 hw
->DACpal
[i
* 3 + 1] = i
;
389 hw
->DACpal
[i
* 3 + 2] = i
;
391 } else if (minfo
->fbcon
.var
.bits_per_pixel
> 8) {
392 if (minfo
->fbcon
.var
.green
.length
== 5) { /* 0..31, 128..159 */
395 for (i
= 0; i
< 32; i
++) {
397 hw
->DACpal
[i
* 3 + 0] = i
<< 3;
398 hw
->DACpal
[i
* 3 + 1] = i
<< 3;
399 hw
->DACpal
[i
* 3 + 2] = i
<< 3;
401 hw
->DACpal
[(i
+ 128) * 3 + 0] = i
<< 3;
402 hw
->DACpal
[(i
+ 128) * 3 + 1] = i
<< 3;
403 hw
->DACpal
[(i
+ 128) * 3 + 2] = i
<< 3;
408 for (i
= 0; i
< 64; i
++) { /* 0..63 */
409 hw
->DACpal
[i
* 3 + 0] = i
<< 3;
410 hw
->DACpal
[i
* 3 + 1] = i
<< 2;
411 hw
->DACpal
[i
* 3 + 2] = i
<< 3;
415 memset(hw
->DACpal
, 0, 768);
420 static void DAC1064_restore_1(struct matrox_fb_info
*minfo
)
422 struct matrox_hw_state
*hw
= &minfo
->hw
;
430 if ((inDAC1064(minfo
, DAC1064_XSYSPLLM
) != hw
->DACclk
[3]) ||
431 (inDAC1064(minfo
, DAC1064_XSYSPLLN
) != hw
->DACclk
[4]) ||
432 (inDAC1064(minfo
, DAC1064_XSYSPLLP
) != hw
->DACclk
[5])) {
433 outDAC1064(minfo
, DAC1064_XSYSPLLM
, hw
->DACclk
[3]);
434 outDAC1064(minfo
, DAC1064_XSYSPLLN
, hw
->DACclk
[4]);
435 outDAC1064(minfo
, DAC1064_XSYSPLLP
, hw
->DACclk
[5]);
440 for (i
= 0; i
< sizeof(MGA1064_DAC_regs
); i
++) {
441 if ((i
!= POS1064_XPIXCLKCTRL
) && (i
!= POS1064_XMISCCTRL
))
442 outDAC1064(minfo
, MGA1064_DAC_regs
[i
], hw
->DACreg
[i
]);
446 DAC1064_global_restore(minfo
);
451 static void DAC1064_restore_2(struct matrox_fb_info
*minfo
)
460 dprintk(KERN_DEBUG
"DAC1064regs ");
461 for (i
= 0; i
< sizeof(MGA1064_DAC_regs
); i
++) {
462 dprintk("R%02X=%02X ", MGA1064_DAC_regs
[i
], minfo
->hw
.DACreg
[i
]);
463 if ((i
& 0x7) == 0x7) dprintk(KERN_DEBUG
"continuing... ");
465 dprintk(KERN_DEBUG
"DAC1064clk ");
466 for (i
= 0; i
< 6; i
++)
467 dprintk("C%02X=%02X ", i
, minfo
->hw
.DACclk
[i
]);
472 static int m1064_compute(void* out
, struct my_timming
* m
) {
473 #define minfo ((struct matrox_fb_info*)out)
479 DAC1064_setpclk(minfo
, m
->pixclock
);
483 for (i
= 0; i
< 3; i
++)
484 outDAC1064(minfo
, M1064_XPIXPLLCM
+ i
, minfo
->hw
.DACclk
[i
]);
485 for (tmout
= 500000; tmout
; tmout
--) {
486 if (inDAC1064(minfo
, M1064_XPIXPLLSTAT
) & 0x40)
494 printk(KERN_ERR
"matroxfb: Pixel PLL not locked after 5 secs\n");
500 static struct matrox_altout m1064
= {
501 .name
= "Primary output",
502 .compute
= m1064_compute
,
505 #ifdef CONFIG_FB_MATROX_G
506 static int g450_compute(void* out
, struct my_timming
* m
) {
507 #define minfo ((struct matrox_fb_info*)out)
509 m
->mnp
= matroxfb_g450_setclk(minfo
, m
->pixclock
, (m
->crtc
== MATROXFB_SRC_CRTC1
) ? M_PIXEL_PLL_C
: M_VIDEO_PLL
);
511 m
->pixclock
= g450_mnp2f(minfo
, m
->mnp
);
518 static struct matrox_altout g450out
= {
519 .name
= "Primary output",
520 .compute
= g450_compute
,
524 #endif /* NEED_DAC1064 */
526 #ifdef CONFIG_FB_MATROX_MYSTIQUE
527 static int MGA1064_init(struct matrox_fb_info
*minfo
, struct my_timming
*m
)
529 struct matrox_hw_state
*hw
= &minfo
->hw
;
533 if (DAC1064_init_1(minfo
, m
)) return 1;
534 if (matroxfb_vgaHWinit(minfo
, m
)) return 1;
536 hw
->MiscOutReg
= 0xCB;
537 if (m
->sync
& FB_SYNC_HOR_HIGH_ACT
)
538 hw
->MiscOutReg
&= ~0x40;
539 if (m
->sync
& FB_SYNC_VERT_HIGH_ACT
)
540 hw
->MiscOutReg
&= ~0x80;
541 if (m
->sync
& FB_SYNC_COMP_HIGH_ACT
) /* should be only FB_SYNC_COMP */
542 hw
->CRTCEXT
[3] |= 0x40;
544 if (DAC1064_init_2(minfo
, m
)) return 1;
549 #ifdef CONFIG_FB_MATROX_G
550 static int MGAG100_init(struct matrox_fb_info
*minfo
, struct my_timming
*m
)
552 struct matrox_hw_state
*hw
= &minfo
->hw
;
556 if (DAC1064_init_1(minfo
, m
)) return 1;
557 hw
->MXoptionReg
&= ~0x2000;
558 if (matroxfb_vgaHWinit(minfo
, m
)) return 1;
560 hw
->MiscOutReg
= 0xEF;
561 if (m
->sync
& FB_SYNC_HOR_HIGH_ACT
)
562 hw
->MiscOutReg
&= ~0x40;
563 if (m
->sync
& FB_SYNC_VERT_HIGH_ACT
)
564 hw
->MiscOutReg
&= ~0x80;
565 if (m
->sync
& FB_SYNC_COMP_HIGH_ACT
) /* should be only FB_SYNC_COMP */
566 hw
->CRTCEXT
[3] |= 0x40;
568 if (DAC1064_init_2(minfo
, m
)) return 1;
573 #ifdef CONFIG_FB_MATROX_MYSTIQUE
574 static void MGA1064_ramdac_init(struct matrox_fb_info
*minfo
)
579 /* minfo->features.DAC1064.vco_freq_min = 120000; */
580 minfo
->features
.pll
.vco_freq_min
= 62000;
581 minfo
->features
.pll
.ref_freq
= 14318;
582 minfo
->features
.pll
.feed_div_min
= 100;
583 minfo
->features
.pll
.feed_div_max
= 127;
584 minfo
->features
.pll
.in_div_min
= 1;
585 minfo
->features
.pll
.in_div_max
= 31;
586 minfo
->features
.pll
.post_shift_max
= 3;
587 minfo
->features
.DAC1064
.xvrefctrl
= DAC1064_XVREFCTRL_EXTERNAL
;
588 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
589 DAC1064_setmclk(minfo
, DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV3
| DAC1064_OPT_SCLK_PLL
, 133333);
593 #ifdef CONFIG_FB_MATROX_G
595 static int x7AF4
= 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
596 /* G100 wants 0x10, G200 SGRAM does not care... */
598 static void MGAG100_progPixClock(const struct matrox_fb_info
*minfo
, int flags
,
607 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, inDAC1064(minfo
, M1064_XPIXCLKCTRL
) | M1064_XPIXCLKCTRL_DIS
|
608 M1064_XPIXCLKCTRL_PLL_UP
);
610 case 0: reg
= M1064_XPIXPLLAM
; break;
611 case 1: reg
= M1064_XPIXPLLBM
; break;
612 default: reg
= M1064_XPIXPLLCM
; break;
614 outDAC1064(minfo
, reg
++, m
);
615 outDAC1064(minfo
, reg
++, n
);
616 outDAC1064(minfo
, reg
, p
);
617 selClk
= mga_inb(M_MISC_REG_READ
) & ~0xC;
618 /* there should be flags & 0x03 & case 0/1/else */
619 /* and we should first select source and after that we should wait for PLL */
620 /* and we are waiting for PLL with oscilator disabled... Is it right? */
621 switch (flags
& 0x03) {
623 case 0x01: selClk
|= 4; break;
624 default: selClk
|= 0x0C; break;
626 mga_outb(M_MISC_REG
, selClk
);
627 for (clk
= 500000; clk
; clk
--) {
628 if (inDAC1064(minfo
, M1064_XPIXPLLSTAT
) & 0x40)
633 printk(KERN_ERR
"matroxfb: Pixel PLL%c not locked after usual time\n", (reg
-M1064_XPIXPLLAM
-2)/4 + 'A');
634 selClk
= inDAC1064(minfo
, M1064_XPIXCLKCTRL
) & ~M1064_XPIXCLKCTRL_SRC_MASK
;
635 switch (flags
& 0x0C) {
636 case 0x00: selClk
|= M1064_XPIXCLKCTRL_SRC_PCI
; break;
637 case 0x04: selClk
|= M1064_XPIXCLKCTRL_SRC_PLL
; break;
638 default: selClk
|= M1064_XPIXCLKCTRL_SRC_EXT
; break;
640 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, selClk
);
641 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, inDAC1064(minfo
, M1064_XPIXCLKCTRL
) & ~M1064_XPIXCLKCTRL_DIS
);
644 static void MGAG100_setPixClock(const struct matrox_fb_info
*minfo
, int flags
,
647 unsigned int m
, n
, p
;
651 DAC1064_calcclock(minfo
, freq
, minfo
->max_pixel_clock
, &m
, &n
, &p
);
652 MGAG100_progPixClock(minfo
, flags
, m
, n
, p
);
656 #ifdef CONFIG_FB_MATROX_MYSTIQUE
657 static int MGA1064_preinit(struct matrox_fb_info
*minfo
)
659 static const int vxres_mystique
[] = { 512, 640, 768, 800, 832, 960,
660 1024, 1152, 1280, 1600, 1664, 1920,
662 struct matrox_hw_state
*hw
= &minfo
->hw
;
666 /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
667 minfo
->capable
.text
= 1;
668 minfo
->capable
.vxres
= vxres_mystique
;
670 minfo
->outputs
[0].output
= &m1064
;
671 minfo
->outputs
[0].src
= minfo
->outputs
[0].default_src
;
672 minfo
->outputs
[0].data
= minfo
;
673 minfo
->outputs
[0].mode
= MATROXFB_OUTPUT_MODE_MONITOR
;
675 if (minfo
->devflags
.noinit
)
676 return 0; /* do not modify settings */
677 hw
->MXoptionReg
&= 0xC0000100;
678 hw
->MXoptionReg
|= 0x00094E20;
679 if (minfo
->devflags
.novga
)
680 hw
->MXoptionReg
&= ~0x00000100;
681 if (minfo
->devflags
.nobios
)
682 hw
->MXoptionReg
&= ~0x40000000;
683 if (minfo
->devflags
.nopciretry
)
684 hw
->MXoptionReg
|= 0x20000000;
685 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
686 mga_setr(M_SEQ_INDEX
, 0x01, 0x20);
687 mga_outl(M_CTLWTST
, 0x00000000);
689 mga_outl(M_MACCESS
, 0x00008000);
691 mga_outl(M_MACCESS
, 0x0000C000);
695 static void MGA1064_reset(struct matrox_fb_info
*minfo
)
700 MGA1064_ramdac_init(minfo
);
704 #ifdef CONFIG_FB_MATROX_G
705 static void g450_mclk_init(struct matrox_fb_info
*minfo
)
707 /* switch all clocks to PCI source */
708 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
| 4);
709 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION3_REG
, minfo
->values
.reg
.opt3
& ~0x00300C03);
710 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
712 if (((minfo
->values
.reg
.opt3
& 0x000003) == 0x000003) ||
713 ((minfo
->values
.reg
.opt3
& 0x000C00) == 0x000C00) ||
714 ((minfo
->values
.reg
.opt3
& 0x300000) == 0x300000)) {
715 matroxfb_g450_setclk(minfo
, minfo
->values
.pll
.video
, M_VIDEO_PLL
);
720 matroxfb_DAC_lock_irqsave(flags
);
721 pwr
= inDAC1064(minfo
, M1064_XPWRCTRL
) & ~0x02;
722 outDAC1064(minfo
, M1064_XPWRCTRL
, pwr
);
723 matroxfb_DAC_unlock_irqrestore(flags
);
725 matroxfb_g450_setclk(minfo
, minfo
->values
.pll
.system
, M_SYSTEM_PLL
);
727 /* switch clocks to their real PLL source(s) */
728 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
| 4);
729 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION3_REG
, minfo
->values
.reg
.opt3
);
730 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
734 static void g450_memory_init(struct matrox_fb_info
*minfo
)
736 /* disable memory refresh */
737 minfo
->hw
.MXoptionReg
&= ~0x001F8000;
738 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
740 /* set memory interface parameters */
741 minfo
->hw
.MXoptionReg
&= ~0x00207E00;
742 minfo
->hw
.MXoptionReg
|= 0x00207E00 & minfo
->values
.reg
.opt
;
743 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
744 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, minfo
->values
.reg
.opt2
);
746 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst
);
748 /* first set up memory interface with disabled memory interface clocks */
749 pci_write_config_dword(minfo
->pcidev
, PCI_MEMMISC_REG
, minfo
->values
.reg
.memmisc
& ~0x80000000U
);
750 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
751 mga_outl(M_MACCESS
, minfo
->values
.reg
.maccess
);
752 /* start memory clocks */
753 pci_write_config_dword(minfo
->pcidev
, PCI_MEMMISC_REG
, minfo
->values
.reg
.memmisc
| 0x80000000U
);
757 if (minfo
->values
.memory
.ddr
&& (!minfo
->values
.memory
.emrswen
|| !minfo
->values
.memory
.dll
)) {
758 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
& ~0x1000);
760 mga_outl(M_MACCESS
, minfo
->values
.reg
.maccess
| 0x8000);
764 minfo
->hw
.MXoptionReg
|= 0x001F8000 & minfo
->values
.reg
.opt
;
765 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
767 /* value is written to memory chips only if old != new */
768 mga_outl(M_PLNWT
, 0);
769 mga_outl(M_PLNWT
, ~0);
771 if (minfo
->values
.reg
.mctlwtst
!= minfo
->values
.reg
.mctlwtst_core
) {
772 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst_core
);
777 static void g450_preinit(struct matrox_fb_info
*minfo
)
783 /* minfo->hw.MXoptionReg = minfo->values.reg.opt; */
784 minfo
->hw
.MXoptionReg
&= 0xC0000100;
785 minfo
->hw
.MXoptionReg
|= 0x00000020;
786 if (minfo
->devflags
.novga
)
787 minfo
->hw
.MXoptionReg
&= ~0x00000100;
788 if (minfo
->devflags
.nobios
)
789 minfo
->hw
.MXoptionReg
&= ~0x40000000;
790 if (minfo
->devflags
.nopciretry
)
791 minfo
->hw
.MXoptionReg
|= 0x20000000;
792 minfo
->hw
.MXoptionReg
|= minfo
->values
.reg
.opt
& 0x03400040;
793 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
795 /* Init system clocks */
798 c2ctl
= mga_inl(M_C2CTL
);
799 mga_outl(M_C2CTL
, c2ctl
& ~1);
801 curctl
= inDAC1064(minfo
, M1064_XCURCTRL
);
802 outDAC1064(minfo
, M1064_XCURCTRL
, 0);
804 c1ctl
= mga_readr(M_SEQ_INDEX
, 1);
805 mga_setr(M_SEQ_INDEX
, 1, c1ctl
| 0x20);
807 g450_mclk_init(minfo
);
808 g450_memory_init(minfo
);
810 /* set legacy VGA clock sources for DOSEmu or VMware... */
811 matroxfb_g450_setclk(minfo
, 25175, M_PIXEL_PLL_A
);
812 matroxfb_g450_setclk(minfo
, 28322, M_PIXEL_PLL_B
);
815 mga_setr(M_SEQ_INDEX
, 1, c1ctl
);
818 outDAC1064(minfo
, M1064_XCURCTRL
, curctl
);
821 mga_outl(M_C2CTL
, c2ctl
);
826 static int MGAG100_preinit(struct matrox_fb_info
*minfo
)
828 static const int vxres_g100
[] = { 512, 640, 768, 800, 832, 960,
829 1024, 1152, 1280, 1600, 1664, 1920,
831 struct matrox_hw_state
*hw
= &minfo
->hw
;
837 /* there are some instabilities if in_div > 19 && vco < 61000 */
838 if (minfo
->devflags
.g450dac
) {
839 minfo
->features
.pll
.vco_freq_min
= 130000; /* my sample: >118 */
841 minfo
->features
.pll
.vco_freq_min
= 62000;
843 if (!minfo
->features
.pll
.ref_freq
) {
844 minfo
->features
.pll
.ref_freq
= 27000;
846 minfo
->features
.pll
.feed_div_min
= 7;
847 minfo
->features
.pll
.feed_div_max
= 127;
848 minfo
->features
.pll
.in_div_min
= 1;
849 minfo
->features
.pll
.in_div_max
= 31;
850 minfo
->features
.pll
.post_shift_max
= 3;
851 minfo
->features
.DAC1064
.xvrefctrl
= DAC1064_XVREFCTRL_G100_DEFAULT
;
852 /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
853 minfo
->capable
.text
= 1;
854 minfo
->capable
.vxres
= vxres_g100
;
855 minfo
->capable
.plnwt
= minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG100
856 ? minfo
->devflags
.sgram
: 1;
858 #ifdef CONFIG_FB_MATROX_G
859 if (minfo
->devflags
.g450dac
) {
860 minfo
->outputs
[0].output
= &g450out
;
864 minfo
->outputs
[0].output
= &m1064
;
866 minfo
->outputs
[0].src
= minfo
->outputs
[0].default_src
;
867 minfo
->outputs
[0].data
= minfo
;
868 minfo
->outputs
[0].mode
= MATROXFB_OUTPUT_MODE_MONITOR
;
870 if (minfo
->devflags
.g450dac
) {
871 /* we must do this always, BIOS does not do it for us
872 and accelerator dies without it */
875 if (minfo
->devflags
.noinit
)
877 if (minfo
->devflags
.g450dac
) {
881 hw
->MXoptionReg
&= 0xC0000100;
882 hw
->MXoptionReg
|= 0x00000020;
883 if (minfo
->devflags
.novga
)
884 hw
->MXoptionReg
&= ~0x00000100;
885 if (minfo
->devflags
.nobios
)
886 hw
->MXoptionReg
&= ~0x40000000;
887 if (minfo
->devflags
.nopciretry
)
888 hw
->MXoptionReg
|= 0x20000000;
889 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
890 DAC1064_setmclk(minfo
, DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV3
| DAC1064_OPT_SCLK_PCI
, 133333);
892 if (minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG100
) {
893 pci_read_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, ®50
);
895 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, reg50
);
897 hw
->MXoptionReg
|= 0x1080;
898 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
899 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst
);
901 mga_outb(0x1C05, 0x00);
902 mga_outb(0x1C05, 0x80);
904 mga_outb(0x1C05, 0x40);
905 mga_outb(0x1C05, 0xC0);
909 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, reg50
);
910 /* it should help with G100 */
911 mga_outb(M_GRAPHICS_INDEX
, 6);
912 mga_outb(M_GRAPHICS_DATA
, (mga_inb(M_GRAPHICS_DATA
) & 3) | 4);
913 mga_setr(M_EXTVGA_INDEX
, 0x03, 0x81);
914 mga_setr(M_EXTVGA_INDEX
, 0x04, 0x00);
915 mga_writeb(minfo
->video
.vbase
, 0x0000, 0xAA);
916 mga_writeb(minfo
->video
.vbase
, 0x0800, 0x55);
917 mga_writeb(minfo
->video
.vbase
, 0x4000, 0x55);
918 hw
->MXoptionReg
|= 0x00078020;
919 } else if (minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG200
) {
920 pci_read_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, ®50
);
922 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, reg50
);
924 if (minfo
->devflags
.memtype
== -1)
925 hw
->MXoptionReg
|= minfo
->values
.reg
.opt
& 0x1C00;
927 hw
->MXoptionReg
|= (minfo
->devflags
.memtype
& 7) << 10;
928 if (minfo
->devflags
.sgram
)
929 hw
->MXoptionReg
|= 0x4000;
930 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst
);
931 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
933 mga_outl(M_MACCESS
, 0x00000000);
934 mga_outl(M_MACCESS
, 0x00008000);
936 mga_outw(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
937 hw
->MXoptionReg
|= 0x00078020;
939 pci_read_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, ®50
);
940 reg50
&= ~0x00000100;
942 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, reg50
);
944 if (minfo
->devflags
.memtype
== -1)
945 hw
->MXoptionReg
|= minfo
->values
.reg
.opt
& 0x1C00;
947 hw
->MXoptionReg
|= (minfo
->devflags
.memtype
& 7) << 10;
948 if (minfo
->devflags
.sgram
)
949 hw
->MXoptionReg
|= 0x4000;
950 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst
);
951 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
953 mga_outl(M_MACCESS
, 0x00000000);
954 mga_outl(M_MACCESS
, 0x00008000);
956 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
957 hw
->MXoptionReg
|= 0x00040020;
959 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
963 static void MGAG100_reset(struct matrox_fb_info
*minfo
)
966 struct matrox_hw_state
*hw
= &minfo
->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
== minfo
->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 (!minfo
->devflags
.noinit
) {
985 hw
->MXoptionReg
|= 0x40;
986 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
988 mga_setr(M_EXTVGA_INDEX
, 0x06, 0x00);
991 if (minfo
->devflags
.g450dac
) {
992 /* either leave MCLK as is... or they were set in preinit */
993 hw
->DACclk
[3] = inDAC1064(minfo
, DAC1064_XSYSPLLM
);
994 hw
->DACclk
[4] = inDAC1064(minfo
, DAC1064_XSYSPLLN
);
995 hw
->DACclk
[5] = inDAC1064(minfo
, DAC1064_XSYSPLLP
);
997 DAC1064_setmclk(minfo
, DAC1064_OPT_RESERVED
| DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV1
| DAC1064_OPT_SCLK_PLL
, 133333);
999 if (minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG400
) {
1000 if (minfo
->devflags
.dfp_type
== -1) {
1001 minfo
->devflags
.dfp_type
= inDAC1064(minfo
, 0x1F);
1004 if (minfo
->devflags
.noinit
)
1006 if (minfo
->devflags
.g450dac
) {
1008 MGAG100_setPixClock(minfo
, 4, 25175);
1009 MGAG100_setPixClock(minfo
, 5, 28322);
1011 b
= inDAC1064(minfo
, M1064_XGENIODATA
) & ~1;
1012 outDAC1064(minfo
, M1064_XGENIODATA
, b
);
1013 b
= inDAC1064(minfo
, M1064_XGENIOCTRL
) | 1;
1014 outDAC1064(minfo
, M1064_XGENIOCTRL
, b
);
1020 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1021 static void MGA1064_restore(struct matrox_fb_info
*minfo
)
1024 struct matrox_hw_state
*hw
= &minfo
->hw
;
1032 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
1033 mga_outb(M_IEN
, 0x00);
1034 mga_outb(M_CACHEFLUSH
, 0x00);
1038 DAC1064_restore_1(minfo
);
1039 matroxfb_vgaHWrestore(minfo
);
1040 minfo
->crtc1
.panpos
= -1;
1041 for (i
= 0; i
< 6; i
++)
1042 mga_setr(M_EXTVGA_INDEX
, i
, hw
->CRTCEXT
[i
]);
1043 DAC1064_restore_2(minfo
);
1047 #ifdef CONFIG_FB_MATROX_G
1048 static void MGAG100_restore(struct matrox_fb_info
*minfo
)
1051 struct matrox_hw_state
*hw
= &minfo
->hw
;
1059 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
1062 DAC1064_restore_1(minfo
);
1063 matroxfb_vgaHWrestore(minfo
);
1064 if (minfo
->devflags
.support32MB
)
1065 mga_setr(M_EXTVGA_INDEX
, 8, hw
->CRTCEXT
[8]);
1066 minfo
->crtc1
.panpos
= -1;
1067 for (i
= 0; i
< 6; i
++)
1068 mga_setr(M_EXTVGA_INDEX
, i
, hw
->CRTCEXT
[i
]);
1069 DAC1064_restore_2(minfo
);
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_G
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");