xref: /linux/drivers/video/fbdev/matrox/matroxfb_DAC1064.c (revision 3932b9ca55b0be314a36d3e84faff3e823c081f5)
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 	MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore,
1092 };
1093 EXPORT_SYMBOL(matrox_mystique);
1094 #endif
1095 
1096 #ifdef CONFIG_FB_MATROX_G
1097 struct matrox_switch matrox_G100 = {
1098 	MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore,
1099 };
1100 EXPORT_SYMBOL(matrox_G100);
1101 #endif
1102 
1103 #ifdef NEED_DAC1064
1104 EXPORT_SYMBOL(DAC1064_global_init);
1105 EXPORT_SYMBOL(DAC1064_global_restore);
1106 #endif
1107 MODULE_LICENSE("GPL");
1108