3 * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
5 * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
7 * Portions Copyright (c) 2001 Matrox Graphics Inc.
9 * Version: 1.65 2002/08/14
11 * See matroxfb_base.c for contributors.
15 #include <linux/config.h>
17 #include "matroxfb_DAC1064.h"
18 #include "matroxfb_misc.h"
19 #include "matroxfb_accel.h"
21 #include <linux/matroxfb.h>
24 #define outDAC1064 matroxfb_DAC_out
25 #define inDAC1064 matroxfb_DAC_in
27 #define DAC1064_OPT_SCLK_PCI 0x00
28 #define DAC1064_OPT_SCLK_PLL 0x01
29 #define DAC1064_OPT_SCLK_EXT 0x02
30 #define DAC1064_OPT_SCLK_MASK 0x03
31 #define DAC1064_OPT_GDIV1 0x04 /* maybe it is GDIV2 on G100 ?! */
32 #define DAC1064_OPT_GDIV3 0x00
33 #define DAC1064_OPT_MDIV1 0x08
34 #define DAC1064_OPT_MDIV2 0x00
35 #define DAC1064_OPT_RESERVED 0x10
37 static void DAC1064_calcclock(CPMINFO
unsigned int freq
, unsigned int fmax
, unsigned int* in
, unsigned int* feed
, unsigned int* post
) {
43 /* only for devices older than G450 */
45 fvco
= PLL_calcclock(PMINFO freq
, fmax
, in
, feed
, &p
);
50 else if (fvco
<= 140000)
52 else if (fvco
<= 180000)
59 /* they must be in POS order */
60 static const unsigned char MGA1064_DAC_regs
[] = {
61 M1064_XCURADDL
, M1064_XCURADDH
, M1064_XCURCTRL
,
62 M1064_XCURCOL0RED
, M1064_XCURCOL0GREEN
, M1064_XCURCOL0BLUE
,
63 M1064_XCURCOL1RED
, M1064_XCURCOL1GREEN
, M1064_XCURCOL1BLUE
,
64 M1064_XCURCOL2RED
, M1064_XCURCOL2GREEN
, M1064_XCURCOL2BLUE
,
65 DAC1064_XVREFCTRL
, M1064_XMULCTRL
, M1064_XPIXCLKCTRL
, M1064_XGENCTRL
,
67 M1064_XGENIOCTRL
, M1064_XGENIODATA
, M1064_XZOOMCTRL
, M1064_XSENSETEST
,
69 M1064_XCOLKEYMASKL
, M1064_XCOLKEYMASKH
, M1064_XCOLKEYL
, M1064_XCOLKEYH
};
71 static const unsigned char MGA1064_DAC
[] = {
72 0x00, 0x00, M1064_XCURCTRL_DIS
,
73 0x00, 0x00, 0x00, /* black */
74 0xFF, 0xFF, 0xFF, /* white */
75 0xFF, 0x00, 0x00, /* red */
77 M1064_XPIXCLKCTRL_PLL_UP
| M1064_XPIXCLKCTRL_EN
| M1064_XPIXCLKCTRL_SRC_PLL
,
78 M1064_XGENCTRL_VS_0
| M1064_XGENCTRL_ALPHA_DIS
| M1064_XGENCTRL_BLACK_0IRE
| M1064_XGENCTRL_NO_SYNC_ON_GREEN
,
79 M1064_XMISCCTRL_DAC_8BIT
,
80 0x00, 0x00, M1064_XZOOMCTRL_1
, M1064_XSENSETEST_BCOMP
| M1064_XSENSETEST_GCOMP
| M1064_XSENSETEST_RCOMP
| M1064_XSENSETEST_PDOWN
,
82 0x00, 0x00, 0xFF, 0xFF};
84 static void DAC1064_setpclk(WPMINFO
unsigned long fout
) {
89 DAC1064_calcclock(PMINFO fout
, ACCESS_FBINFO(max_pixel_clock
), &m
, &n
, &p
);
90 ACCESS_FBINFO(hw
).DACclk
[0] = m
;
91 ACCESS_FBINFO(hw
).DACclk
[1] = n
;
92 ACCESS_FBINFO(hw
).DACclk
[2] = p
;
95 static void DAC1064_setmclk(WPMINFO
int oscinfo
, unsigned long fmem
) {
97 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
101 if (ACCESS_FBINFO(devflags
.noinit
)) {
102 /* read MCLK and give up... */
103 hw
->DACclk
[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM
);
104 hw
->DACclk
[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN
);
105 hw
->DACclk
[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP
);
108 mx
= hw
->MXoptionReg
| 0x00000004;
109 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, mx
);
111 if (oscinfo
& DAC1064_OPT_GDIV1
)
113 if (oscinfo
& DAC1064_OPT_MDIV1
)
115 if (oscinfo
& DAC1064_OPT_RESERVED
)
117 if ((oscinfo
& DAC1064_OPT_SCLK_MASK
) == DAC1064_OPT_SCLK_PLL
) {
118 /* select PCI clock until we have setup oscilator... */
120 unsigned int m
, n
, p
;
122 /* powerup system PLL, select PCI clock */
124 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, mx
);
126 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, mx
);
128 /* !!! you must not access device if MCLK is not running !!!
129 Doing so cause immediate PCI lockup :-( Maybe they should
130 generate ABORT or I/O (parity...) error and Linux should
131 recover from this... (kill driver/process). But world is not
133 /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
134 select PLL... because of PLL can be stopped at this time) */
135 DAC1064_calcclock(PMINFO fmem
, ACCESS_FBINFO(max_pixel_clock
), &m
, &n
, &p
);
136 outDAC1064(PMINFO DAC1064_XSYSPLLM
, hw
->DACclk
[3] = m
);
137 outDAC1064(PMINFO DAC1064_XSYSPLLN
, hw
->DACclk
[4] = n
);
138 outDAC1064(PMINFO DAC1064_XSYSPLLP
, hw
->DACclk
[5] = p
);
139 for (clk
= 65536; clk
; --clk
) {
140 if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT
) & 0x40)
144 printk(KERN_ERR
"matroxfb: aiee, SYSPLL not locked\n");
148 /* select specified system clock source */
149 mx
|= oscinfo
& DAC1064_OPT_SCLK_MASK
;
151 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, mx
);
153 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, mx
);
154 hw
->MXoptionReg
= mx
;
157 #ifdef CONFIG_FB_MATROX_G
158 static void g450_set_plls(WPMINFO2
) {
161 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
165 c2_ctl
= hw
->crtc2
.ctl
& ~0x4007; /* Clear PLL + enable for CRTC2 */
166 c2_ctl
|= 0x0001; /* Enable CRTC2 */
167 hw
->DACreg
[POS1064_XPWRCTRL
] &= ~0x02; /* Stop VIDEO PLL */
168 pixelmnp
= ACCESS_FBINFO(crtc1
).mnp
;
169 videomnp
= ACCESS_FBINFO(crtc2
).mnp
;
171 c2_ctl
&= ~0x0001; /* Disable CRTC2 */
172 hw
->DACreg
[POS1064_XPWRCTRL
] &= ~0x10; /* Powerdown CRTC2 */
173 } else if (ACCESS_FBINFO(crtc2
).pixclock
== ACCESS_FBINFO(features
).pll
.ref_freq
) {
174 c2_ctl
|= 0x4002; /* Use reference directly */
175 } else if (videomnp
== pixelmnp
) {
176 c2_ctl
|= 0x0004; /* Use pixel PLL */
178 if (0 == ((videomnp
^ pixelmnp
) & 0xFFFFFF00)) {
179 /* PIXEL and VIDEO PLL must not use same frequency. We modify N
180 of PIXEL PLL in such case because of VIDEO PLL may be source
181 of TVO clocks, and chroma subcarrier is derived from its
183 pixelmnp
+= 0x000100;
185 c2_ctl
|= 0x0006; /* Use video PLL */
186 hw
->DACreg
[POS1064_XPWRCTRL
] |= 0x02;
188 outDAC1064(PMINFO M1064_XPWRCTRL
, hw
->DACreg
[POS1064_XPWRCTRL
]);
189 matroxfb_g450_setpll_cond(PMINFO videomnp
, M_VIDEO_PLL
);
192 hw
->DACreg
[POS1064_XPIXCLKCTRL
] &= ~M1064_XPIXCLKCTRL_PLL_UP
;
194 hw
->DACreg
[POS1064_XPIXCLKCTRL
] |= M1064_XPIXCLKCTRL_PLL_UP
;
196 outDAC1064(PMINFO M1064_XPIXCLKCTRL
, hw
->DACreg
[POS1064_XPIXCLKCTRL
]);
197 matroxfb_g450_setpll_cond(PMINFO pixelmnp
, M_PIXEL_PLL_C
);
199 if (c2_ctl
!= hw
->crtc2
.ctl
) {
200 hw
->crtc2
.ctl
= c2_ctl
;
201 mga_outl(0x3C10, c2_ctl
);
204 pxc
= ACCESS_FBINFO(crtc1
).pixclock
;
205 if (pxc
== 0 || ACCESS_FBINFO(outputs
[2]).src
== MATROXFB_SRC_CRTC2
) {
206 pxc
= ACCESS_FBINFO(crtc2
).pixclock
;
208 if (ACCESS_FBINFO(chip
) == MGA_G550
) {
210 hw
->DACreg
[POS1064_XPANMODE
] = 0x00; /* 0-50 */
211 } else if (pxc
< 55000) {
212 hw
->DACreg
[POS1064_XPANMODE
] = 0x08; /* 34-62 */
213 } else if (pxc
< 70000) {
214 hw
->DACreg
[POS1064_XPANMODE
] = 0x10; /* 42-78 */
215 } else if (pxc
< 85000) {
216 hw
->DACreg
[POS1064_XPANMODE
] = 0x18; /* 62-92 */
217 } else if (pxc
< 100000) {
218 hw
->DACreg
[POS1064_XPANMODE
] = 0x20; /* 74-108 */
219 } else if (pxc
< 115000) {
220 hw
->DACreg
[POS1064_XPANMODE
] = 0x28; /* 94-122 */
221 } else if (pxc
< 125000) {
222 hw
->DACreg
[POS1064_XPANMODE
] = 0x30; /* 108-132 */
224 hw
->DACreg
[POS1064_XPANMODE
] = 0x38; /* 120-168 */
229 hw
->DACreg
[POS1064_XPANMODE
] = 0x00; /* 0-54 */
230 } else if (pxc
< 65000) {
231 hw
->DACreg
[POS1064_XPANMODE
] = 0x08; /* 38-70 */
232 } else if (pxc
< 85000) {
233 hw
->DACreg
[POS1064_XPANMODE
] = 0x10; /* 56-96 */
234 } else if (pxc
< 105000) {
235 hw
->DACreg
[POS1064_XPANMODE
] = 0x18; /* 80-114 */
236 } else if (pxc
< 135000) {
237 hw
->DACreg
[POS1064_XPANMODE
] = 0x20; /* 102-144 */
238 } else if (pxc
< 160000) {
239 hw
->DACreg
[POS1064_XPANMODE
] = 0x28; /* 132-166 */
240 } else if (pxc
< 175000) {
241 hw
->DACreg
[POS1064_XPANMODE
] = 0x30; /* 154-182 */
243 hw
->DACreg
[POS1064_XPANMODE
] = 0x38; /* 170-204 */
249 void DAC1064_global_init(WPMINFO2
) {
250 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
252 hw
->DACreg
[POS1064_XMISCCTRL
] &= M1064_XMISCCTRL_DAC_WIDTHMASK
;
253 hw
->DACreg
[POS1064_XMISCCTRL
] |= M1064_XMISCCTRL_LUT_EN
;
254 hw
->DACreg
[POS1064_XPIXCLKCTRL
] = M1064_XPIXCLKCTRL_PLL_UP
| M1064_XPIXCLKCTRL_EN
| M1064_XPIXCLKCTRL_SRC_PLL
;
255 #ifdef CONFIG_FB_MATROX_G
256 if (ACCESS_FBINFO(devflags
.g450dac
)) {
257 hw
->DACreg
[POS1064_XPWRCTRL
] = 0x1F; /* powerup everything */
258 hw
->DACreg
[POS1064_XOUTPUTCONN
] = 0x00; /* disable outputs */
259 hw
->DACreg
[POS1064_XMISCCTRL
] |= M1064_XMISCCTRL_DAC_EN
;
260 switch (ACCESS_FBINFO(outputs
[0]).src
) {
261 case MATROXFB_SRC_CRTC1
:
262 case MATROXFB_SRC_CRTC2
:
263 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x01; /* enable output; CRTC1/2 selection is in CRTC2 ctl */
265 case MATROXFB_SRC_NONE
:
266 hw
->DACreg
[POS1064_XMISCCTRL
] &= ~M1064_XMISCCTRL_DAC_EN
;
269 switch (ACCESS_FBINFO(outputs
[1]).src
) {
270 case MATROXFB_SRC_CRTC1
:
271 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x04;
273 case MATROXFB_SRC_CRTC2
:
274 if (ACCESS_FBINFO(outputs
[1]).mode
== MATROXFB_OUTPUT_MODE_MONITOR
) {
275 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x08;
277 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x0C;
280 case MATROXFB_SRC_NONE
:
281 hw
->DACreg
[POS1064_XPWRCTRL
] &= ~0x01; /* Poweroff DAC2 */
284 switch (ACCESS_FBINFO(outputs
[2]).src
) {
285 case MATROXFB_SRC_CRTC1
:
286 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x20;
288 case MATROXFB_SRC_CRTC2
:
289 hw
->DACreg
[POS1064_XOUTPUTCONN
] |= 0x40;
291 case MATROXFB_SRC_NONE
:
293 /* HELP! If we boot without DFP connected to DVI, we can
294 poweroff TMDS. But if we boot with DFP connected,
295 TMDS generated clocks are used instead of ALL pixclocks
296 available... If someone knows which register
297 handles it, please reveal this secret to me... */
298 hw
->DACreg
[POS1064_XPWRCTRL
] &= ~0x04; /* Poweroff TMDS */
302 /* Now set timming related variables... */
303 g450_set_plls(PMINFO2
);
307 if (ACCESS_FBINFO(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 (ACCESS_FBINFO(outputs
[1]).src
== MATROXFB_SRC_CRTC2
) {
311 hw
->DACreg
[POS1064_XMISCCTRL
] |= GX00_XMISCCTRL_MFC_MAFC
| G400_XMISCCTRL_VDO_C2_MAFC12
;
312 } else if (ACCESS_FBINFO(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 (ACCESS_FBINFO(outputs
[0]).src
!= MATROXFB_SRC_NONE
)
318 hw
->DACreg
[POS1064_XMISCCTRL
] |= M1064_XMISCCTRL_DAC_EN
;
322 void DAC1064_global_restore(WPMINFO2
) {
323 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
325 outDAC1064(PMINFO M1064_XPIXCLKCTRL
, hw
->DACreg
[POS1064_XPIXCLKCTRL
]);
326 outDAC1064(PMINFO M1064_XMISCCTRL
, hw
->DACreg
[POS1064_XMISCCTRL
]);
327 if (ACCESS_FBINFO(devflags
.accelerator
) == FB_ACCEL_MATROX_MGAG400
) {
328 outDAC1064(PMINFO
0x20, 0x04);
329 outDAC1064(PMINFO
0x1F, ACCESS_FBINFO(devflags
.dfp_type
));
330 if (ACCESS_FBINFO(devflags
.g450dac
)) {
331 outDAC1064(PMINFO M1064_XSYNCCTRL
, 0xCC);
332 outDAC1064(PMINFO M1064_XPWRCTRL
, hw
->DACreg
[POS1064_XPWRCTRL
]);
333 outDAC1064(PMINFO M1064_XPANMODE
, hw
->DACreg
[POS1064_XPANMODE
]);
334 outDAC1064(PMINFO M1064_XOUTPUTCONN
, hw
->DACreg
[POS1064_XOUTPUTCONN
]);
339 static int DAC1064_init_1(WPMINFO
struct my_timming
* m
) {
340 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
344 memcpy(hw
->DACreg
, MGA1064_DAC
, sizeof(MGA1064_DAC_regs
));
345 switch (ACCESS_FBINFO(fbcon
).var
.bits_per_pixel
) {
346 /* case 4: not supported by MGA1064 DAC */
348 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_8BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
351 if (ACCESS_FBINFO(fbcon
).var
.green
.length
== 5)
352 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_15BPP_1BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
354 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_16BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
357 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_24BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
360 hw
->DACreg
[POS1064_XMULCTRL
] = M1064_XMULCTRL_DEPTH_32BPP
| M1064_XMULCTRL_GRAPHICS_PALETIZED
;
363 return 1; /* unsupported depth */
365 hw
->DACreg
[POS1064_XVREFCTRL
] = ACCESS_FBINFO(features
.DAC1064
.xvrefctrl
);
366 hw
->DACreg
[POS1064_XGENCTRL
] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK
;
367 hw
->DACreg
[POS1064_XGENCTRL
] |= (m
->sync
& FB_SYNC_ON_GREEN
)?M1064_XGENCTRL_SYNC_ON_GREEN
:M1064_XGENCTRL_NO_SYNC_ON_GREEN
;
368 hw
->DACreg
[POS1064_XCURADDL
] = 0;
369 hw
->DACreg
[POS1064_XCURADDH
] = 0;
371 DAC1064_global_init(PMINFO2
);
375 static int DAC1064_init_2(WPMINFO
struct my_timming
* m
) {
376 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
380 if (ACCESS_FBINFO(fbcon
).var
.bits_per_pixel
> 16) { /* 256 entries */
383 for (i
= 0; i
< 256; i
++) {
384 hw
->DACpal
[i
* 3 + 0] = i
;
385 hw
->DACpal
[i
* 3 + 1] = i
;
386 hw
->DACpal
[i
* 3 + 2] = i
;
388 } else if (ACCESS_FBINFO(fbcon
).var
.bits_per_pixel
> 8) {
389 if (ACCESS_FBINFO(fbcon
).var
.green
.length
== 5) { /* 0..31, 128..159 */
392 for (i
= 0; i
< 32; i
++) {
394 hw
->DACpal
[i
* 3 + 0] = i
<< 3;
395 hw
->DACpal
[i
* 3 + 1] = i
<< 3;
396 hw
->DACpal
[i
* 3 + 2] = i
<< 3;
398 hw
->DACpal
[(i
+ 128) * 3 + 0] = i
<< 3;
399 hw
->DACpal
[(i
+ 128) * 3 + 1] = i
<< 3;
400 hw
->DACpal
[(i
+ 128) * 3 + 2] = i
<< 3;
405 for (i
= 0; i
< 64; i
++) { /* 0..63 */
406 hw
->DACpal
[i
* 3 + 0] = i
<< 3;
407 hw
->DACpal
[i
* 3 + 1] = i
<< 2;
408 hw
->DACpal
[i
* 3 + 2] = i
<< 3;
412 memset(hw
->DACpal
, 0, 768);
417 static void DAC1064_restore_1(WPMINFO2
) {
418 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
426 if ((inDAC1064(PMINFO DAC1064_XSYSPLLM
) != hw
->DACclk
[3]) ||
427 (inDAC1064(PMINFO DAC1064_XSYSPLLN
) != hw
->DACclk
[4]) ||
428 (inDAC1064(PMINFO DAC1064_XSYSPLLP
) != hw
->DACclk
[5])) {
429 outDAC1064(PMINFO DAC1064_XSYSPLLM
, hw
->DACclk
[3]);
430 outDAC1064(PMINFO DAC1064_XSYSPLLN
, hw
->DACclk
[4]);
431 outDAC1064(PMINFO DAC1064_XSYSPLLP
, hw
->DACclk
[5]);
436 for (i
= 0; i
< sizeof(MGA1064_DAC_regs
); i
++) {
437 if ((i
!= POS1064_XPIXCLKCTRL
) && (i
!= POS1064_XMISCCTRL
))
438 outDAC1064(PMINFO MGA1064_DAC_regs
[i
], hw
->DACreg
[i
]);
442 DAC1064_global_restore(PMINFO2
);
447 static void DAC1064_restore_2(WPMINFO2
) {
455 dprintk(KERN_DEBUG
"DAC1064regs ");
456 for (i
= 0; i
< sizeof(MGA1064_DAC_regs
); i
++) {
457 dprintk("R%02X=%02X ", MGA1064_DAC_regs
[i
], ACCESS_FBINFO(hw
).DACreg
[i
]);
458 if ((i
& 0x7) == 0x7) dprintk("\n" KERN_DEBUG
"continuing... ");
460 dprintk("\n" KERN_DEBUG
"DAC1064clk ");
461 for (i
= 0; i
< 6; i
++)
462 dprintk("C%02X=%02X ", i
, ACCESS_FBINFO(hw
).DACclk
[i
]);
467 static int m1064_compute(void* out
, struct my_timming
* m
) {
468 #define minfo ((struct matrox_fb_info*)out)
474 DAC1064_setpclk(PMINFO m
->pixclock
);
478 for (i
= 0; i
< 3; i
++)
479 outDAC1064(PMINFO M1064_XPIXPLLCM
+ i
, ACCESS_FBINFO(hw
).DACclk
[i
]);
480 for (tmout
= 500000; tmout
; tmout
--) {
481 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT
) & 0x40)
489 printk(KERN_ERR
"matroxfb: Pixel PLL not locked after 5 secs\n");
495 static struct matrox_altout m1064
= {
496 .name
= "Primary output",
497 .compute
= m1064_compute
,
500 #ifdef CONFIG_FB_MATROX_G
501 static int g450_compute(void* out
, struct my_timming
* m
) {
502 #define minfo ((struct matrox_fb_info*)out)
504 m
->mnp
= matroxfb_g450_setclk(PMINFO m
->pixclock
, (m
->crtc
== MATROXFB_SRC_CRTC1
) ? M_PIXEL_PLL_C
: M_VIDEO_PLL
);
506 m
->pixclock
= g450_mnp2f(PMINFO m
->mnp
);
513 static struct matrox_altout g450out
= {
514 .name
= "Primary output",
515 .compute
= g450_compute
,
519 #endif /* NEED_DAC1064 */
521 #ifdef CONFIG_FB_MATROX_MYSTIQUE
522 static int MGA1064_init(WPMINFO
struct my_timming
* m
) {
523 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
527 if (DAC1064_init_1(PMINFO m
)) return 1;
528 if (matroxfb_vgaHWinit(PMINFO m
)) return 1;
530 hw
->MiscOutReg
= 0xCB;
531 if (m
->sync
& FB_SYNC_HOR_HIGH_ACT
)
532 hw
->MiscOutReg
&= ~0x40;
533 if (m
->sync
& FB_SYNC_VERT_HIGH_ACT
)
534 hw
->MiscOutReg
&= ~0x80;
535 if (m
->sync
& FB_SYNC_COMP_HIGH_ACT
) /* should be only FB_SYNC_COMP */
536 hw
->CRTCEXT
[3] |= 0x40;
538 if (DAC1064_init_2(PMINFO m
)) return 1;
543 #ifdef CONFIG_FB_MATROX_G
544 static int MGAG100_init(WPMINFO
struct my_timming
* m
) {
545 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
549 if (DAC1064_init_1(PMINFO m
)) return 1;
550 hw
->MXoptionReg
&= ~0x2000;
551 if (matroxfb_vgaHWinit(PMINFO m
)) return 1;
553 hw
->MiscOutReg
= 0xEF;
554 if (m
->sync
& FB_SYNC_HOR_HIGH_ACT
)
555 hw
->MiscOutReg
&= ~0x40;
556 if (m
->sync
& FB_SYNC_VERT_HIGH_ACT
)
557 hw
->MiscOutReg
&= ~0x80;
558 if (m
->sync
& FB_SYNC_COMP_HIGH_ACT
) /* should be only FB_SYNC_COMP */
559 hw
->CRTCEXT
[3] |= 0x40;
561 if (DAC1064_init_2(PMINFO m
)) return 1;
566 #ifdef CONFIG_FB_MATROX_MYSTIQUE
567 static void MGA1064_ramdac_init(WPMINFO2
) {
571 /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */
572 ACCESS_FBINFO(features
.pll
.vco_freq_min
) = 62000;
573 ACCESS_FBINFO(features
.pll
.ref_freq
) = 14318;
574 ACCESS_FBINFO(features
.pll
.feed_div_min
) = 100;
575 ACCESS_FBINFO(features
.pll
.feed_div_max
) = 127;
576 ACCESS_FBINFO(features
.pll
.in_div_min
) = 1;
577 ACCESS_FBINFO(features
.pll
.in_div_max
) = 31;
578 ACCESS_FBINFO(features
.pll
.post_shift_max
) = 3;
579 ACCESS_FBINFO(features
.DAC1064
.xvrefctrl
) = DAC1064_XVREFCTRL_EXTERNAL
;
580 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
581 DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV3
| DAC1064_OPT_SCLK_PLL
, 133333);
585 #ifdef CONFIG_FB_MATROX_G
587 static int x7AF4
= 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
588 /* G100 wants 0x10, G200 SGRAM does not care... */
590 static int def50
= 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
593 static void MGAG100_progPixClock(CPMINFO
int flags
, int m
, int n
, int p
) {
600 outDAC1064(PMINFO M1064_XPIXCLKCTRL
, inDAC1064(PMINFO M1064_XPIXCLKCTRL
) | M1064_XPIXCLKCTRL_DIS
|
601 M1064_XPIXCLKCTRL_PLL_UP
);
603 case 0: reg
= M1064_XPIXPLLAM
; break;
604 case 1: reg
= M1064_XPIXPLLBM
; break;
605 default: reg
= M1064_XPIXPLLCM
; break;
607 outDAC1064(PMINFO reg
++, m
);
608 outDAC1064(PMINFO reg
++, n
);
609 outDAC1064(PMINFO reg
, p
);
610 selClk
= mga_inb(M_MISC_REG_READ
) & ~0xC;
611 /* there should be flags & 0x03 & case 0/1/else */
612 /* and we should first select source and after that we should wait for PLL */
613 /* and we are waiting for PLL with oscilator disabled... Is it right? */
614 switch (flags
& 0x03) {
616 case 0x01: selClk
|= 4; break;
617 default: selClk
|= 0x0C; break;
619 mga_outb(M_MISC_REG
, selClk
);
620 for (clk
= 500000; clk
; clk
--) {
621 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT
) & 0x40)
626 printk(KERN_ERR
"matroxfb: Pixel PLL%c not locked after usual time\n", (reg
-M1064_XPIXPLLAM
-2)/4 + 'A');
627 selClk
= inDAC1064(PMINFO M1064_XPIXCLKCTRL
) & ~M1064_XPIXCLKCTRL_SRC_MASK
;
628 switch (flags
& 0x0C) {
629 case 0x00: selClk
|= M1064_XPIXCLKCTRL_SRC_PCI
; break;
630 case 0x04: selClk
|= M1064_XPIXCLKCTRL_SRC_PLL
; break;
631 default: selClk
|= M1064_XPIXCLKCTRL_SRC_EXT
; break;
633 outDAC1064(PMINFO M1064_XPIXCLKCTRL
, selClk
);
634 outDAC1064(PMINFO M1064_XPIXCLKCTRL
, inDAC1064(PMINFO M1064_XPIXCLKCTRL
) & ~M1064_XPIXCLKCTRL_DIS
);
637 static void MGAG100_setPixClock(CPMINFO
int flags
, int freq
) {
638 unsigned int m
, n
, p
;
642 DAC1064_calcclock(PMINFO freq
, ACCESS_FBINFO(max_pixel_clock
), &m
, &n
, &p
);
643 MGAG100_progPixClock(PMINFO flags
, m
, n
, p
);
647 #ifdef CONFIG_FB_MATROX_MYSTIQUE
648 static int MGA1064_preinit(WPMINFO2
) {
649 static const int vxres_mystique
[] = { 512, 640, 768, 800, 832, 960,
650 1024, 1152, 1280, 1600, 1664, 1920,
652 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
656 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
657 ACCESS_FBINFO(capable
.text
) = 1;
658 ACCESS_FBINFO(capable
.vxres
) = vxres_mystique
;
660 ACCESS_FBINFO(outputs
[0]).output
= &m1064
;
661 ACCESS_FBINFO(outputs
[0]).src
= ACCESS_FBINFO(outputs
[0]).default_src
;
662 ACCESS_FBINFO(outputs
[0]).data
= MINFO
;
663 ACCESS_FBINFO(outputs
[0]).mode
= MATROXFB_OUTPUT_MODE_MONITOR
;
665 if (ACCESS_FBINFO(devflags
.noinit
))
666 return 0; /* do not modify settings */
667 hw
->MXoptionReg
&= 0xC0000100;
668 hw
->MXoptionReg
|= 0x00094E20;
669 if (ACCESS_FBINFO(devflags
.novga
))
670 hw
->MXoptionReg
&= ~0x00000100;
671 if (ACCESS_FBINFO(devflags
.nobios
))
672 hw
->MXoptionReg
&= ~0x40000000;
673 if (ACCESS_FBINFO(devflags
.nopciretry
))
674 hw
->MXoptionReg
|= 0x20000000;
675 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, hw
->MXoptionReg
);
676 mga_setr(M_SEQ_INDEX
, 0x01, 0x20);
677 mga_outl(M_CTLWTST
, 0x00000000);
679 mga_outl(M_MACCESS
, 0x00008000);
681 mga_outl(M_MACCESS
, 0x0000C000);
685 static void MGA1064_reset(WPMINFO2
) {
689 MGA1064_ramdac_init(PMINFO2
);
693 #ifdef CONFIG_FB_MATROX_G
694 static void g450_mclk_init(WPMINFO2
) {
695 /* switch all clocks to PCI source */
696 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, ACCESS_FBINFO(hw
).MXoptionReg
| 4);
697 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION3_REG
, ACCESS_FBINFO(values
).reg
.opt3
& ~0x00300C03);
698 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, ACCESS_FBINFO(hw
).MXoptionReg
);
700 if (((ACCESS_FBINFO(values
).reg
.opt3
& 0x000003) == 0x000003) ||
701 ((ACCESS_FBINFO(values
).reg
.opt3
& 0x000C00) == 0x000C00) ||
702 ((ACCESS_FBINFO(values
).reg
.opt3
& 0x300000) == 0x300000)) {
703 matroxfb_g450_setclk(PMINFO
ACCESS_FBINFO(values
.pll
.video
), M_VIDEO_PLL
);
708 matroxfb_DAC_lock_irqsave(flags
);
709 pwr
= inDAC1064(PMINFO M1064_XPWRCTRL
) & ~0x02;
710 outDAC1064(PMINFO M1064_XPWRCTRL
, pwr
);
711 matroxfb_DAC_unlock_irqrestore(flags
);
713 matroxfb_g450_setclk(PMINFO
ACCESS_FBINFO(values
.pll
.system
), M_SYSTEM_PLL
);
715 /* switch clocks to their real PLL source(s) */
716 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, ACCESS_FBINFO(hw
).MXoptionReg
| 4);
717 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION3_REG
, ACCESS_FBINFO(values
).reg
.opt3
);
718 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, ACCESS_FBINFO(hw
).MXoptionReg
);
722 static void g450_memory_init(WPMINFO2
) {
723 /* disable memory refresh */
724 ACCESS_FBINFO(hw
).MXoptionReg
&= ~0x001F8000;
725 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, ACCESS_FBINFO(hw
).MXoptionReg
);
727 /* set memory interface parameters */
728 ACCESS_FBINFO(hw
).MXoptionReg
&= ~0x00207E00;
729 ACCESS_FBINFO(hw
).MXoptionReg
|= 0x00207E00 & ACCESS_FBINFO(values
).reg
.opt
;
730 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, ACCESS_FBINFO(hw
).MXoptionReg
);
731 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION2_REG
, ACCESS_FBINFO(values
).reg
.opt2
);
733 mga_outl(M_CTLWTST
, ACCESS_FBINFO(values
).reg
.mctlwtst
);
735 /* first set up memory interface with disabled memory interface clocks */
736 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_MEMMISC_REG
, ACCESS_FBINFO(values
).reg
.memmisc
& ~0x80000000U
);
737 mga_outl(M_MEMRDBK
, ACCESS_FBINFO(values
).reg
.memrdbk
);
738 mga_outl(M_MACCESS
, ACCESS_FBINFO(values
).reg
.maccess
);
739 /* start memory clocks */
740 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_MEMMISC_REG
, ACCESS_FBINFO(values
).reg
.memmisc
| 0x80000000U
);
744 if (ACCESS_FBINFO(values
).memory
.ddr
&& (!ACCESS_FBINFO(values
).memory
.emrswen
|| !ACCESS_FBINFO(values
).memory
.dll
)) {
745 mga_outl(M_MEMRDBK
, ACCESS_FBINFO(values
).reg
.memrdbk
& ~0x1000);
747 mga_outl(M_MACCESS
, ACCESS_FBINFO(values
).reg
.maccess
| 0x8000);
751 ACCESS_FBINFO(hw
).MXoptionReg
|= 0x001F8000 & ACCESS_FBINFO(values
).reg
.opt
;
752 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, ACCESS_FBINFO(hw
).MXoptionReg
);
754 /* value is written to memory chips only if old != new */
755 mga_outl(M_PLNWT
, 0);
756 mga_outl(M_PLNWT
, ~0);
758 if (ACCESS_FBINFO(values
).reg
.mctlwtst
!= ACCESS_FBINFO(values
).reg
.mctlwtst_core
) {
759 mga_outl(M_CTLWTST
, ACCESS_FBINFO(values
).reg
.mctlwtst_core
);
764 static void g450_preinit(WPMINFO2
) {
769 /* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */
770 ACCESS_FBINFO(hw
).MXoptionReg
&= 0xC0000100;
771 ACCESS_FBINFO(hw
).MXoptionReg
|= 0x00000020;
772 if (ACCESS_FBINFO(devflags
.novga
))
773 ACCESS_FBINFO(hw
).MXoptionReg
&= ~0x00000100;
774 if (ACCESS_FBINFO(devflags
.nobios
))
775 ACCESS_FBINFO(hw
).MXoptionReg
&= ~0x40000000;
776 if (ACCESS_FBINFO(devflags
.nopciretry
))
777 ACCESS_FBINFO(hw
).MXoptionReg
|= 0x20000000;
778 ACCESS_FBINFO(hw
).MXoptionReg
|= ACCESS_FBINFO(values
).reg
.opt
& 0x03400040;
779 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, ACCESS_FBINFO(hw
).MXoptionReg
);
781 /* Init system clocks */
784 c2ctl
= mga_inl(M_C2CTL
);
785 mga_outl(M_C2CTL
, c2ctl
& ~1);
787 curctl
= inDAC1064(PMINFO M1064_XCURCTRL
);
788 outDAC1064(PMINFO M1064_XCURCTRL
, 0);
790 c1ctl
= mga_readr(M_SEQ_INDEX
, 1);
791 mga_setr(M_SEQ_INDEX
, 1, c1ctl
| 0x20);
793 g450_mclk_init(PMINFO2
);
794 g450_memory_init(PMINFO2
);
796 /* set legacy VGA clock sources for DOSEmu or VMware... */
797 matroxfb_g450_setclk(PMINFO
25175, M_PIXEL_PLL_A
);
798 matroxfb_g450_setclk(PMINFO
28322, M_PIXEL_PLL_B
);
801 mga_setr(M_SEQ_INDEX
, 1, c1ctl
);
804 outDAC1064(PMINFO M1064_XCURCTRL
, curctl
);
807 mga_outl(M_C2CTL
, c2ctl
);
812 static int MGAG100_preinit(WPMINFO2
) {
813 static const int vxres_g100
[] = { 512, 640, 768, 800, 832, 960,
814 1024, 1152, 1280, 1600, 1664, 1920,
816 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
825 /* there are some instabilities if in_div > 19 && vco < 61000 */
826 if (ACCESS_FBINFO(devflags
.g450dac
)) {
827 ACCESS_FBINFO(features
.pll
.vco_freq_min
) = 130000; /* my sample: >118 */
829 ACCESS_FBINFO(features
.pll
.vco_freq_min
) = 62000;
831 if (!ACCESS_FBINFO(features
.pll
.ref_freq
)) {
832 ACCESS_FBINFO(features
.pll
.ref_freq
) = 27000;
834 ACCESS_FBINFO(features
.pll
.feed_div_min
) = 7;
835 ACCESS_FBINFO(features
.pll
.feed_div_max
) = 127;
836 ACCESS_FBINFO(features
.pll
.in_div_min
) = 1;
837 ACCESS_FBINFO(features
.pll
.in_div_max
) = 31;
838 ACCESS_FBINFO(features
.pll
.post_shift_max
) = 3;
839 ACCESS_FBINFO(features
.DAC1064
.xvrefctrl
) = DAC1064_XVREFCTRL_G100_DEFAULT
;
840 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
841 ACCESS_FBINFO(capable
.text
) = 1;
842 ACCESS_FBINFO(capable
.vxres
) = vxres_g100
;
843 ACCESS_FBINFO(capable
.plnwt
) = ACCESS_FBINFO(devflags
.accelerator
) == FB_ACCEL_MATROX_MGAG100
844 ? ACCESS_FBINFO(devflags
.sgram
) : 1;
846 #ifdef CONFIG_FB_MATROX_G
847 if (ACCESS_FBINFO(devflags
.g450dac
)) {
848 ACCESS_FBINFO(outputs
[0]).output
= &g450out
;
852 ACCESS_FBINFO(outputs
[0]).output
= &m1064
;
854 ACCESS_FBINFO(outputs
[0]).src
= ACCESS_FBINFO(outputs
[0]).default_src
;
855 ACCESS_FBINFO(outputs
[0]).data
= MINFO
;
856 ACCESS_FBINFO(outputs
[0]).mode
= MATROXFB_OUTPUT_MODE_MONITOR
;
858 if (ACCESS_FBINFO(devflags
.g450dac
)) {
859 /* we must do this always, BIOS does not do it for us
860 and accelerator dies without it */
863 if (ACCESS_FBINFO(devflags
.noinit
))
865 if (ACCESS_FBINFO(devflags
.g450dac
)) {
866 g450_preinit(PMINFO2
);
869 hw
->MXoptionReg
&= 0xC0000100;
870 hw
->MXoptionReg
|= 0x00000020;
871 if (ACCESS_FBINFO(devflags
.novga
))
872 hw
->MXoptionReg
&= ~0x00000100;
873 if (ACCESS_FBINFO(devflags
.nobios
))
874 hw
->MXoptionReg
&= ~0x40000000;
875 if (ACCESS_FBINFO(devflags
.nopciretry
))
876 hw
->MXoptionReg
|= 0x20000000;
877 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, hw
->MXoptionReg
);
878 DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV3
| DAC1064_OPT_SCLK_PCI
, 133333);
880 if (ACCESS_FBINFO(devflags
.accelerator
) == FB_ACCEL_MATROX_MGAG100
) {
881 pci_read_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION2_REG
, ®50
);
883 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION2_REG
, reg50
);
885 hw
->MXoptionReg
|= 0x1080;
886 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, hw
->MXoptionReg
);
887 mga_outl(M_CTLWTST
, ACCESS_FBINFO(values
).reg
.mctlwtst
);
889 mga_outb(0x1C05, 0x00);
890 mga_outb(0x1C05, 0x80);
892 mga_outb(0x1C05, 0x40);
893 mga_outb(0x1C05, 0xC0);
897 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION2_REG
, reg50
);
898 /* it should help with G100 */
899 mga_outb(M_GRAPHICS_INDEX
, 6);
900 mga_outb(M_GRAPHICS_DATA
, (mga_inb(M_GRAPHICS_DATA
) & 3) | 4);
901 mga_setr(M_EXTVGA_INDEX
, 0x03, 0x81);
902 mga_setr(M_EXTVGA_INDEX
, 0x04, 0x00);
903 mga_writeb(ACCESS_FBINFO(video
.vbase
), 0x0000, 0xAA);
904 mga_writeb(ACCESS_FBINFO(video
.vbase
), 0x0800, 0x55);
905 mga_writeb(ACCESS_FBINFO(video
.vbase
), 0x4000, 0x55);
907 if (mga_readb(ACCESS_FBINFO(video
.vbase
), 0x0000) != 0xAA) {
908 hw
->MXoptionReg
&= ~0x1000;
911 hw
->MXoptionReg
|= 0x00078020;
912 } else if (ACCESS_FBINFO(devflags
.accelerator
) == FB_ACCEL_MATROX_MGAG200
) {
913 pci_read_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION2_REG
, ®50
);
915 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION2_REG
, reg50
);
917 if (ACCESS_FBINFO(devflags
.memtype
) == -1)
918 hw
->MXoptionReg
|= ACCESS_FBINFO(values
).reg
.opt
& 0x1C00;
920 hw
->MXoptionReg
|= (ACCESS_FBINFO(devflags
.memtype
) & 7) << 10;
921 if (ACCESS_FBINFO(devflags
.sgram
))
922 hw
->MXoptionReg
|= 0x4000;
923 mga_outl(M_CTLWTST
, ACCESS_FBINFO(values
).reg
.mctlwtst
);
924 mga_outl(M_MEMRDBK
, ACCESS_FBINFO(values
).reg
.memrdbk
);
926 mga_outl(M_MACCESS
, 0x00000000);
927 mga_outl(M_MACCESS
, 0x00008000);
929 mga_outw(M_MEMRDBK
, ACCESS_FBINFO(values
).reg
.memrdbk
);
930 hw
->MXoptionReg
|= 0x00078020;
932 pci_read_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION2_REG
, ®50
);
933 reg50
&= ~0x00000100;
935 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION2_REG
, reg50
);
937 if (ACCESS_FBINFO(devflags
.memtype
) == -1)
938 hw
->MXoptionReg
|= ACCESS_FBINFO(values
).reg
.opt
& 0x1C00;
940 hw
->MXoptionReg
|= (ACCESS_FBINFO(devflags
.memtype
) & 7) << 10;
941 if (ACCESS_FBINFO(devflags
.sgram
))
942 hw
->MXoptionReg
|= 0x4000;
943 mga_outl(M_CTLWTST
, ACCESS_FBINFO(values
).reg
.mctlwtst
);
944 mga_outl(M_MEMRDBK
, ACCESS_FBINFO(values
).reg
.memrdbk
);
946 mga_outl(M_MACCESS
, 0x00000000);
947 mga_outl(M_MACCESS
, 0x00008000);
949 mga_outl(M_MEMRDBK
, ACCESS_FBINFO(values
).reg
.memrdbk
);
950 hw
->MXoptionReg
|= 0x00040020;
952 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, hw
->MXoptionReg
);
956 static void MGAG100_reset(WPMINFO2
) {
958 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
963 #ifdef G100_BROKEN_IBM_82351
966 find
1014/22 (IBM
/82351); /* if found and bridging Matrox, do some strange stuff */
967 pci_read_config_byte(ibm
, PCI_SECONDARY_BUS
, &b
);
968 if (b
== ACCESS_FBINFO(pcidev
)->bus
->number
) {
969 pci_write_config_byte(ibm
, PCI_COMMAND
+1, 0); /* disable back-to-back & SERR */
970 pci_write_config_byte(ibm
, 0x41, 0xF4); /* ??? */
971 pci_write_config_byte(ibm
, PCI_IO_BASE
, 0xF0); /* ??? */
972 pci_write_config_byte(ibm
, PCI_IO_LIMIT
, 0x00); /* ??? */
975 if (!ACCESS_FBINFO(devflags
.noinit
)) {
977 hw
->MXoptionReg
|= 0x40; /* FIXME... */
978 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, hw
->MXoptionReg
);
980 mga_setr(M_EXTVGA_INDEX
, 0x06, 0x00);
983 if (ACCESS_FBINFO(devflags
.g450dac
)) {
984 /* either leave MCLK as is... or they were set in preinit */
985 hw
->DACclk
[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM
);
986 hw
->DACclk
[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN
);
987 hw
->DACclk
[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP
);
989 DAC1064_setmclk(PMINFO DAC1064_OPT_RESERVED
| DAC1064_OPT_MDIV2
| DAC1064_OPT_GDIV1
| DAC1064_OPT_SCLK_PLL
, 133333);
991 if (ACCESS_FBINFO(devflags
.accelerator
) == FB_ACCEL_MATROX_MGAG400
) {
992 if (ACCESS_FBINFO(devflags
.dfp_type
) == -1) {
993 ACCESS_FBINFO(devflags
.dfp_type
) = inDAC1064(PMINFO
0x1F);
996 if (ACCESS_FBINFO(devflags
.noinit
))
998 if (ACCESS_FBINFO(devflags
.g450dac
)) {
1000 MGAG100_setPixClock(PMINFO
4, 25175);
1001 MGAG100_setPixClock(PMINFO
5, 28322);
1003 b
= inDAC1064(PMINFO M1064_XGENIODATA
) & ~1;
1004 outDAC1064(PMINFO M1064_XGENIODATA
, b
);
1005 b
= inDAC1064(PMINFO M1064_XGENIOCTRL
) | 1;
1006 outDAC1064(PMINFO M1064_XGENIOCTRL
, b
);
1012 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1013 static void MGA1064_restore(WPMINFO2
) {
1015 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
1023 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, hw
->MXoptionReg
);
1024 mga_outb(M_IEN
, 0x00);
1025 mga_outb(M_CACHEFLUSH
, 0x00);
1029 DAC1064_restore_1(PMINFO2
);
1030 matroxfb_vgaHWrestore(PMINFO2
);
1031 ACCESS_FBINFO(crtc1
.panpos
) = -1;
1032 for (i
= 0; i
< 6; i
++)
1033 mga_setr(M_EXTVGA_INDEX
, i
, hw
->CRTCEXT
[i
]);
1034 DAC1064_restore_2(PMINFO2
);
1038 #ifdef CONFIG_FB_MATROX_G
1039 static void MGAG100_restore(WPMINFO2
) {
1041 struct matrox_hw_state
* hw
= &ACCESS_FBINFO(hw
);
1049 pci_write_config_dword(ACCESS_FBINFO(pcidev
), PCI_OPTION_REG
, hw
->MXoptionReg
);
1052 DAC1064_restore_1(PMINFO2
);
1053 matroxfb_vgaHWrestore(PMINFO2
);
1054 #ifdef CONFIG_FB_MATROX_32MB
1055 if (ACCESS_FBINFO(devflags
.support32MB
))
1056 mga_setr(M_EXTVGA_INDEX
, 8, hw
->CRTCEXT
[8]);
1058 ACCESS_FBINFO(crtc1
.panpos
) = -1;
1059 for (i
= 0; i
< 6; i
++)
1060 mga_setr(M_EXTVGA_INDEX
, i
, hw
->CRTCEXT
[i
]);
1061 DAC1064_restore_2(PMINFO2
);
1065 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1066 struct matrox_switch matrox_mystique
= {
1067 MGA1064_preinit
, MGA1064_reset
, MGA1064_init
, MGA1064_restore
,
1069 EXPORT_SYMBOL(matrox_mystique
);
1072 #ifdef CONFIG_FB_MATROX_G
1073 struct matrox_switch matrox_G100
= {
1074 MGAG100_preinit
, MGAG100_reset
, MGAG100_init
, MGAG100_restore
,
1076 EXPORT_SYMBOL(matrox_G100
);
1080 EXPORT_SYMBOL(DAC1064_global_init
);
1081 EXPORT_SYMBOL(DAC1064_global_restore
);
1083 MODULE_LICENSE("GPL");