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