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