Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / 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         ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
661
662         ACCESS_FBINFO(outputs[0]).output = &m1064;
663         ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
664         ACCESS_FBINFO(outputs[0]).data = MINFO;
665         ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
666
667         if (ACCESS_FBINFO(devflags.noinit))
668                 return 0;       /* do not modify settings */
669         hw->MXoptionReg &= 0xC0000100;
670         hw->MXoptionReg |= 0x00094E20;
671         if (ACCESS_FBINFO(devflags.novga))
672                 hw->MXoptionReg &= ~0x00000100;
673         if (ACCESS_FBINFO(devflags.nobios))
674                 hw->MXoptionReg &= ~0x40000000;
675         if (ACCESS_FBINFO(devflags.nopciretry))
676                 hw->MXoptionReg |=  0x20000000;
677         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
678         mga_setr(M_SEQ_INDEX, 0x01, 0x20);
679         mga_outl(M_CTLWTST, 0x00000000);
680         udelay(200);
681         mga_outl(M_MACCESS, 0x00008000);
682         udelay(100);
683         mga_outl(M_MACCESS, 0x0000C000);
684         return 0;
685 }
686
687 static void MGA1064_reset(WPMINFO2) {
688
689         DBG(__FUNCTION__);
690
691         MGA1064_ramdac_init(PMINFO2);
692 }
693 #endif
694
695 #ifdef CONFIG_FB_MATROX_G
696 static void g450_mclk_init(WPMINFO2) {
697         /* switch all clocks to PCI source */
698         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
699         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3 & ~0x00300C03);
700         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
701         
702         if (((ACCESS_FBINFO(values).reg.opt3 & 0x000003) == 0x000003) ||
703             ((ACCESS_FBINFO(values).reg.opt3 & 0x000C00) == 0x000C00) ||
704             ((ACCESS_FBINFO(values).reg.opt3 & 0x300000) == 0x300000)) {
705                 matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.video), M_VIDEO_PLL);
706         } else {
707                 unsigned long flags;
708                 unsigned int pwr;
709                 
710                 matroxfb_DAC_lock_irqsave(flags);
711                 pwr = inDAC1064(PMINFO M1064_XPWRCTRL) & ~0x02;
712                 outDAC1064(PMINFO M1064_XPWRCTRL, pwr);
713                 matroxfb_DAC_unlock_irqrestore(flags);
714         }
715         matroxfb_g450_setclk(PMINFO ACCESS_FBINFO(values.pll.system), M_SYSTEM_PLL);
716         
717         /* switch clocks to their real PLL source(s) */
718         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg | 4);
719         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION3_REG, ACCESS_FBINFO(values).reg.opt3);
720         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
721
722 }
723
724 static void g450_memory_init(WPMINFO2) {
725         /* disable memory refresh */
726         ACCESS_FBINFO(hw).MXoptionReg &= ~0x001F8000;
727         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
728         
729         /* set memory interface parameters */
730         ACCESS_FBINFO(hw).MXoptionReg &= ~0x00207E00;
731         ACCESS_FBINFO(hw).MXoptionReg |= 0x00207E00 & ACCESS_FBINFO(values).reg.opt;
732         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
733         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, ACCESS_FBINFO(values).reg.opt2);
734         
735         mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
736         
737         /* first set up memory interface with disabled memory interface clocks */
738         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc & ~0x80000000U);
739         mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
740         mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess);
741         /* start memory clocks */
742         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MEMMISC_REG, ACCESS_FBINFO(values).reg.memmisc | 0x80000000U);
743
744         udelay(200);
745         
746         if (ACCESS_FBINFO(values).memory.ddr && (!ACCESS_FBINFO(values).memory.emrswen || !ACCESS_FBINFO(values).memory.dll)) {
747                 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk & ~0x1000);
748         }
749         mga_outl(M_MACCESS, ACCESS_FBINFO(values).reg.maccess | 0x8000);
750         
751         udelay(200);
752         
753         ACCESS_FBINFO(hw).MXoptionReg |= 0x001F8000 & ACCESS_FBINFO(values).reg.opt;
754         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
755         
756         /* value is written to memory chips only if old != new */
757         mga_outl(M_PLNWT, 0);
758         mga_outl(M_PLNWT, ~0);
759         
760         if (ACCESS_FBINFO(values).reg.mctlwtst != ACCESS_FBINFO(values).reg.mctlwtst_core) {
761                 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst_core);
762         }
763         
764 }
765
766 static void g450_preinit(WPMINFO2) {
767         u_int32_t c2ctl;
768         u_int8_t curctl;
769         u_int8_t c1ctl;
770         
771         /* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */
772         ACCESS_FBINFO(hw).MXoptionReg &= 0xC0000100;
773         ACCESS_FBINFO(hw).MXoptionReg |= 0x00000020;
774         if (ACCESS_FBINFO(devflags.novga))
775                 ACCESS_FBINFO(hw).MXoptionReg &= ~0x00000100;
776         if (ACCESS_FBINFO(devflags.nobios))
777                 ACCESS_FBINFO(hw).MXoptionReg &= ~0x40000000;
778         if (ACCESS_FBINFO(devflags.nopciretry))
779                 ACCESS_FBINFO(hw).MXoptionReg |=  0x20000000;
780         ACCESS_FBINFO(hw).MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x03400040;
781         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
782
783         /* Init system clocks */
784                 
785         /* stop crtc2 */
786         c2ctl = mga_inl(M_C2CTL);
787         mga_outl(M_C2CTL, c2ctl & ~1);
788         /* stop cursor */
789         curctl = inDAC1064(PMINFO M1064_XCURCTRL);
790         outDAC1064(PMINFO M1064_XCURCTRL, 0);
791         /* stop crtc1 */
792         c1ctl = mga_readr(M_SEQ_INDEX, 1);
793         mga_setr(M_SEQ_INDEX, 1, c1ctl | 0x20);
794
795         g450_mclk_init(PMINFO2);
796         g450_memory_init(PMINFO2);
797         
798         /* set legacy VGA clock sources for DOSEmu or VMware... */
799         matroxfb_g450_setclk(PMINFO 25175, M_PIXEL_PLL_A);
800         matroxfb_g450_setclk(PMINFO 28322, M_PIXEL_PLL_B);
801
802         /* restore crtc1 */
803         mga_setr(M_SEQ_INDEX, 1, c1ctl);
804         
805         /* restore cursor */
806         outDAC1064(PMINFO M1064_XCURCTRL, curctl);
807
808         /* restore crtc2 */
809         mga_outl(M_C2CTL, c2ctl);
810         
811         return;
812 }
813
814 static int MGAG100_preinit(WPMINFO2) {
815         static const int vxres_g100[] = {  512,        640, 768,  800,  832,  960,
816                                           1024, 1152, 1280,      1600, 1664, 1920,
817                                           2048, 0};
818         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
819
820         u_int32_t reg50;
821 #if 0
822         u_int32_t q;
823 #endif
824
825         DBG(__FUNCTION__)
826
827         /* there are some instabilities if in_div > 19 && vco < 61000 */
828         if (ACCESS_FBINFO(devflags.g450dac)) {
829                 ACCESS_FBINFO(features.pll.vco_freq_min) = 130000;      /* my sample: >118 */
830         } else {
831                 ACCESS_FBINFO(features.pll.vco_freq_min) = 62000;
832         }
833         if (!ACCESS_FBINFO(features.pll.ref_freq)) {
834                 ACCESS_FBINFO(features.pll.ref_freq)     = 27000;
835         }
836         ACCESS_FBINFO(features.pll.feed_div_min) = 7;
837         ACCESS_FBINFO(features.pll.feed_div_max) = 127;
838         ACCESS_FBINFO(features.pll.in_div_min)   = 1;
839         ACCESS_FBINFO(features.pll.in_div_max)   = 31;
840         ACCESS_FBINFO(features.pll.post_shift_max) = 3;
841         ACCESS_FBINFO(features.DAC1064.xvrefctrl) = DAC1064_XVREFCTRL_G100_DEFAULT;
842         /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
843         ACCESS_FBINFO(capable.text) = 1;
844         ACCESS_FBINFO(capable.vxres) = vxres_g100;
845         ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
846         ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
847                         ? ACCESS_FBINFO(devflags.sgram) : 1;
848
849 #ifdef CONFIG_FB_MATROX_G
850         if (ACCESS_FBINFO(devflags.g450dac)) {
851                 ACCESS_FBINFO(outputs[0]).output = &g450out;
852         } else
853 #endif
854         {
855                 ACCESS_FBINFO(outputs[0]).output = &m1064;
856         }
857         ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
858         ACCESS_FBINFO(outputs[0]).data = MINFO;
859         ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
860
861         if (ACCESS_FBINFO(devflags.g450dac)) {
862                 /* we must do this always, BIOS does not do it for us
863                    and accelerator dies without it */
864                 mga_outl(0x1C0C, 0);
865         }
866         if (ACCESS_FBINFO(devflags.noinit))
867                 return 0;
868         if (ACCESS_FBINFO(devflags.g450dac)) {
869                 g450_preinit(PMINFO2);
870                 return 0;
871         }
872         hw->MXoptionReg &= 0xC0000100;
873         hw->MXoptionReg |= 0x00000020;
874         if (ACCESS_FBINFO(devflags.novga))
875                 hw->MXoptionReg &= ~0x00000100;
876         if (ACCESS_FBINFO(devflags.nobios))
877                 hw->MXoptionReg &= ~0x40000000;
878         if (ACCESS_FBINFO(devflags.nopciretry))
879                 hw->MXoptionReg |=  0x20000000;
880         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
881         DAC1064_setmclk(PMINFO DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PCI, 133333);
882
883         if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
884                 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
885                 reg50 &= ~0x3000;
886                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
887
888                 hw->MXoptionReg |= 0x1080;
889                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
890                 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
891                 udelay(100);
892                 mga_outb(0x1C05, 0x00);
893                 mga_outb(0x1C05, 0x80);
894                 udelay(100);
895                 mga_outb(0x1C05, 0x40);
896                 mga_outb(0x1C05, 0xC0);
897                 udelay(100);
898                 reg50 &= ~0xFF;
899                 reg50 |=  0x07;
900                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
901                 /* it should help with G100 */
902                 mga_outb(M_GRAPHICS_INDEX, 6);
903                 mga_outb(M_GRAPHICS_DATA, (mga_inb(M_GRAPHICS_DATA) & 3) | 4);
904                 mga_setr(M_EXTVGA_INDEX, 0x03, 0x81);
905                 mga_setr(M_EXTVGA_INDEX, 0x04, 0x00);
906                 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0000, 0xAA);
907                 mga_writeb(ACCESS_FBINFO(video.vbase), 0x0800, 0x55);
908                 mga_writeb(ACCESS_FBINFO(video.vbase), 0x4000, 0x55);
909 #if 0
910                 if (mga_readb(ACCESS_FBINFO(video.vbase), 0x0000) != 0xAA) {
911                         hw->MXoptionReg &= ~0x1000;
912                 }
913 #endif
914                 hw->MXoptionReg |= 0x00078020;
915         } else if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG200) {
916                 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
917                 reg50 &= ~0x3000;
918                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
919
920                 if (ACCESS_FBINFO(devflags.memtype) == -1)
921                         hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
922                 else
923                         hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
924                 if (ACCESS_FBINFO(devflags.sgram))
925                         hw->MXoptionReg |= 0x4000;
926                 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
927                 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
928                 udelay(200);
929                 mga_outl(M_MACCESS, 0x00000000);
930                 mga_outl(M_MACCESS, 0x00008000);
931                 udelay(100);
932                 mga_outw(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
933                 hw->MXoptionReg |= 0x00078020;
934         } else {
935                 pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, &reg50);
936                 reg50 &= ~0x00000100;
937                 reg50 |=  0x00000000;
938                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION2_REG, reg50);
939
940                 if (ACCESS_FBINFO(devflags.memtype) == -1)
941                         hw->MXoptionReg |= ACCESS_FBINFO(values).reg.opt & 0x1C00;
942                 else
943                         hw->MXoptionReg |= (ACCESS_FBINFO(devflags.memtype) & 7) << 10;
944                 if (ACCESS_FBINFO(devflags.sgram))
945                         hw->MXoptionReg |= 0x4000;
946                 mga_outl(M_CTLWTST, ACCESS_FBINFO(values).reg.mctlwtst);
947                 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
948                 udelay(200);
949                 mga_outl(M_MACCESS, 0x00000000);
950                 mga_outl(M_MACCESS, 0x00008000);
951                 udelay(100);
952                 mga_outl(M_MEMRDBK, ACCESS_FBINFO(values).reg.memrdbk);
953                 hw->MXoptionReg |= 0x00040020;
954         }
955         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
956         return 0;
957 }
958
959 static void MGAG100_reset(WPMINFO2) {
960         u_int8_t b;
961         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
962
963         DBG(__FUNCTION__)
964
965         {
966 #ifdef G100_BROKEN_IBM_82351
967                 u_int32_t d;
968
969                 find 1014/22 (IBM/82351); /* if found and bridging Matrox, do some strange stuff */
970                 pci_read_config_byte(ibm, PCI_SECONDARY_BUS, &b);
971                 if (b == ACCESS_FBINFO(pcidev)->bus->number) {
972                         pci_write_config_byte(ibm, PCI_COMMAND+1, 0);   /* disable back-to-back & SERR */
973                         pci_write_config_byte(ibm, 0x41, 0xF4);         /* ??? */
974                         pci_write_config_byte(ibm, PCI_IO_BASE, 0xF0);  /* ??? */
975                         pci_write_config_byte(ibm, PCI_IO_LIMIT, 0x00); /* ??? */
976                 }
977 #endif
978                 if (!ACCESS_FBINFO(devflags.noinit)) {
979                         if (x7AF4 & 8) {
980                                 hw->MXoptionReg |= 0x40;        /* FIXME... */
981                                 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
982                         }
983                         mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
984                 }
985         }
986         if (ACCESS_FBINFO(devflags.g450dac)) {
987                 /* either leave MCLK as is... or they were set in preinit */
988                 hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);
989                 hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);
990                 hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);
991         } else {
992                 DAC1064_setmclk(PMINFO DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
993         }
994         if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
995                 if (ACCESS_FBINFO(devflags.dfp_type) == -1) {
996                         ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F);
997                 }
998         }
999         if (ACCESS_FBINFO(devflags.noinit))
1000                 return;
1001         if (ACCESS_FBINFO(devflags.g450dac)) {
1002         } else {
1003                 MGAG100_setPixClock(PMINFO 4, 25175);
1004                 MGAG100_setPixClock(PMINFO 5, 28322);
1005                 if (x7AF4 & 0x10) {
1006                         b = inDAC1064(PMINFO M1064_XGENIODATA) & ~1;
1007                         outDAC1064(PMINFO M1064_XGENIODATA, b);
1008                         b = inDAC1064(PMINFO M1064_XGENIOCTRL) | 1;
1009                         outDAC1064(PMINFO M1064_XGENIOCTRL, b);
1010                 }
1011         }
1012 }
1013 #endif
1014
1015 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1016 static void MGA1064_restore(WPMINFO2) {
1017         int i;
1018         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
1019
1020         CRITFLAGS
1021
1022         DBG(__FUNCTION__)
1023
1024         CRITBEGIN
1025
1026         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
1027         mga_outb(M_IEN, 0x00);
1028         mga_outb(M_CACHEFLUSH, 0x00);
1029
1030         CRITEND
1031
1032         DAC1064_restore_1(PMINFO2);
1033         matroxfb_vgaHWrestore(PMINFO2);
1034         ACCESS_FBINFO(crtc1.panpos) = -1;
1035         for (i = 0; i < 6; i++)
1036                 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1037         DAC1064_restore_2(PMINFO2);
1038 }
1039 #endif
1040
1041 #ifdef CONFIG_FB_MATROX_G
1042 static void MGAG100_restore(WPMINFO2) {
1043         int i;
1044         struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
1045
1046         CRITFLAGS
1047
1048         DBG(__FUNCTION__)
1049
1050         CRITBEGIN
1051
1052         pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
1053         CRITEND
1054
1055         DAC1064_restore_1(PMINFO2);
1056         matroxfb_vgaHWrestore(PMINFO2);
1057 #ifdef CONFIG_FB_MATROX_32MB
1058         if (ACCESS_FBINFO(devflags.support32MB))
1059                 mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
1060 #endif
1061         ACCESS_FBINFO(crtc1.panpos) = -1;
1062         for (i = 0; i < 6; i++)
1063                 mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
1064         DAC1064_restore_2(PMINFO2);
1065 }
1066 #endif
1067
1068 #ifdef CONFIG_FB_MATROX_MYSTIQUE
1069 struct matrox_switch matrox_mystique = {
1070         MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore,
1071 };
1072 EXPORT_SYMBOL(matrox_mystique);
1073 #endif
1074
1075 #ifdef CONFIG_FB_MATROX_G
1076 struct matrox_switch matrox_G100 = {
1077         MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore,
1078 };
1079 EXPORT_SYMBOL(matrox_G100);
1080 #endif
1081
1082 #ifdef NEED_DAC1064
1083 EXPORT_SYMBOL(DAC1064_global_init);
1084 EXPORT_SYMBOL(DAC1064_global_restore);
1085 #endif
1086 MODULE_LICENSE("GPL");