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
:
301 /* HELP! If we boot without DFP connected to DVI, we can
302 poweroff TMDS. But if we boot with DFP connected,
303 TMDS generated clocks are used instead of ALL pixclocks
304 available... If someone knows which register
305 handles it, please reveal this secret to me... */
306 hw
->DACreg
[POS1064_XPWRCTRL
] &= ~0x04; /* Poweroff TMDS */
310 /* Now set timming related variables... */
311 g450_set_plls(minfo
);
315 if (minfo
->outputs
[1].src
== MATROXFB_SRC_CRTC1
) {
316 hw
->DACreg
[POS1064_XPIXCLKCTRL
] = M1064_XPIXCLKCTRL_PLL_UP
| M1064_XPIXCLKCTRL_EN
| M1064_XPIXCLKCTRL_SRC_EXT
;
317 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_MAFC
| G400_XMISCCTRL_VDO_MAFC12
;
318 } else if (minfo
->outputs
[1].src
== MATROXFB_SRC_CRTC2
) {
319 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_MAFC
| G400_XMISCCTRL_VDO_C2_MAFC12
;
320 } else if (minfo
->outputs
[2].src
== MATROXFB_SRC_CRTC1
)
321 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_PANELLINK
| G400_XMISCCTRL_VDO_MAFC12
;
323 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_DIS
;
325 if (minfo
->outputs
[0].src
!= MATROXFB_SRC_NONE
)
326 hw
->DACreg
[POS1064_XMISCCTRL
] |= M1064_XMISCCTRL_DAC_EN
;
330 void DAC1064_global_restore(struct matrox_fb_info
*minfo
)
332 struct matrox_hw_state
*hw
= &minfo
->hw
;
334 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, hw
->DACreg
[POS1064_XPIXCLKCTRL
]);
335 outDAC1064(minfo
, M1064_XMISCCTRL
, hw
->DACreg
[POS1064_XMISCCTRL
]);
336 if (minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG400
) {
337 outDAC1064(minfo
, 0x20, 0x04);
338 outDAC1064(minfo
, 0x1F, minfo
->devflags
.dfp_type
);
339 if (minfo
->devflags
.g450dac
) {
340 outDAC1064(minfo
, M1064_XSYNCCTRL
, 0xCC);
341 outDAC1064(minfo
, M1064_XPWRCTRL
, hw
->DACreg
[POS1064_XPWRCTRL
]);
342 outDAC1064(minfo
, M1064_XPANMODE
, hw
->DACreg
[POS1064_XPANMODE
]);
343 outDAC1064(minfo
, M1064_XOUTPUTCONN
, hw
->DACreg
[POS1064_XOUTPUTCONN
]);
348 static int DAC1064_init_1(struct matrox_fb_info
*minfo
, struct my_timming
*m
)
350 struct matrox_hw_state
*hw
= &minfo
->hw
;
354 memcpy(hw
->DACreg
, MGA1064_DAC
, sizeof(MGA1064_DAC_regs
));
355 switch (minfo
->fbcon
.var
.bits_per_pixel
) {
356 /* case 4: not supported by MGA1064 DAC */
358 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_8BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
361 if (minfo
->fbcon
.var
.green
.length
== 5)
362 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_15BPP_1BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
364 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_16BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
367 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_24BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
370 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_32BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
373 return 1; /* unsupported depth */
375 hw
->DACreg
[POS1064_XVREFCTRL
] = minfo
->features
.DAC1064
.xvrefctrl
;
376 hw
->DACreg
[POS1064_XGENCTRL
] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK
;
377 hw
->DACreg
[POS1064_XGENCTRL
] |= (m
->sync
& FB_SYNC_ON_GREEN
)?M1064_XGENCTRL_SYNC_ON_GREEN
:M1064_XGENCTRL_NO_SYNC_ON_GREEN
;
378 hw
->DACreg
[POS1064_XCURADDL
] = 0;
379 hw
->DACreg
[POS1064_XCURADDH
] = 0;
381 DAC1064_global_init(minfo
);
385 static int DAC1064_init_2(struct matrox_fb_info
*minfo
, struct my_timming
*m
)
387 struct matrox_hw_state
*hw
= &minfo
->hw
;
391 if (minfo
->fbcon
.var
.bits_per_pixel
> 16) { /* 256 entries */
394 for (i
= 0; i
< 256; i
++) {
395 hw
->DACpal
[i
* 3 + 0] = i
;
396 hw
->DACpal
[i
* 3 + 1] = i
;
397 hw
->DACpal
[i
* 3 + 2] = i
;
399 } else if (minfo
->fbcon
.var
.bits_per_pixel
> 8) {
400 if (minfo
->fbcon
.var
.green
.length
== 5) { /* 0..31, 128..159 */
403 for (i
= 0; i
< 32; i
++) {
405 hw
->DACpal
[i
* 3 + 0] = i
<< 3;
406 hw
->DACpal
[i
* 3 + 1] = i
<< 3;
407 hw
->DACpal
[i
* 3 + 2] = i
<< 3;
409 hw
->DACpal
[(i
+ 128) * 3 + 0] = i
<< 3;
410 hw
->DACpal
[(i
+ 128) * 3 + 1] = i
<< 3;
411 hw
->DACpal
[(i
+ 128) * 3 + 2] = i
<< 3;
416 for (i
= 0; i
< 64; i
++) { /* 0..63 */
417 hw
->DACpal
[i
* 3 + 0] = i
<< 3;
418 hw
->DACpal
[i
* 3 + 1] = i
<< 2;
419 hw
->DACpal
[i
* 3 + 2] = i
<< 3;
423 memset(hw
->DACpal
, 0, 768);
428 static void DAC1064_restore_1(struct matrox_fb_info
*minfo
)
430 struct matrox_hw_state
*hw
= &minfo
->hw
;
438 if ((inDAC1064(minfo
, DAC1064_XSYSPLLM
) != hw
->DACclk
[3]) ||
439 (inDAC1064(minfo
, DAC1064_XSYSPLLN
) != hw
->DACclk
[4]) ||
440 (inDAC1064(minfo
, DAC1064_XSYSPLLP
) != hw
->DACclk
[5])) {
441 outDAC1064(minfo
, DAC1064_XSYSPLLM
, hw
->DACclk
[3]);
442 outDAC1064(minfo
, DAC1064_XSYSPLLN
, hw
->DACclk
[4]);
443 outDAC1064(minfo
, DAC1064_XSYSPLLP
, hw
->DACclk
[5]);
448 for (i
= 0; i
< sizeof(MGA1064_DAC_regs
); i
++) {
449 if ((i
!= POS1064_XPIXCLKCTRL
) && (i
!= POS1064_XMISCCTRL
))
450 outDAC1064(minfo
, MGA1064_DAC_regs
[i
], hw
->DACreg
[i
]);
454 DAC1064_global_restore(minfo
);
459 static void DAC1064_restore_2(struct matrox_fb_info
*minfo
)
468 dprintk(KERN_DEBUG
"DAC1064regs ");
469 for (i
= 0; i
< sizeof(MGA1064_DAC_regs
); i
++) {
470 dprintk("R%02X=%02X ", MGA1064_DAC_regs
[i
], minfo
->hw
.DACreg
[i
]);
471 if ((i
& 0x7) == 0x7) dprintk(KERN_DEBUG
"continuing... ");
473 dprintk(KERN_DEBUG
"DAC1064clk ");
474 for (i
= 0; i
< 6; i
++)
475 dprintk("C%02X=%02X ", i
, minfo
->hw
.DACclk
[i
]);
480 static int m1064_compute(void* out
, struct my_timming
* m
) {
481 #define minfo ((struct matrox_fb_info*)out)
487 DAC1064_setpclk(minfo
, m
->pixclock
);
491 for (i
= 0; i
< 3; i
++)
492 outDAC1064(minfo
, M1064_XPIXPLLCM
+ i
, minfo
->hw
.DACclk
[i
]);
493 for (tmout
= 500000; tmout
; tmout
--) {
494 if (inDAC1064(minfo
, M1064_XPIXPLLSTAT
) & 0x40)
502 printk(KERN_ERR
"matroxfb: Pixel PLL not locked after 5 secs\n");
508 static struct matrox_altout m1064
= {
509 .name
= "Primary output",
510 .compute
= m1064_compute
,
513 #ifdef CONFIG_FB_MATROX_G
514 static int g450_compute(void* out
, struct my_timming
* m
) {
515 #define minfo ((struct matrox_fb_info*)out)
517 m
->mnp
= matroxfb_g450_setclk(minfo
, m
->pixclock
, (m
->crtc
== MATROXFB_SRC_CRTC1
) ? M_PIXEL_PLL_C
: M_VIDEO_PLL
);
519 m
->pixclock
= g450_mnp2f(minfo
, m
->mnp
);
526 static struct matrox_altout g450out
= {
527 .name
= "Primary output",
528 .compute
= g450_compute
,
532 #endif /* NEED_DAC1064 */
534 #ifdef CONFIG_FB_MATROX_MYSTIQUE
535 static int MGA1064_init(struct matrox_fb_info
*minfo
, struct my_timming
*m
)
537 struct matrox_hw_state
*hw
= &minfo
->hw
;
541 if (DAC1064_init_1(minfo
, m
)) return 1;
542 if (matroxfb_vgaHWinit(minfo
, m
)) return 1;
544 hw
->MiscOutReg
= 0xCB;
545 if (m
->sync
& FB_SYNC_HOR_HIGH_ACT
)
546 hw
->MiscOutReg
&= ~0x40;
547 if (m
->sync
& FB_SYNC_VERT_HIGH_ACT
)
548 hw
->MiscOutReg
&= ~0x80;
549 if (m
->sync
& FB_SYNC_COMP_HIGH_ACT
) /* should be only FB_SYNC_COMP */
550 hw
->CRTCEXT
[3] |= 0x40;
552 if (DAC1064_init_2(minfo
, m
)) return 1;
557 #ifdef CONFIG_FB_MATROX_G
558 static int MGAG100_init(struct matrox_fb_info
*minfo
, struct my_timming
*m
)
560 struct matrox_hw_state
*hw
= &minfo
->hw
;
564 if (DAC1064_init_1(minfo
, m
)) return 1;
565 hw
->MXoptionReg
&= ~0x2000;
566 if (matroxfb_vgaHWinit(minfo
, m
)) return 1;
568 hw
->MiscOutReg
= 0xEF;
569 if (m
->sync
& FB_SYNC_HOR_HIGH_ACT
)
570 hw
->MiscOutReg
&= ~0x40;
571 if (m
->sync
& FB_SYNC_VERT_HIGH_ACT
)
572 hw
->MiscOutReg
&= ~0x80;
573 if (m
->sync
& FB_SYNC_COMP_HIGH_ACT
) /* should be only FB_SYNC_COMP */
574 hw
->CRTCEXT
[3] |= 0x40;
576 if (DAC1064_init_2(minfo
, m
)) return 1;
581 #ifdef CONFIG_FB_MATROX_MYSTIQUE
582 static void MGA1064_ramdac_init(struct matrox_fb_info
*minfo
)
587 /* minfo->features.DAC1064.vco_freq_min = 120000; */
588 minfo
->features
.pll
.vco_freq_min
= 62000;
589 minfo
->features
.pll
.ref_freq
= 14318;
590 minfo
->features
.pll
.feed_div_min
= 100;
591 minfo
->features
.pll
.feed_div_max
= 127;
592 minfo
->features
.pll
.in_div_min
= 1;
593 minfo
->features
.pll
.in_div_max
= 31;
594 minfo
->features
.pll
.post_shift_max
= 3;
595 minfo
->features
.DAC1064
.xvrefctrl
= DAC1064_XVREFCTRL_EXTERNAL
;
596 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
597 DAC1064_setmclk(minfo
, DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV3
| DAC1064_OPT_SCLK_PLL
, 133333);
601 #ifdef CONFIG_FB_MATROX_G
603 static int x7AF4
= 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
604 /* G100 wants 0x10, G200 SGRAM does not care... */
606 static int def50
= 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
609 static void MGAG100_progPixClock(const struct matrox_fb_info
*minfo
, int flags
,
618 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, inDAC1064(minfo
, M1064_XPIXCLKCTRL
) | M1064_XPIXCLKCTRL_DIS
|
619 M1064_XPIXCLKCTRL_PLL_UP
);
621 case 0: reg
= M1064_XPIXPLLAM
; break;
622 case 1: reg
= M1064_XPIXPLLBM
; break;
623 default: reg
= M1064_XPIXPLLCM
; break;
625 outDAC1064(minfo
, reg
++, m
);
626 outDAC1064(minfo
, reg
++, n
);
627 outDAC1064(minfo
, reg
, p
);
628 selClk
= mga_inb(M_MISC_REG_READ
) & ~0xC;
629 /* there should be flags & 0x03 & case 0/1/else */
630 /* and we should first select source and after that we should wait for PLL */
631 /* and we are waiting for PLL with oscilator disabled... Is it right? */
632 switch (flags
& 0x03) {
634 case 0x01: selClk
|= 4; break;
635 default: selClk
|= 0x0C; break;
637 mga_outb(M_MISC_REG
, selClk
);
638 for (clk
= 500000; clk
; clk
--) {
639 if (inDAC1064(minfo
, M1064_XPIXPLLSTAT
) & 0x40)
644 printk(KERN_ERR
"matroxfb: Pixel PLL%c not locked after usual time\n", (reg
-M1064_XPIXPLLAM
-2)/4 + 'A');
645 selClk
= inDAC1064(minfo
, M1064_XPIXCLKCTRL
) & ~M1064_XPIXCLKCTRL_SRC_MASK
;
646 switch (flags
& 0x0C) {
647 case 0x00: selClk
|= M1064_XPIXCLKCTRL_SRC_PCI
; break;
648 case 0x04: selClk
|= M1064_XPIXCLKCTRL_SRC_PLL
; break;
649 default: selClk
|= M1064_XPIXCLKCTRL_SRC_EXT
; break;
651 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, selClk
);
652 outDAC1064(minfo
, M1064_XPIXCLKCTRL
, inDAC1064(minfo
, M1064_XPIXCLKCTRL
) & ~M1064_XPIXCLKCTRL_DIS
);
655 static void MGAG100_setPixClock(const struct matrox_fb_info
*minfo
, int flags
,
658 unsigned int m
, n
, p
;
662 DAC1064_calcclock(minfo
, freq
, minfo
->max_pixel_clock
, &m
, &n
, &p
);
663 MGAG100_progPixClock(minfo
, flags
, m
, n
, p
);
667 #ifdef CONFIG_FB_MATROX_MYSTIQUE
668 static int MGA1064_preinit(struct matrox_fb_info
*minfo
)
670 static const int vxres_mystique
[] = { 512, 640, 768, 800, 832, 960,
671 1024, 1152, 1280, 1600, 1664, 1920,
673 struct matrox_hw_state
*hw
= &minfo
->hw
;
677 /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
678 minfo
->capable
.text
= 1;
679 minfo
->capable
.vxres
= vxres_mystique
;
681 minfo
->outputs
[0].output
= &m1064
;
682 minfo
->outputs
[0].src
= minfo
->outputs
[0].default_src
;
683 minfo
->outputs
[0].data
= minfo
;
684 minfo
->outputs
[0].mode
= MATROXFB_OUTPUT_MODE_MONITOR
;
686 if (minfo
->devflags
.noinit
)
687 return 0; /* do not modify settings */
688 hw
->MXoptionReg
&= 0xC0000100;
689 hw
->MXoptionReg
|= 0x00094E20;
690 if (minfo
->devflags
.novga
)
691 hw
->MXoptionReg
&= ~0x00000100;
692 if (minfo
->devflags
.nobios
)
693 hw
->MXoptionReg
&= ~0x40000000;
694 if (minfo
->devflags
.nopciretry
)
695 hw
->MXoptionReg
|= 0x20000000;
696 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
697 mga_setr(M_SEQ_INDEX
, 0x01, 0x20);
698 mga_outl(M_CTLWTST
, 0x00000000);
700 mga_outl(M_MACCESS
, 0x00008000);
702 mga_outl(M_MACCESS
, 0x0000C000);
706 static void MGA1064_reset(struct matrox_fb_info
*minfo
)
711 MGA1064_ramdac_init(minfo
);
715 #ifdef CONFIG_FB_MATROX_G
716 static void g450_mclk_init(struct matrox_fb_info
*minfo
)
718 /* switch all clocks to PCI source */
719 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
| 4);
720 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION3_REG
, minfo
->values
.reg
.opt3
& ~0x00300C03);
721 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
723 if (((minfo
->values
.reg
.opt3
& 0x000003) == 0x000003) ||
724 ((minfo
->values
.reg
.opt3
& 0x000C00) == 0x000C00) ||
725 ((minfo
->values
.reg
.opt3
& 0x300000) == 0x300000)) {
726 matroxfb_g450_setclk(minfo
, minfo
->values
.pll
.video
, M_VIDEO_PLL
);
731 matroxfb_DAC_lock_irqsave(flags
);
732 pwr
= inDAC1064(minfo
, M1064_XPWRCTRL
) & ~0x02;
733 outDAC1064(minfo
, M1064_XPWRCTRL
, pwr
);
734 matroxfb_DAC_unlock_irqrestore(flags
);
736 matroxfb_g450_setclk(minfo
, minfo
->values
.pll
.system
, M_SYSTEM_PLL
);
738 /* switch clocks to their real PLL source(s) */
739 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
| 4);
740 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION3_REG
, minfo
->values
.reg
.opt3
);
741 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
745 static void g450_memory_init(struct matrox_fb_info
*minfo
)
747 /* disable memory refresh */
748 minfo
->hw
.MXoptionReg
&= ~0x001F8000;
749 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
751 /* set memory interface parameters */
752 minfo
->hw
.MXoptionReg
&= ~0x00207E00;
753 minfo
->hw
.MXoptionReg
|= 0x00207E00 & minfo
->values
.reg
.opt
;
754 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
755 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, minfo
->values
.reg
.opt2
);
757 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst
);
759 /* first set up memory interface with disabled memory interface clocks */
760 pci_write_config_dword(minfo
->pcidev
, PCI_MEMMISC_REG
, minfo
->values
.reg
.memmisc
& ~0x80000000U
);
761 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
762 mga_outl(M_MACCESS
, minfo
->values
.reg
.maccess
);
763 /* start memory clocks */
764 pci_write_config_dword(minfo
->pcidev
, PCI_MEMMISC_REG
, minfo
->values
.reg
.memmisc
| 0x80000000U
);
768 if (minfo
->values
.memory
.ddr
&& (!minfo
->values
.memory
.emrswen
|| !minfo
->values
.memory
.dll
)) {
769 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
& ~0x1000);
771 mga_outl(M_MACCESS
, minfo
->values
.reg
.maccess
| 0x8000);
775 minfo
->hw
.MXoptionReg
|= 0x001F8000 & minfo
->values
.reg
.opt
;
776 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
778 /* value is written to memory chips only if old != new */
779 mga_outl(M_PLNWT
, 0);
780 mga_outl(M_PLNWT
, ~0);
782 if (minfo
->values
.reg
.mctlwtst
!= minfo
->values
.reg
.mctlwtst_core
) {
783 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst_core
);
788 static void g450_preinit(struct matrox_fb_info
*minfo
)
794 /* minfo->hw.MXoptionReg = minfo->values.reg.opt; */
795 minfo
->hw
.MXoptionReg
&= 0xC0000100;
796 minfo
->hw
.MXoptionReg
|= 0x00000020;
797 if (minfo
->devflags
.novga
)
798 minfo
->hw
.MXoptionReg
&= ~0x00000100;
799 if (minfo
->devflags
.nobios
)
800 minfo
->hw
.MXoptionReg
&= ~0x40000000;
801 if (minfo
->devflags
.nopciretry
)
802 minfo
->hw
.MXoptionReg
|= 0x20000000;
803 minfo
->hw
.MXoptionReg
|= minfo
->values
.reg
.opt
& 0x03400040;
804 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, minfo
->hw
.MXoptionReg
);
806 /* Init system clocks */
809 c2ctl
= mga_inl(M_C2CTL
);
810 mga_outl(M_C2CTL
, c2ctl
& ~1);
812 curctl
= inDAC1064(minfo
, M1064_XCURCTRL
);
813 outDAC1064(minfo
, M1064_XCURCTRL
, 0);
815 c1ctl
= mga_readr(M_SEQ_INDEX
, 1);
816 mga_setr(M_SEQ_INDEX
, 1, c1ctl
| 0x20);
818 g450_mclk_init(minfo
);
819 g450_memory_init(minfo
);
821 /* set legacy VGA clock sources for DOSEmu or VMware... */
822 matroxfb_g450_setclk(minfo
, 25175, M_PIXEL_PLL_A
);
823 matroxfb_g450_setclk(minfo
, 28322, M_PIXEL_PLL_B
);
826 mga_setr(M_SEQ_INDEX
, 1, c1ctl
);
829 outDAC1064(minfo
, M1064_XCURCTRL
, curctl
);
832 mga_outl(M_C2CTL
, c2ctl
);
837 static int MGAG100_preinit(struct matrox_fb_info
*minfo
)
839 static const int vxres_g100
[] = { 512, 640, 768, 800, 832, 960,
840 1024, 1152, 1280, 1600, 1664, 1920,
842 struct matrox_hw_state
*hw
= &minfo
->hw
;
851 /* there are some instabilities if in_div > 19 && vco < 61000 */
852 if (minfo
->devflags
.g450dac
) {
853 minfo
->features
.pll
.vco_freq_min
= 130000; /* my sample: >118 */
855 minfo
->features
.pll
.vco_freq_min
= 62000;
857 if (!minfo
->features
.pll
.ref_freq
) {
858 minfo
->features
.pll
.ref_freq
= 27000;
860 minfo
->features
.pll
.feed_div_min
= 7;
861 minfo
->features
.pll
.feed_div_max
= 127;
862 minfo
->features
.pll
.in_div_min
= 1;
863 minfo
->features
.pll
.in_div_max
= 31;
864 minfo
->features
.pll
.post_shift_max
= 3;
865 minfo
->features
.DAC1064
.xvrefctrl
= DAC1064_XVREFCTRL_G100_DEFAULT
;
866 /* minfo->capable.cfb4 = 0; ... preinitialized by 0 */
867 minfo
->capable
.text
= 1;
868 minfo
->capable
.vxres
= vxres_g100
;
869 minfo
->capable
.plnwt
= minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG100
870 ? minfo
->devflags
.sgram
: 1;
872 #ifdef CONFIG_FB_MATROX_G
873 if (minfo
->devflags
.g450dac
) {
874 minfo
->outputs
[0].output
= &g450out
;
878 minfo
->outputs
[0].output
= &m1064
;
880 minfo
->outputs
[0].src
= minfo
->outputs
[0].default_src
;
881 minfo
->outputs
[0].data
= minfo
;
882 minfo
->outputs
[0].mode
= MATROXFB_OUTPUT_MODE_MONITOR
;
884 if (minfo
->devflags
.g450dac
) {
885 /* we must do this always, BIOS does not do it for us
886 and accelerator dies without it */
889 if (minfo
->devflags
.noinit
)
891 if (minfo
->devflags
.g450dac
) {
895 hw
->MXoptionReg
&= 0xC0000100;
896 hw
->MXoptionReg
|= 0x00000020;
897 if (minfo
->devflags
.novga
)
898 hw
->MXoptionReg
&= ~0x00000100;
899 if (minfo
->devflags
.nobios
)
900 hw
->MXoptionReg
&= ~0x40000000;
901 if (minfo
->devflags
.nopciretry
)
902 hw
->MXoptionReg
|= 0x20000000;
903 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
904 DAC1064_setmclk(minfo
, DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV3
| DAC1064_OPT_SCLK_PCI
, 133333);
906 if (minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG100
) {
907 pci_read_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, ®50
);
909 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, reg50
);
911 hw
->MXoptionReg
|= 0x1080;
912 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
913 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst
);
915 mga_outb(0x1C05, 0x00);
916 mga_outb(0x1C05, 0x80);
918 mga_outb(0x1C05, 0x40);
919 mga_outb(0x1C05, 0xC0);
923 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, reg50
);
924 /* it should help with G100 */
925 mga_outb(M_GRAPHICS_INDEX
, 6);
926 mga_outb(M_GRAPHICS_DATA
, (mga_inb(M_GRAPHICS_DATA
) & 3) | 4);
927 mga_setr(M_EXTVGA_INDEX
, 0x03, 0x81);
928 mga_setr(M_EXTVGA_INDEX
, 0x04, 0x00);
929 mga_writeb(minfo
->video
.vbase
, 0x0000, 0xAA);
930 mga_writeb(minfo
->video
.vbase
, 0x0800, 0x55);
931 mga_writeb(minfo
->video
.vbase
, 0x4000, 0x55);
933 if (mga_readb(minfo
->video
.vbase
, 0x0000) != 0xAA) {
934 hw
->MXoptionReg
&= ~0x1000;
937 hw
->MXoptionReg
|= 0x00078020;
938 } else if (minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG200
) {
939 pci_read_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, ®50
);
941 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, reg50
);
943 if (minfo
->devflags
.memtype
== -1)
944 hw
->MXoptionReg
|= minfo
->values
.reg
.opt
& 0x1C00;
946 hw
->MXoptionReg
|= (minfo
->devflags
.memtype
& 7) << 10;
947 if (minfo
->devflags
.sgram
)
948 hw
->MXoptionReg
|= 0x4000;
949 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst
);
950 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
952 mga_outl(M_MACCESS
, 0x00000000);
953 mga_outl(M_MACCESS
, 0x00008000);
955 mga_outw(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
956 hw
->MXoptionReg
|= 0x00078020;
958 pci_read_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, ®50
);
959 reg50
&= ~0x00000100;
961 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION2_REG
, reg50
);
963 if (minfo
->devflags
.memtype
== -1)
964 hw
->MXoptionReg
|= minfo
->values
.reg
.opt
& 0x1C00;
966 hw
->MXoptionReg
|= (minfo
->devflags
.memtype
& 7) << 10;
967 if (minfo
->devflags
.sgram
)
968 hw
->MXoptionReg
|= 0x4000;
969 mga_outl(M_CTLWTST
, minfo
->values
.reg
.mctlwtst
);
970 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
972 mga_outl(M_MACCESS
, 0x00000000);
973 mga_outl(M_MACCESS
, 0x00008000);
975 mga_outl(M_MEMRDBK
, minfo
->values
.reg
.memrdbk
);
976 hw
->MXoptionReg
|= 0x00040020;
978 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
982 static void MGAG100_reset(struct matrox_fb_info
*minfo
)
985 struct matrox_hw_state
*hw
= &minfo
->hw
;
990 #ifdef G100_BROKEN_IBM_82351
993 find
1014/22 (IBM
/82351); /* if found and bridging Matrox, do some strange stuff */
994 pci_read_config_byte(ibm
, PCI_SECONDARY_BUS
, &b
);
995 if (b
== minfo
->pcidev
->bus
->number
) {
996 pci_write_config_byte(ibm
, PCI_COMMAND
+1, 0); /* disable back-to-back & SERR */
997 pci_write_config_byte(ibm
, 0x41, 0xF4); /* ??? */
998 pci_write_config_byte(ibm
, PCI_IO_BASE
, 0xF0); /* ??? */
999 pci_write_config_byte(ibm
, PCI_IO_LIMIT
, 0x00); /* ??? */
1002 if (!minfo
->devflags
.noinit
) {
1004 hw
->MXoptionReg
|= 0x40; /* FIXME... */
1005 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
1007 mga_setr(M_EXTVGA_INDEX
, 0x06, 0x00);
1010 if (minfo
->devflags
.g450dac
) {
1011 /* either leave MCLK as is... or they were set in preinit */
1012 hw
->DACclk
[3] = inDAC1064(minfo
, DAC1064_XSYSPLLM
);
1013 hw
->DACclk
[4] = inDAC1064(minfo
, DAC1064_XSYSPLLN
);
1014 hw
->DACclk
[5] = inDAC1064(minfo
, DAC1064_XSYSPLLP
);
1016 DAC1064_setmclk(minfo
, DAC1064_OPT_RESERVED
| DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV1
| DAC1064_OPT_SCLK_PLL
, 133333);
1018 if (minfo
->devflags
.accelerator
== FB_ACCEL_MATROX_MGAG400
) {
1019 if (minfo
->devflags
.dfp_type
== -1) {
1020 minfo
->devflags
.dfp_type
= inDAC1064(minfo
, 0x1F);
1023 if (minfo
->devflags
.noinit
)
1025 if (minfo
->devflags
.g450dac
) {
1027 MGAG100_setPixClock(minfo
, 4, 25175);
1028 MGAG100_setPixClock(minfo
, 5, 28322);
1030 b
= inDAC1064(minfo
, M1064_XGENIODATA
) & ~1;
1031 outDAC1064(minfo
, M1064_XGENIODATA
, b
);
1032 b
= inDAC1064(minfo
, M1064_XGENIOCTRL
) | 1;
1033 outDAC1064(minfo
, M1064_XGENIOCTRL
, b
);
1039 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1040 static void MGA1064_restore(struct matrox_fb_info
*minfo
)
1043 struct matrox_hw_state
*hw
= &minfo
->hw
;
1051 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
1052 mga_outb(M_IEN
, 0x00);
1053 mga_outb(M_CACHEFLUSH
, 0x00);
1057 DAC1064_restore_1(minfo
);
1058 matroxfb_vgaHWrestore(minfo
);
1059 minfo
->crtc1
.panpos
= -1;
1060 for (i
= 0; i
< 6; i
++)
1061 mga_setr(M_EXTVGA_INDEX
, i
, hw
->CRTCEXT
[i
]);
1062 DAC1064_restore_2(minfo
);
1066 #ifdef CONFIG_FB_MATROX_G
1067 static void MGAG100_restore(struct matrox_fb_info
*minfo
)
1070 struct matrox_hw_state
*hw
= &minfo
->hw
;
1078 pci_write_config_dword(minfo
->pcidev
, PCI_OPTION_REG
, hw
->MXoptionReg
);
1081 DAC1064_restore_1(minfo
);
1082 matroxfb_vgaHWrestore(minfo
);
1083 if (minfo
->devflags
.support32MB
)
1084 mga_setr(M_EXTVGA_INDEX
, 8, hw
->CRTCEXT
[8]);
1085 minfo
->crtc1
.panpos
= -1;
1086 for (i
= 0; i
< 6; i
++)
1087 mga_setr(M_EXTVGA_INDEX
, i
, hw
->CRTCEXT
[i
]);
1088 DAC1064_restore_2(minfo
);
1092 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1093 struct matrox_switch matrox_mystique
= {
1094 MGA1064_preinit
, MGA1064_reset
, MGA1064_init
, MGA1064_restore
,
1096 EXPORT_SYMBOL(matrox_mystique
);
1099 #ifdef CONFIG_FB_MATROX_G
1100 struct matrox_switch matrox_G100
= {
1101 MGAG100_preinit
, MGAG100_reset
, MGAG100_init
, MGAG100_restore
,
1103 EXPORT_SYMBOL(matrox_G100
);
1107 EXPORT_SYMBOL(DAC1064_global_init
);
1108 EXPORT_SYMBOL(DAC1064_global_restore
);
1110 MODULE_LICENSE("GPL");