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