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