Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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