Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[linux-2.6] / drivers / video / matrox / matroxfb_DAC1064.c
1 /*
2  *
3  * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
4  *
5  * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
6  *
7  * Portions Copyright (c) 2001 Matrox Graphics Inc.
8  *
9  * Version: 1.65 2002/08/14
10  *
11  * See matroxfb_base.c for contributors.
12  *
13  */
14
15 /* make checkconfig does not walk through include tree :-( */
16 #include <linux/config.h>
17
18 #include "matroxfb_DAC1064.h"
19 #include "matroxfb_misc.h"
20 #include "matroxfb_accel.h"
21 #include "g450_pll.h"
22 #include <linux/matroxfb.h>
23
24 #ifdef NEED_DAC1064
25 #define outDAC1064 matroxfb_DAC_out
26 #define inDAC1064 matroxfb_DAC_in
27
28 #define DAC1064_OPT_SCLK_PCI    0x00
29 #define DAC1064_OPT_SCLK_PLL    0x01
30 #define DAC1064_OPT_SCLK_EXT    0x02
31 #define DAC1064_OPT_SCLK_MASK   0x03
32 #define DAC1064_OPT_GDIV1       0x04    /* maybe it is GDIV2 on G100 ?! */
33 #define DAC1064_OPT_GDIV3       0x00
34 #define DAC1064_OPT_MDIV1       0x08
35 #define DAC1064_OPT_MDIV2       0x00
36 #define DAC1064_OPT_RESERVED    0x10
37
38 static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {
39         unsigned int fvco;
40         unsigned int p;
41
42         DBG(__FUNCTION__)
43         
44         /* only for devices older than G450 */
45
46         fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p);
47         
48         p = (1 << p) - 1;
49         if (fvco <= 100000)
50                 ;
51         else if (fvco <= 140000)
52                 p |= 0x08;
53         else if (fvco <= 180000)
54                 p |= 0x10;
55         else
56                 p |= 0x18;
57         *post = p;
58 }
59
60 /* they must be in POS order */
61 static const unsigned char MGA1064_DAC_regs[] = {
62                 M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,
63                 M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,
64                 M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,
65                 M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,
66                 DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,
67                 M1064_XMISCCTRL,
68                 M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,
69                 M1064_XCRCBITSEL,
70                 M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };
71
72 static const unsigned char MGA1064_DAC[] = {
73                 0x00, 0x00, M1064_XCURCTRL_DIS,
74                 0x00, 0x00, 0x00,       /* black */
75                 0xFF, 0xFF, 0xFF,       /* white */
76                 0xFF, 0x00, 0x00,       /* red */
77                 0x00, 0,
78                 M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,
79                 M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,
80                 M1064_XMISCCTRL_DAC_8BIT,
81                 0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,
82                 0x00,
83                 0x00, 0x00, 0xFF, 0xFF};
84
85 static void DAC1064_setpclk(WPMINFO unsigned long fout) {
86         unsigned int m, n, p;
87
88         DBG(__FUNCTION__)
89
90         DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
91         ACCESS_FBINFO(hw).DACclk[0] = m;
92         ACCESS_FBINFO(hw).DACclk[1] = n;
93         ACCESS_FBINFO(hw).DACclk[2] = p;
94 }
95
96 static void DAC1064_setmclk(WPMINFO int oscinfo, unsigned long fmem) {
97         u_int32_t mx;
98         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
99
100         DBG(__FUNCTION__)
101
102         if (ACCESS_FBINFO(devflags.noinit)) {
103                 /* read MCLK and give up... */
104                 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
105                 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
106                 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
107                 return;
108         }
109         mx = hw->MXoptionReg | 0x00000004;
110         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
111         mx &= ~0x000000BB;
112         if (oscinfo & DAC1064_OPT_GDIV1)
113                 mx |= 0x00000008;
114         if (oscinfo & DAC1064_OPT_MDIV1)
115                 mx |= 0x00000010;
116         if (oscinfo & DAC1064_OPT_RESERVED)
117                 mx |= 0x00000080;
118         if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {
119                 /* select PCI clock until we have setup oscilator... */
120                 int clk;
121                 unsigned int m, n, p;
122
123                 /* powerup system PLL, select PCI clock */
124                 mx |= 0x00000020;
125                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
126                 mx &= ~0x00000004;
127                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
128
129                 /* !!! you must not access device if MCLK is not running !!!
130                    Doing so cause immediate PCI lockup :-( Maybe they should
131                    generate ABORT or I/O (parity...) error and Linux should
132                    recover from this... (kill driver/process). But world is not
133                    perfect... */
134                 /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
135                    select PLL... because of PLL can be stopped at this time) */
136                 DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
137                 outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m);
138                 outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n);
139                 outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p);
140                 for (clk = 65536; clk; --clk) {
141                         if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40)
142                                 break;
143                 }
144                 if (!clk)
145                         printk(KERN_ERR "matroxfb: aiee, SYSPLL not locked\n");
146                 /* select PLL */
147                 mx |= 0x00000005;
148         } else {
149                 /* select specified system clock source */
150                 mx |= oscinfo & DAC1064_OPT_SCLK_MASK;
151         }
152         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
153         mx &= ~0x00000004;
154         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);
155         hw->MXoptionReg = mx;
156 }
157
158 #ifdef CONFIG_FB_MATROX_G
159 static void g450_set_plls(WPMINFO2) {
160         u_int32_t c2_ctl;
161         unsigned int pxc;
162         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
163         int pixelmnp;
164         int videomnp;
165         
166         c2_ctl = hw->crtc2.ctl & ~0x4007;       /* Clear PLL + enable for CRTC2 */
167         c2_ctl |= 0x0001;                       /* Enable CRTC2 */
168         hw->DACreg[POS1064_XPWRCTRL] &= ~0x02;  /* Stop VIDEO PLL */
169         pixelmnp = ACCESS_FBINFO(crtc1).mnp;
170         videomnp = ACCESS_FBINFO(crtc2).mnp;
171         if (videomnp < 0) {
172                 c2_ctl &= ~0x0001;                      /* Disable CRTC2 */
173                 hw->DACreg[POS1064_XPWRCTRL] &= ~0x10;  /* Powerdown CRTC2 */
174         } else if (ACCESS_FBINFO(crtc2).pixclock == ACCESS_FBINFO(features).pll.ref_freq) {
175                 c2_ctl |=  0x4002;      /* Use reference directly */
176         } else if (videomnp == pixelmnp) {
177                 c2_ctl |=  0x0004;      /* Use pixel PLL */
178         } else {
179                 if (0 == ((videomnp ^ pixelmnp) & 0xFFFFFF00)) {
180                         /* PIXEL and VIDEO PLL must not use same frequency. We modify N
181                            of PIXEL PLL in such case because of VIDEO PLL may be source
182                            of TVO clocks, and chroma subcarrier is derived from its
183                            pixel clocks */
184                         pixelmnp += 0x000100;
185                 }
186                 c2_ctl |=  0x0006;      /* Use video PLL */
187                 hw->DACreg[POS1064_XPWRCTRL] |= 0x02;
188                 
189                 outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
190                 matroxfb_g450_setpll_cond(PMINFO videomnp, M_VIDEO_PLL);
191         }
192
193         hw->DACreg[POS1064_XPIXCLKCTRL] &= ~M1064_XPIXCLKCTRL_PLL_UP;
194         if (pixelmnp >= 0) {
195                 hw->DACreg[POS1064_XPIXCLKCTRL] |= M1064_XPIXCLKCTRL_PLL_UP;
196                 
197                 outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
198                 matroxfb_g450_setpll_cond(PMINFO pixelmnp, M_PIXEL_PLL_C);
199         }
200         if (c2_ctl != hw->crtc2.ctl) {
201                 hw->crtc2.ctl = c2_ctl;
202                 mga_outl(0x3C10, c2_ctl);
203         }
204
205         pxc = ACCESS_FBINFO(crtc1).pixclock;
206         if (pxc == 0 || ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC2) {
207                 pxc = ACCESS_FBINFO(crtc2).pixclock;
208         }
209         if (ACCESS_FBINFO(chip) == MGA_G550) {
210                 if (pxc < 45000) {
211                         hw->DACreg[POS1064_XPANMODE] = 0x00;    /* 0-50 */
212                 } else if (pxc < 55000) {
213                         hw->DACreg[POS1064_XPANMODE] = 0x08;    /* 34-62 */
214                 } else if (pxc < 70000) {
215                         hw->DACreg[POS1064_XPANMODE] = 0x10;    /* 42-78 */
216                 } else if (pxc < 85000) {
217                         hw->DACreg[POS1064_XPANMODE] = 0x18;    /* 62-92 */
218                 } else if (pxc < 100000) {
219                         hw->DACreg[POS1064_XPANMODE] = 0x20;    /* 74-108 */
220                 } else if (pxc < 115000) {
221                         hw->DACreg[POS1064_XPANMODE] = 0x28;    /* 94-122 */
222                 } else if (pxc < 125000) {
223                         hw->DACreg[POS1064_XPANMODE] = 0x30;    /* 108-132 */
224                 } else {
225                         hw->DACreg[POS1064_XPANMODE] = 0x38;    /* 120-168 */
226                 }
227         } else {
228                 /* G450 */
229                 if (pxc < 45000) {
230                         hw->DACreg[POS1064_XPANMODE] = 0x00;    /* 0-54 */
231                 } else if (pxc < 65000) {
232                         hw->DACreg[POS1064_XPANMODE] = 0x08;    /* 38-70 */
233                 } else if (pxc < 85000) {
234                         hw->DACreg[POS1064_XPANMODE] = 0x10;    /* 56-96 */
235                 } else if (pxc < 105000) {
236                         hw->DACreg[POS1064_XPANMODE] = 0x18;    /* 80-114 */
237                 } else if (pxc < 135000) {
238                         hw->DACreg[POS1064_XPANMODE] = 0x20;    /* 102-144 */
239                 } else if (pxc < 160000) {
240                         hw->DACreg[POS1064_XPANMODE] = 0x28;    /* 132-166 */
241                 } else if (pxc < 175000) {
242                         hw->DACreg[POS1064_XPANMODE] = 0x30;    /* 154-182 */
243                 } else {
244                         hw->DACreg[POS1064_XPANMODE] = 0x38;    /* 170-204 */
245                 }
246         }
247 }
248 #endif
249
250 void DAC1064_global_init(WPMINFO2) {
251         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
252
253         hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;
254         hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
255         hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
256 #ifdef CONFIG_FB_MATROX_G
257         if (ACCESS_FBINFO(devflags.g450dac)) {
258                 hw->DACreg[POS1064_XPWRCTRL] = 0x1F;    /* powerup everything */
259                 hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */
260                 hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
261                 switch (ACCESS_FBINFO(outputs[0]).src) {
262                         case MATROXFB_SRC_CRTC1:
263                         case MATROXFB_SRC_CRTC2:
264                                 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x01;        /* enable output; CRTC1/2 selection is in CRTC2 ctl */
265                                 break;
266                         case MATROXFB_SRC_NONE:
267                                 hw->DACreg[POS1064_XMISCCTRL] &= ~M1064_XMISCCTRL_DAC_EN;
268                                 break;
269                 }
270                 switch (ACCESS_FBINFO(outputs[1]).src) {
271                         case MATROXFB_SRC_CRTC1:
272                                 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x04;
273                                 break;
274                         case MATROXFB_SRC_CRTC2:
275                                 if (ACCESS_FBINFO(outputs[1]).mode == MATROXFB_OUTPUT_MODE_MONITOR) {
276                                         hw->DACreg[POS1064_XOUTPUTCONN] |= 0x08;
277                                 } else {
278                                         hw->DACreg[POS1064_XOUTPUTCONN] |= 0x0C;
279                                 }
280                                 break;
281                         case MATROXFB_SRC_NONE:
282                                 hw->DACreg[POS1064_XPWRCTRL] &= ~0x01;          /* Poweroff DAC2 */
283                                 break;
284                 }
285                 switch (ACCESS_FBINFO(outputs[2]).src) {
286                         case MATROXFB_SRC_CRTC1:
287                                 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x20;
288                                 break;
289                         case MATROXFB_SRC_CRTC2:
290                                 hw->DACreg[POS1064_XOUTPUTCONN] |= 0x40;
291                                 break;
292                         case MATROXFB_SRC_NONE:
293 #if 0
294                                 /* HELP! If we boot without DFP connected to DVI, we can
295                                    poweroff TMDS. But if we boot with DFP connected,
296                                    TMDS generated clocks are used instead of ALL pixclocks
297                                    available... If someone knows which register
298                                    handles it, please reveal this secret to me... */                    
299                                 hw->DACreg[POS1064_XPWRCTRL] &= ~0x04;          /* Poweroff TMDS */
300 #endif                          
301                                 break;
302                 }
303                 /* Now set timming related variables... */
304                 g450_set_plls(PMINFO2);
305         } else
306 #endif
307         {
308                 if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) {
309                         hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
310                         hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
311                 } else if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) {
312                         hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
313                 } else if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1)
314                         hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;
315                 else
316                         hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;
317
318                 if (ACCESS_FBINFO(outputs[0]).src != MATROXFB_SRC_NONE)
319                         hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
320         }
321 }
322
323 void DAC1064_global_restore(WPMINFO2) {
324         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
325
326         outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);
327         outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
328         if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
329                 outDAC1064(PMINFO 0x20, 0x04);
330                 outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type));
331                 if (ACCESS_FBINFO(devflags.g450dac)) {
332                         outDAC1064(PMINFO M1064_XSYNCCTRL, 0xCC);
333                         outDAC1064(PMINFO M1064_XPWRCTRL, hw->DACreg[POS1064_XPWRCTRL]);
334                         outDAC1064(PMINFO M1064_XPANMODE, hw->DACreg[POS1064_XPANMODE]);
335                         outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
336                 }
337         }
338 }
339
340 static int DAC1064_init_1(WPMINFO struct my_timming* m) {
341         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
342
343         DBG(__FUNCTION__)
344
345         memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
346         switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) {
347                 /* case 4: not supported by MGA1064 DAC */
348                 case 8:
349                         hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
350                         break;
351                 case 16:
352                         if (ACCESS_FBINFO(fbcon).var.green.length == 5)
353                                 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
354                         else
355                                 hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
356                         break;
357                 case 24:
358                         hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
359                         break;
360                 case 32:
361                         hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;
362                         break;
363                 default:
364                         return 1;       /* unsupported depth */
365         }
366         hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl);
367         hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;
368         hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;
369         hw->DACreg[POS1064_XCURADDL] = 0;
370         hw->DACreg[POS1064_XCURADDH] = 0;
371
372         DAC1064_global_init(PMINFO2);
373         return 0;
374 }
375
376 static int DAC1064_init_2(WPMINFO struct my_timming* m) {
377         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
378
379         DBG(__FUNCTION__)
380
381         if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 16) {     /* 256 entries */
382                 int i;
383
384                 for (i = 0; i < 256; i++) {
385                         hw->DACpal[i * 3 + 0] = i;
386                         hw->DACpal[i * 3 + 1] = i;
387                         hw->DACpal[i * 3 + 2] = i;
388                 }
389         } else if (ACCESS_FBINFO(fbcon).var.bits_per_pixel > 8) {
390                 if (ACCESS_FBINFO(fbcon).var.green.length == 5) {       /* 0..31, 128..159 */
391                         int i;
392
393                         for (i = 0; i < 32; i++) {
394                                 /* with p15 == 0 */
395                                 hw->DACpal[i * 3 + 0] = i << 3;
396                                 hw->DACpal[i * 3 + 1] = i << 3;
397                                 hw->DACpal[i * 3 + 2] = i << 3;
398                                 /* with p15 == 1 */
399                                 hw->DACpal[(i + 128) * 3 + 0] = i << 3;
400                                 hw->DACpal[(i + 128) * 3 + 1] = i << 3;
401                                 hw->DACpal[(i + 128) * 3 + 2] = i << 3;
402                         }
403                 } else {
404                         int i;
405
406                         for (i = 0; i < 64; i++) {              /* 0..63 */
407                                 hw->DACpal[i * 3 + 0] = i << 3;
408                                 hw->DACpal[i * 3 + 1] = i << 2;
409                                 hw->DACpal[i * 3 + 2] = i << 3;
410                         }
411                 }
412         } else {
413                 memset(hw->DACpal, 0, 768);
414         }
415         return 0;
416 }
417
418 static void DAC1064_restore_1(WPMINFO2) {
419         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
420
421         CRITFLAGS
422
423         DBG(__FUNCTION__)
424
425         CRITBEGIN
426
427         if ((inDAC1064(PMINFO DAC1064_XSYSPLLM) != hw->DACclk[3]) ||
428             (inDAC1064(PMINFO DAC1064_XSYSPLLN) != hw->DACclk[4]) ||
429             (inDAC1064(PMINFO DAC1064_XSYSPLLP) != hw->DACclk[5])) {
430                 outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
431                 outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
432                 outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
433         }
434         {
435                 unsigned int i;
436
437                 for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
438                         if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))
439                                 outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);
440                 }
441         }
442
443         DAC1064_global_restore(PMINFO2);
444
445         CRITEND
446 };
447
448 static void DAC1064_restore_2(WPMINFO2) {
449 #ifdef DEBUG
450         unsigned int i;
451 #endif
452
453         DBG(__FUNCTION__)
454
455 #ifdef DEBUG
456         dprintk(KERN_DEBUG "DAC1064regs ");
457         for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
458                 dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]);
459                 if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
460         }
461         dprintk("\n" KERN_DEBUG "DAC1064clk ");
462         for (i = 0; i < 6; i++)
463                 dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]);
464         dprintk("\n");
465 #endif
466 }
467
468 static int m1064_compute(void* out, struct my_timming* m) {
469 #define minfo ((struct matrox_fb_info*)out)
470         {
471                 int i;
472                 int tmout;
473                 CRITFLAGS
474
475                 DAC1064_setpclk(PMINFO m->pixclock);
476
477                 CRITBEGIN
478
479                 for (i = 0; i < 3; i++)
480                         outDAC1064(PMINFO M1064_XPIXPLLCM + i, ACCESS_FBINFO(hw).DACclk[i]);
481                 for (tmout = 500000; tmout; tmout--) {
482                         if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
483                                 break;
484                         udelay(10);
485                 };
486
487                 CRITEND
488
489                 if (!tmout)
490                         printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
491         }
492 #undef minfo
493         return 0;
494 }
495
496 static struct matrox_altout m1064 = {
497         .name    = "Primary output",
498         .compute = m1064_compute,
499 };
500
501 #ifdef CONFIG_FB_MATROX_G
502 static int g450_compute(void* out, struct my_timming* m) {
503 #define minfo ((struct matrox_fb_info*)out)
504         if (m->mnp < 0) {
505                 m->mnp = matroxfb_g450_setclk(PMINFO m->pixclock, (m->crtc == MATROXFB_SRC_CRTC1) ? M_PIXEL_PLL_C : M_VIDEO_PLL);
506                 if (m->mnp >= 0) {
507                         m->pixclock = g450_mnp2f(PMINFO m->mnp);
508                 }
509         }
510 #undef minfo
511         return 0;
512 }
513
514 static struct matrox_altout g450out = {
515         .name    = "Primary output",
516         .compute = g450_compute,
517 };
518 #endif
519
520 #endif /* NEED_DAC1064 */
521
522 #ifdef CONFIG_FB_MATROX_MYSTIQUE
523 static int MGA1064_init(WPMINFO struct my_timming* m) {
524         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
525
526         DBG(__FUNCTION__)
527
528         if (DAC1064_init_1(PMINFO m)) return 1;
529         if (matroxfb_vgaHWinit(PMINFO m)) return 1;
530
531         hw->MiscOutReg = 0xCB;
532         if (m->sync & FB_SYNC_HOR_HIGH_ACT)
533                 hw->MiscOutReg &= ~0x40;
534         if (m->sync & FB_SYNC_VERT_HIGH_ACT)
535                 hw->MiscOutReg &= ~0x80;
536         if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
537                 hw->CRTCEXT[3] |= 0x40;
538
539         if (DAC1064_init_2(PMINFO m)) return 1;
540         return 0;
541 }
542 #endif
543
544 #ifdef CONFIG_FB_MATROX_G
545 static int MGAG100_init(WPMINFO struct my_timming* m) {
546         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
547
548         DBG(__FUNCTION__)
549
550         if (DAC1064_init_1(PMINFO m)) return 1;
551         hw->MXoptionReg &= ~0x2000;
552         if (matroxfb_vgaHWinit(PMINFO m)) return 1;
553
554         hw->MiscOutReg = 0xEF;
555         if (m->sync & FB_SYNC_HOR_HIGH_ACT)
556                 hw->MiscOutReg &= ~0x40;
557         if (m->sync & FB_SYNC_VERT_HIGH_ACT)
558                 hw->MiscOutReg &= ~0x80;
559         if (m->sync & FB_SYNC_COMP_HIGH_ACT) /* should be only FB_SYNC_COMP */
560                 hw->CRTCEXT[3] |= 0x40;
561
562         if (DAC1064_init_2(PMINFO m)) return 1;
563         return 0;
564 }
565 #endif  /* G */
566
567 #ifdef CONFIG_FB_MATROX_MYSTIQUE
568 static void MGA1064_ramdac_init(WPMINFO2) {
569
570         DBG(__FUNCTION__)
571
572         /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */
573         ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
574         ACCESS_FBINFO(features.pll.ref_freq)     = 14318;
575         ACCESS_FBINFO(features.pll.feed_div_min) = 100;
576         ACCESS_FBINFO(features.pll.feed_div_max) = 127;
577         ACCESS_FBINFO(features.pll.in_div_min)   = 1;
578         ACCESS_FBINFO(features.pll.in_div_max)   = 31;
579         ACCESS_FBINFO(features.pll.post_shift_max) = 3;
580         ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_EXTERNAL;
581         /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
582         DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
583 }
584 #endif
585
586 #ifdef CONFIG_FB_MATROX_G
587 /* BIOS environ */
588 static int x7AF4 = 0x10;        /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
589                                 /* G100 wants 0x10, G200 SGRAM does not care... */
590 #if 0
591 static int def50 = 0;   /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
592 #endif
593
594 static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p) {
595         int reg;
596         int selClk;
597         int clk;
598
599         DBG(__FUNCTION__)
600
601         outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) | M1064_XPIXCLKCTRL_DIS |
602                    M1064_XPIXCLKCTRL_PLL_UP);
603         switch (flags & 3) {
604                 case 0:         reg = M1064_XPIXPLLAM; break;
605                 case 1:         reg = M1064_XPIXPLLBM; break;
606                 default:        reg = M1064_XPIXPLLCM; break;
607         }
608         outDAC1064(PMINFO reg++, m);
609         outDAC1064(PMINFO reg++, n);
610         outDAC1064(PMINFO reg, p);
611         selClk = mga_inb(M_MISC_REG_READ) & ~0xC;
612         /* there should be flags & 0x03 & case 0/1/else */
613         /* and we should first select source and after that we should wait for PLL */
614         /* and we are waiting for PLL with oscilator disabled... Is it right? */
615         switch (flags & 0x03) {
616                 case 0x00:      break;
617                 case 0x01:      selClk |= 4; break;
618                 default:        selClk |= 0x0C; break;
619         }
620         mga_outb(M_MISC_REG, selClk);
621         for (clk = 500000; clk; clk--) {
622                 if (inDAC1064(PMINFO M1064_XPIXPLLSTAT) & 0x40)
623                         break;
624                 udelay(10);
625         };
626         if (!clk)
627                 printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');
628         selClk = inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK;
629         switch (flags & 0x0C) {
630                 case 0x00:      selClk |= M1064_XPIXCLKCTRL_SRC_PCI; break;
631                 case 0x04:      selClk |= M1064_XPIXCLKCTRL_SRC_PLL; break;
632                 default:        selClk |= M1064_XPIXCLKCTRL_SRC_EXT; break;
633         }
634         outDAC1064(PMINFO M1064_XPIXCLKCTRL, selClk);
635         outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
636 }
637
638 static void MGAG100_setPixClock(CPMINFO int flags, int freq) {
639         unsigned int m, n, p;
640
641         DBG(__FUNCTION__)
642
643         DAC1064_calcclock(PMINFO freq, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);
644         MGAG100_progPixClock(PMINFO flags, m, n, p);
645 }
646 #endif
647
648 #ifdef CONFIG_FB_MATROX_MYSTIQUE
649 static int MGA1064_preinit(WPMINFO2) {
650         static const int vxres_mystique[] = { 512,        640, 768,  800,  832,  960,
651                                              1024, 1152, 1280,      1600, 1664, 1920,
652                                              2048,    0};
653         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
654
655         DBG(__FUNCTION__)
656
657         /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
658         ACCESS_FBINFO(capable.text) = 1;
659         ACCESS_FBINFO(capable.vxres) = vxres_mystique;
660
661         ACCESS_FBINFO(outputs[0]).output = &m1064;
662         ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
663         ACCESS_FBINFO(outputs[0]).data = MINFO;
664         ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
665
666         if (ACCESS_FBINFO(devflags.noinit))
667                 return 0;       /* do not modify settings */
668         hw->MXoptionReg &= 0xC0000100;
669         hw->MXoptionReg |= 0x00094E20;
670         if (ACCESS_FBINFO(devflags.novga))
671                 hw->MXoptionReg &= ~0x00000100;
672         if (ACCESS_FBINFO(devflags.nobios))
673                 hw->MXoptionReg &= ~0x40000000;
674         if (ACCESS_FBINFO(devflags.nopciretry))
675                 hw->MXoptionReg |=  0x20000000;
676         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
677         mga_setr(M_SEQ_INDEX, 0x01, 0x20);
678         mga_outl(M_CTLWTST, 0x00000000);
679         udelay(200);
680         mga_outl(M_MACCESS, 0x00008000);
681         udelay(100);
682         mga_outl(M_MACCESS, 0x0000C000);
683         return 0;
684 }
685
686 static void MGA1064_reset(WPMINFO2) {
687
688         DBG(__FUNCTION__);
689
690         MGA1064_ramdac_init(PMINFO2);
691 }
692 #endif
693
694 #ifdef CONFIG_FB_MATROX_G
695 static void g450_mclk_init(WPMINFO2) {
696         /* switch all clocks to PCI source */
697         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
698         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3 & ~0x00300C03);
699         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
700         
701         if (((ACCESS_FBINFO(values).reg.opt3 & 0x000003) == 0x000003) ||
702             ((ACCESS_FBINFO(values).reg.opt3 & 0x000C00) == 0x000C00) ||
703             ((ACCESS_FBINFO(values).reg.opt3 & 0x300000) == 0x300000)) {
704                 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.video), M_VIDEO_PLL);
705         } else {
706                 unsigned long flags;
707                 unsigned int pwr;
708                 
709                 matroxfb_DAC_lock_irqsave(flags);
710                 pwr = inDAC1064(PMINFO M1064_XPWRCTRL) & ~0x02;
711                 outDAC1064(PMINFO M1064_XPWRCTRL, pwr);
712                 matroxfb_DAC_unlock_irqrestore(flags);
713         }
714         matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.system), M_SYSTEM_PLL);
715         
716         /* switch clocks to their real PLL source(s) */
717         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
718         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3);
719         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
720
721 }
722
723 static void g450_memory_init(WPMINFO2) {
724         /* disable memory refresh */
725         ACCESS_FBINFO(hw).MXoptionReg &= ~0x001F8000;
726         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
727         
728         /* set memory interface parameters */
729         ACCESS_FBINFO(hw).MXoptionReg &= ~0x00207E00;
730         ACCESS_FBINFO(hw).MXoptionReg |= 0x00207E00 & ACCESS_FBINFO(values).reg.opt;
731         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
732         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ACCESS_FBINFO(values).reg.opt2);
733         
734         mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
735         
736         /* first set up memory interface with disabled memory interface clocks */
737         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc & ~0x80000000U);
738         mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
739         mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess);
740         /* start memory clocks */
741         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc | 0x80000000U);
742
743         udelay(200);
744         
745         if (ACCESS_FBINFO(values).memory.ddr && (!ACCESS_FBINFO(values).memory.emrswen || !ACCESS_FBINFO(values).memory.dll)) {
746                 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk & ~0x1000);
747         }
748         mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess | 0x8000);
749         
750         udelay(200);
751         
752         ACCESS_FBINFO(hw).MXoptionReg |= 0x001F8000 & ACCESS_FBINFO(values).reg.opt;
753         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
754         
755         /* value is written to memory chips only if old != new */
756         mga_outl(M_PLNWT, 0);
757         mga_outl(M_PLNWT, ~0);
758         
759         if (ACCESS_FBINFO(values).reg.mctlwtst != ACCESS_FBINFO(values).reg.mctlwtst_core) {
760                 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst_core);
761         }
762         
763 }
764
765 static void g450_preinit(WPMINFO2) {
766         u_int32_t c2ctl;
767         u_int8_t curctl;
768         u_int8_t c1ctl;
769         
770         /* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */
771         ACCESS_FBINFO(hw).MXoptionReg &= 0xC0000100;
772         ACCESS_FBINFO(hw).MXoptionReg |= 0x00000020;
773         if (ACCESS_FBINFO(devflags.novga))
774                 ACCESS_FBINFO(hw).MXoptionReg &= ~0x00000100;
775         if (ACCESS_FBINFO(devflags.nobios))
776                 ACCESS_FBINFO(hw).MXoptionReg &= ~0x40000000;
777         if (ACCESS_FBINFO(devflags.nopciretry))
778                 ACCESS_FBINFO(hw).MXoptionReg |=  0x20000000;
779         ACCESS_FBINFO(hw).MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x03400040;
780         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
781
782         /* Init system clocks */
783                 
784         /* stop crtc2 */
785         c2ctl = mga_inl(M_C2CTL);
786         mga_outl(M_C2CTL, c2ctl & ~1);
787         /* stop cursor */
788         curctl = inDAC1064(PMINFO M1064_XCURCTRL);
789         outDAC1064(PMINFO M1064_XCURCTRL, 0);
790         /* stop crtc1 */
791         c1ctl = mga_readr(M_SEQ_INDEX, 1);
792         mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20);
793
794         g450_mclk_init(PMINFO2);
795         g450_memory_init(PMINFO2);
796         
797         /* set legacy VGA clock sources for DOSEmu or VMware... */
798         matroxfb_g450_setclk(PMINFO 25175, M_PIXEL_PLL_A);
799         matroxfb_g450_setclk(PMINFO 28322, M_PIXEL_PLL_B);
800
801         /* restore crtc1 */
802         mga_setr(M_SEQ_INDEX, 1, c1ctl);
803         
804         /* restore cursor */
805         outDAC1064(PMINFO M1064_XCURCTRL, curctl);
806
807         /* restore crtc2 */
808         mga_outl(M_C2CTL, c2ctl);
809         
810         return;
811 }
812
813 static int MGAG100_preinit(WPMINFO2) {
814         static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
815                                           1024, 1152, 1280,      1600, 1664, 1920,
816                                           2048, 0};
817         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
818
819         u_int32_t reg50;
820 #if 0
821         u_int32_t q;
822 #endif
823
824         DBG(__FUNCTION__)
825
826         /* there are some instabilities if in_div > 19 && vco < 61000 */
827         if (ACCESS_FBINFO(devflags.g450dac)) {
828                 ACCESS_FBINFO(features.pll.vco_freq_min) = 130000;      /* my sample: >118 */
829         } else {
830                 ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
831         }
832         if (!ACCESS_FBINFO(features.pll.ref_freq)) {
833                 ACCESS_FBINFO(features.pll.ref_freq)     = 27000;
834         }
835         ACCESS_FBINFO(features.pll.feed_div_min) = 7;
836         ACCESS_FBINFO(features.pll.feed_div_max) = 127;
837         ACCESS_FBINFO(features.pll.in_div_min)   = 1;
838         ACCESS_FBINFO(features.pll.in_div_max)   = 31;
839         ACCESS_FBINFO(features.pll.post_shift_max) = 3;
840         ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT;
841         /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
842         ACCESS_FBINFO(capable.text) = 1;
843         ACCESS_FBINFO(capable.vxres) = vxres_g100;
844         ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
845                         ? ACCESS_FBINFO(devflags.sgram) : 1;
846
847 #ifdef CONFIG_FB_MATROX_G
848         if (ACCESS_FBINFO(devflags.g450dac)) {
849                 ACCESS_FBINFO(outputs[0]).output = &g450out;
850         } else
851 #endif
852         {
853                 ACCESS_FBINFO(outputs[0]).output = &m1064;
854         }
855         ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
856         ACCESS_FBINFO(outputs[0]).data = MINFO;
857         ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
858
859         if (ACCESS_FBINFO(devflags.g450dac)) {
860                 /* we must do this always, BIOS does not do it for us
861                    and accelerator dies without it */
862                 mga_outl(0x1C0C, 0);
863         }
864         if (ACCESS_FBINFO(devflags.noinit))
865                 return 0;
866         if (ACCESS_FBINFO(devflags.g450dac)) {
867                 g450_preinit(PMINFO2);
868                 return 0;
869         }
870         hw->MXoptionReg &= 0xC0000100;
871         hw->MXoptionReg |= 0x00000020;
872         if (ACCESS_FBINFO(devflags.novga))
873                 hw->MXoptionReg &= ~0x00000100;
874         if (ACCESS_FBINFO(devflags.nobios))
875                 hw->MXoptionReg &= ~0x40000000;
876         if (ACCESS_FBINFO(devflags.nopciretry))
877                 hw->MXoptionReg |=  0x20000000;
878         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
879         DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
880
881         if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
882                 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
883                 reg50 &= ~0x3000;
884                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
885
886                 hw->MXoptionReg |= 0x1080;
887                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
888                 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
889                 udelay(100);
890                 mga_outb(0x1C05, 0x00);
891                 mga_outb(0x1C05, 0x80);
892                 udelay(100);
893                 mga_outb(0x1C05, 0x40);
894                 mga_outb(0x1C05, 0xC0);
895                 udelay(100);
896                 reg50 &= ~0xFF;
897                 reg50 |=  0x07;
898                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
899                 /* it should help with G100 */
900                 mga_outb(M_GRAPHICS_INDEX, 6);
901                 mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
902                 mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
903                 mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
904                 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA);
905                 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55);
906                 mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55);
907 #if 0
908                 if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) {
909                         hw->MXoptionReg &= ~0x1000;
910                 }
911 #endif
912                 hw->MXoptionReg |= 0x00078020;
913         } else if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) {
914                 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
915                 reg50 &= ~0x3000;
916                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
917
918                 if (ACCESS_FBINFO(devflags.memtype) == -1)
919                         hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
920                 else
921                         hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
922                 if (ACCESS_FBINFO(devflags.sgram))
923                         hw->MXoptionReg |= 0x4000;
924                 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
925                 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
926                 udelay(200);
927                 mga_outl(M_MACCESS, 0x00000000);
928                 mga_outl(M_MACCESS, 0x00008000);
929                 udelay(100);
930                 mga_outw(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
931                 hw->MXoptionReg |= 0x00078020;
932         } else {
933                 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
934                 reg50 &= ~0x00000100;
935                 reg50 |=  0x00000000;
936                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
937
938                 if (ACCESS_FBINFO(devflags.memtype) == -1)
939                         hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
940                 else
941                         hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
942                 if (ACCESS_FBINFO(devflags.sgram))
943                         hw->MXoptionReg |= 0x4000;
944                 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
945                 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
946                 udelay(200);
947                 mga_outl(M_MACCESS, 0x00000000);
948                 mga_outl(M_MACCESS, 0x00008000);
949                 udelay(100);
950                 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
951                 hw->MXoptionReg |= 0x00040020;
952         }
953         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
954         return 0;
955 }
956
957 static void MGAG100_reset(WPMINFO2) {
958         u_int8_t b;
959         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
960
961         DBG(__FUNCTION__)
962
963         {
964 #ifdef G100_BROKEN_IBM_82351
965                 u_int32_t d;
966
967                 find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
968                 pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
969                 if (b == ACCESS_FBINFO(pcidev)->bus->number) {
970                         pci_write_config_byte(ibm, PCI_COMMAND+1, 0);   /* disable back-to-back & SERR */
971                         pci_write_config_byte(ibm, 0x41, 0xF4);         /* ??? */
972                         pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0);  /* ??? */
973                         pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */
974                 }
975 #endif
976                 if (!ACCESS_FBINFO(devflags.noinit)) {
977                         if (x7AF4 & 8) {
978                                 hw->MXoptionReg |= 0x40;        /* FIXME... */
979                                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
980                         }
981                         mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
982                 }
983         }
984         if (ACCESS_FBINFO(devflags.g450dac)) {
985                 /* either leave MCLK as is... or they were set in preinit */
986                 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
987                 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
988                 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
989         } else {
990                 DAC1064_setmclk(PMINFO DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
991         }
992         if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
993                 if (ACCESS_FBINFO(devflags.dfp_type) == -1) {
994                         ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F);
995                 }
996         }
997         if (ACCESS_FBINFO(devflags.noinit))
998                 return;
999         if (ACCESS_FBINFO(devflags.g450dac)) {
1000         } else {
1001                 MGAG100_setPixClock(PMINFO 4, 25175);
1002                 MGAG100_setPixClock(PMINFO 5, 28322);
1003                 if (x7AF4 & 0x10) {
1004                         b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
1005                         outDAC1064(PMINFO M1064_XGENIODATA, b);
1006                         b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
1007                         outDAC1064(PMINFO M1064_XGENIOCTRL, b);
1008                 }
1009         }
1010 }
1011 #endif
1012
1013 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1014 static void MGA1064_restore(WPMINFO2) {
1015         int i;
1016         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
1017
1018         CRITFLAGS
1019
1020         DBG(__FUNCTION__)
1021
1022         CRITBEGIN
1023
1024         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
1025         mga_outb(M_IEN, 0x00);
1026         mga_outb(M_CACHEFLUSH, 0x00);
1027
1028         CRITEND
1029
1030         DAC1064_restore_1(PMINFO2);
1031         matroxfb_vgaHWrestore(PMINFO2);
1032         ACCESS_FBINFO(crtc1.panpos) = -1;
1033         for (i = 0; i < 6; i++)
1034                 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1035         DAC1064_restore_2(PMINFO2);
1036 }
1037 #endif
1038
1039 #ifdef CONFIG_FB_MATROX_G
1040 static void MGAG100_restore(WPMINFO2) {
1041         int i;
1042         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
1043
1044         CRITFLAGS
1045
1046         DBG(__FUNCTION__)
1047
1048         CRITBEGIN
1049
1050         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
1051         CRITEND
1052
1053         DAC1064_restore_1(PMINFO2);
1054         matroxfb_vgaHWrestore(PMINFO2);
1055 #ifdef CONFIG_FB_MATROX_32MB
1056         if (ACCESS_FBINFO(devflags.support32MB))
1057                 mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
1058 #endif
1059         ACCESS_FBINFO(crtc1.panpos) = -1;
1060         for (i = 0; i < 6; i++)
1061                 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1062         DAC1064_restore_2(PMINFO2);
1063 }
1064 #endif
1065
1066 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1067 struct matrox_switch matrox_mystique = {
1068         MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore,
1069 };
1070 EXPORT_SYMBOL(matrox_mystique);
1071 #endif
1072
1073 #ifdef CONFIG_FB_MATROX_G
1074 struct matrox_switch matrox_G100 = {
1075         MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore,
1076 };
1077 EXPORT_SYMBOL(matrox_G100);
1078 #endif
1079
1080 #ifdef NEED_DAC1064
1081 EXPORT_SYMBOL(DAC1064_global_init);
1082 EXPORT_SYMBOL(DAC1064_global_restore);
1083 #endif
1084 MODULE_LICENSE("GPL");