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