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