xref: /linux/drivers/video/fbdev/matrox/matroxfb_DAC1064.c (revision e7d759f31ca295d589f7420719c311870bb3166f)
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");
1115