xref: /openbmc/linux/drivers/video/fbdev/matrox/matroxfb_DAC1064.c (revision 58e16d792a6a8c6b750f637a4649967fcac853dc)
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  
DAC1064_calcclock(const struct matrox_fb_info * minfo,unsigned int freq,unsigned int fmax,unsigned int * in,unsigned int * feed,unsigned int * post)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  
DAC1064_setpclk(struct matrox_fb_info * minfo,unsigned long fout)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  
DAC1064_setmclk(struct matrox_fb_info * minfo,int oscinfo,unsigned long fmem)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
g450_set_plls(struct matrox_fb_info * minfo)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  
DAC1064_global_init(struct matrox_fb_info * minfo)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  
DAC1064_global_restore(struct matrox_fb_info * minfo)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  
DAC1064_init_1(struct matrox_fb_info * minfo,struct my_timming * m)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  
DAC1064_init_2(struct matrox_fb_info * minfo,struct my_timming * m)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  
DAC1064_restore_1(struct matrox_fb_info * minfo)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  
DAC1064_restore_2(struct matrox_fb_info * minfo)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  
m1064_compute(void * out,struct my_timming * m)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
g450_compute(void * out,struct my_timming * m)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
MGA1064_init(struct matrox_fb_info * minfo,struct my_timming * m)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
MGAG100_init(struct matrox_fb_info * minfo,struct my_timming * m)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
MGA1064_ramdac_init(struct matrox_fb_info * minfo)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  
MGAG100_progPixClock(const struct matrox_fb_info * minfo,int flags,int m,int n,int p)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  
MGAG100_setPixClock(const struct matrox_fb_info * minfo,int flags,int freq)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
MGA1064_preinit(struct matrox_fb_info * minfo)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  
MGA1064_reset(struct matrox_fb_info * minfo)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
g450_mclk_init(struct matrox_fb_info * minfo)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  
g450_memory_init(struct matrox_fb_info * minfo)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  
g450_preinit(struct matrox_fb_info * minfo)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  
MGAG100_preinit(struct matrox_fb_info * minfo)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  
MGAG100_reset(struct matrox_fb_info * minfo)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
MGA1064_restore(struct matrox_fb_info * minfo)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
MGAG100_restore(struct matrox_fb_info * minfo)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