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