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