1 /*
2 *
3 * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
4 *
5 * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
6 *
7 * Portions Copyright (c) 2001 Matrox Graphics Inc.
8 *
9 * Version: 1.64 2002/06/10
10 *
11 * See matroxfb_base.c for contributors.
12 *
13 */
14
15 /* make checkconfig does not walk through include tree :-( */
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 /* 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
matroxfb_DAC1064_flashcursor(unsigned long ptr)38 static 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
matroxfb_DAC1064_createcursor(WPMINFO struct display * p)50 static 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
matroxfb_DAC1064_cursor(struct display * p,int mode,int x,int y)102 static 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
matroxfb_DAC1064_setfont(struct display * p,int width,int height)147 static 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
DAC1064_selhwcursor(WPMINFO struct display * p)153 static 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
DAC1064_calcclock(CPMINFO unsigned int freq,unsigned int fmax,unsigned int * in,unsigned int * feed,unsigned int * post)159 static 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 /* only for devices older than G450 */
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 /* they must be in POS order */
182 static 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
193 static const unsigned char MGA1064_DAC[] = {
194 0x00, 0x00, M1064_XCURCTRL_DIS,
195 0x00, 0x00, 0x00, /* black */
196 0xFF, 0xFF, 0xFF, /* white */
197 0xFF, 0x00, 0x00, /* red */
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
DAC1064_setpclk(WPMINFO unsigned long fout)206 static 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
DAC1064_setmclk(WPMINFO int oscinfo,unsigned long fmem)217 static 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 /* read MCLK and give up... */
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 /* select PCI clock until we have setup oscilator... */
241 int clk;
242 unsigned int m, n, p;
243
244 /* powerup system PLL, select PCI clock */
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 /* !!! you must not access device if MCLK is not running !!!
251 Doing so cause immediate PCI lockup :-( Maybe they should
252 generate ABORT or I/O (parity...) error and Linux should
253 recover from this... (kill driver/process). But world is not
254 perfect... */
255 /* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not
256 select PLL... because of PLL can be stopped at this time) */
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 /* select PLL */
268 mx |= 0x00000005;
269 } else {
270 /* select specified system clock source */
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
g450_set_plls(WPMINFO2)280 static 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; /* Clear PLL + enable for CRTC2 */
288 c2_ctl |= 0x0001; /* Enable CRTC2 */
289 hw->DACreg[POS1064_XPWRCTRL] &= ~0x02; /* Stop VIDEO PLL */
290 pixelmnp = ACCESS_FBINFO(crtc1).mnp;
291 videomnp = ACCESS_FBINFO(crtc2).mnp;
292 if (videomnp < 0) {
293 c2_ctl &= ~0x0001; /* Disable CRTC2 */
294 hw->DACreg[POS1064_XPWRCTRL] &= ~0x10; /* Powerdown CRTC2 */
295 } else if (ACCESS_FBINFO(crtc2).pixclock == ACCESS_FBINFO(features).pll.ref_freq) {
296 c2_ctl |= 0x4002; /* Use reference directly */
297 } else if (videomnp == pixelmnp) {
298 c2_ctl |= 0x0004; /* Use pixel PLL */
299 } else {
300 if (0 == ((videomnp ^ pixelmnp) & 0xFFFFFF00)) {
301 /* PIXEL and VIDEO PLL must not use same frequency. We modify N
302 of PIXEL PLL in such case because of VIDEO PLL may be source
303 of TVO clocks, and chroma subcarrier is derived from its
304 pixel clocks */
305 pixelmnp += 0x000100;
306 }
307 c2_ctl |= 0x0006; /* Use video PLL */
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; /* 0-50 */
333 } else if (pxc < 55000) {
334 hw->DACreg[POS1064_XPANMODE] = 0x08; /* 34-62 */
335 } else if (pxc < 70000) {
336 hw->DACreg[POS1064_XPANMODE] = 0x10; /* 42-78 */
337 } else if (pxc < 85000) {
338 hw->DACreg[POS1064_XPANMODE] = 0x18; /* 62-92 */
339 } else if (pxc < 100000) {
340 hw->DACreg[POS1064_XPANMODE] = 0x20; /* 74-108 */
341 } else if (pxc < 115000) {
342 hw->DACreg[POS1064_XPANMODE] = 0x28; /* 94-122 */
343 } else if (pxc < 125000) {
344 hw->DACreg[POS1064_XPANMODE] = 0x30; /* 108-132 */
345 } else {
346 hw->DACreg[POS1064_XPANMODE] = 0x38; /* 120-168 */
347 }
348 } else {
349 /* G450 */
350 if (pxc < 45000) {
351 hw->DACreg[POS1064_XPANMODE] = 0x00; /* 0-54 */
352 } else if (pxc < 65000) {
353 hw->DACreg[POS1064_XPANMODE] = 0x08; /* 38-70 */
354 } else if (pxc < 85000) {
355 hw->DACreg[POS1064_XPANMODE] = 0x10; /* 56-96 */
356 } else if (pxc < 105000) {
357 hw->DACreg[POS1064_XPANMODE] = 0x18; /* 80-114 */
358 } else if (pxc < 135000) {
359 hw->DACreg[POS1064_XPANMODE] = 0x20; /* 102-144 */
360 } else if (pxc < 160000) {
361 hw->DACreg[POS1064_XPANMODE] = 0x28; /* 132-166 */
362 } else if (pxc < 175000) {
363 hw->DACreg[POS1064_XPANMODE] = 0x30; /* 154-182 */
364 } else {
365 hw->DACreg[POS1064_XPANMODE] = 0x38; /* 170-204 */
366 }
367 }
368 }
369 #endif
370
DAC1064_global_init(WPMINFO2)371 void 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; /* powerup everything */
380 hw->DACreg[POS1064_XOUTPUTCONN] = 0x00; /* disable outputs */
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; /* enable output; CRTC1/2 selection is in CRTC2 ctl */
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; /* Poweroff DAC2 */
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 /* HELP! If we boot without DFP connected to DVI, we can
416 poweroff TMDS. But if we boot with DFP connected,
417 TMDS generated clocks are used instead of ALL pixclocks
418 available... If someone knows which register
419 handles it, please reveal this secret to me... */
420 hw->DACreg[POS1064_XPWRCTRL] &= ~0x04; /* Poweroff TMDS */
421 #endif
422 break;
423 }
424 /* Now set timming related variables... */
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
DAC1064_global_restore(WPMINFO2)444 void 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
DAC1064_init_1(WPMINFO struct my_timming * m,struct display * p)461 static 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 /* case 4: not supported by MGA1064 DAC */
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; /* unsupported depth */
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
DAC1064_init_2(WPMINFO struct my_timming * m,struct display * p)503 static 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) { /* 256 entries */
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) { /* 0..31, 128..159 */
518 int i;
519
520 for (i = 0; i < 32; i++) {
521 /* with p15 == 0 */
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 /* with p15 == 1 */
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++) { /* 0..63 */
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
DAC1064_restore_1(WPMINFO2)545 static 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
DAC1064_restore_2(WPMINFO struct display * p)575 static 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
m1064_compute(void * out,struct my_timming * m)596 static 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
624 static struct matrox_altout m1064 = {
625 .owner = THIS_MODULE,
626 .name = "Primary output",
627 .compute = m1064_compute,
628 };
629
630 #ifdef CONFIG_FB_MATROX_G450
g450_compute(void * out,struct my_timming * m)631 static 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
643 static struct matrox_altout g450out = {
644 .owner = THIS_MODULE,
645 .name = "Primary output",
646 .compute = g450_compute,
647 };
648 #endif
649
650 #endif /* NEED_DAC1064 */
651
652 #ifdef CONFIG_FB_MATROX_MYSTIQUE
MGA1064_init(WPMINFO struct my_timming * m,struct display * p)653 static 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) /* should be only FB_SYNC_COMP */
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
MGAG100_init(WPMINFO struct my_timming * m,struct display * p)675 static 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) /* should be only FB_SYNC_COMP */
690 hw->CRTCEXT[3] |= 0x40;
691
692 if (DAC1064_init_2(PMINFO m, p)) return 1;
693 return 0;
694 }
695 #endif /* G100 */
696
697 #ifdef CONFIG_FB_MATROX_MYSTIQUE
MGA1064_ramdac_init(WPMINFO2)698 static void MGA1064_ramdac_init(WPMINFO2) {
699
700 DBG("MGA1064_ramdac_init");
701
702 /* ACCESS_FBINFO(features.DAC1064.vco_freq_min) = 120000; */
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 /* maybe cmdline MCLK= ?, doc says gclk=44MHz, mclk=66MHz... it was 55/83 with old values */
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 /* BIOS environ */
718 static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
719 /* G100 wants 0x10, G200 SGRAM does not care... */
720 #if 0
721 static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
722 #endif
723
MGAG100_progPixClock(CPMINFO int flags,int m,int n,int p)724 static 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 /* there should be flags & 0x03 & case 0/1/else */
743 /* and we should first select source and after that we should wait for PLL */
744 /* and we are waiting for PLL with oscilator disabled... Is it right? */
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
MGAG100_setPixClock(CPMINFO int flags,int freq)768 static 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
MGA1064_preinit(WPMINFO2)779 static 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 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
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; /* do not modify settings */
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
MGA1064_reset(WPMINFO2)818 static 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
g450_mclk_init(WPMINFO2)832 static void g450_mclk_init(WPMINFO2) {
833 /* switch all clocks to PCI source */
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 /* switch clocks to their real PLL source(s) */
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
g450_memory_init(WPMINFO2)860 static void g450_memory_init(WPMINFO2) {
861 /* disable memory refresh */
862 ACCESS_FBINFO(hw).MXoptionReg &= ~0x001F8000;
863 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
864
865 /* set memory interface parameters */
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 /* first set up memory interface with disabled memory interface clocks */
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 /* start memory clocks */
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 /* value is written to memory chips only if old != new */
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
g450_preinit(WPMINFO2)902 static void g450_preinit(WPMINFO2) {
903 u_int32_t c2ctl;
904 u_int8_t curctl;
905 u_int8_t c1ctl;
906
907 /* ACCESS_FBINFO(hw).MXoptionReg = minfo->values.reg.opt; */
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 /* Init system clocks */
920
921 /* stop crtc2 */
922 c2ctl = mga_inl(M_C2CTL);
923 mga_outl(M_C2CTL, c2ctl & ~1);
924 /* stop cursor */
925 curctl = inDAC1064(PMINFO M1064_XCURCTRL);
926 outDAC1064(PMINFO M1064_XCURCTRL, 0);
927 /* stop crtc1 */
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 /* set legacy VGA clock sources for DOSEmu or VMware... */
935 matroxfb_g450_setclk(PMINFO 25175, M_PIXEL_PLL_A);
936 matroxfb_g450_setclk(PMINFO 28322, M_PIXEL_PLL_B);
937
938 /* restore crtc1 */
939 mga_setr(M_SEQ_INDEX, 1, c1ctl);
940
941 /* restore cursor */
942 outDAC1064(PMINFO M1064_XCURCTRL, curctl);
943
944 /* restore crtc2 */
945 mga_outl(M_C2CTL, c2ctl);
946
947 return;
948 }
949 #else
g450_preinit(WPMINFO2)950 static inline void g450_preinit(WPMINFO2) {
951 }
952 #endif
953
MGAG100_preinit(WPMINFO2)954 static 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 /* there are some instabilities if in_div > 19 && vco < 61000 */
968 if (ACCESS_FBINFO(devflags.g450dac)) {
969 ACCESS_FBINFO(features.pll.vco_freq_min) = 130000; /* my sample: >118 */
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 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
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 /* we must do this always, BIOS does not do it for us
1004 and accelerator dies without it */
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 /* it should help with G100 */
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
MGAG100_reset(WPMINFO2)1100 static 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); /* if found and bridging Matrox, do some strange stuff */
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); /* disable back-to-back & SERR */
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; /* FIXME... */
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 /* either leave MCLK as is... or they were set in preinit */
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
MGA1064_restore(WPMINFO struct display * p)1162 static 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
MGAG100_restore(WPMINFO struct display * p)1188 static 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
1215 struct matrox_switch matrox_mystique = {
1216 MGA1064_preinit, MGA1064_reset, MGA1064_init, MGA1064_restore, DAC1064_selhwcursor
1217 };
1218 EXPORT_SYMBOL(matrox_mystique);
1219 #endif
1220
1221 #ifdef CONFIG_FB_MATROX_G100
1222 struct matrox_switch matrox_G100 = {
1223 MGAG100_preinit, MGAG100_reset, MGAG100_init, MGAG100_restore, DAC1064_selhwcursor
1224 };
1225 EXPORT_SYMBOL(matrox_G100);
1226 #endif
1227
1228 #ifdef NEED_DAC1064
1229 EXPORT_SYMBOL(DAC1064_global_init);
1230 EXPORT_SYMBOL(DAC1064_global_restore);
1231 #endif
1232 MODULE_LICENSE("GPL");
1233