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 and G400
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
 * MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
12
 *
13
 * Contributors: "menion?" <menion@mindless.com>
14
 *                     Betatesting, fixes, ideas
15
 *
16
 *               "Kurt Garloff" <garloff@suse.de>
17
 *                     Betatesting, fixes, ideas, videomodes, videomodes timmings
18
 *
19
 *               "Tom Rini" <trini@kernel.crashing.org>
20
 *                     MTRR stuff, PPC cleanups, betatesting, fixes, ideas
21
 *
22
 *               "Bibek Sahu" <scorpio@dodds.net>
23
 *                     Access device through readb|w|l and write b|w|l
24
 *                     Extensive debugging stuff
25
 *
26
 *               "Daniel Haun" <haund@usa.net>
27
 *                     Testing, hardware cursor fixes
28
 *
29
 *               "Scott Wood" <sawst46+@pitt.edu>
30
 *                     Fixes
31
 *
32
 *               "Gerd Knorr" <kraxel@goldbach.isdn.cs.tu-berlin.de>
33
 *                     Betatesting
34
 *
35
 *               "Kelly French" <targon@hazmat.com>
36
 *               "Fernando Herrera" <fherrera@eurielec.etsit.upm.es>
37
 *                     Betatesting, bug reporting
38
 *
39
 *               "Pablo Bianucci" <pbian@pccp.com.ar>
40
 *                     Fixes, ideas, betatesting
41
 *
42
 *               "Inaky Perez Gonzalez" <inaky@peloncho.fis.ucm.es>
43
 *                     Fixes, enhandcements, ideas, betatesting
44
 *
45
 *               "Ryuichi Oikawa" <roikawa@rr.iiij4u.or.jp>
46
 *                     PPC betatesting, PPC support, backward compatibility
47
 *
48
 *               "Paul Womar" <Paul@pwomar.demon.co.uk>
49
 *               "Owen Waller" <O.Waller@ee.qub.ac.uk>
50
 *                     PPC betatesting
51
 *
52
 *               "Thomas Pornin" <pornin@bolet.ens.fr>
53
 *                     Alpha betatesting
54
 *
55
 *               "Pieter van Leuven" <pvl@iae.nl>
56
 *               "Ulf Jaenicke-Roessler" <ujr@physik.phy.tu-dresden.de>
57
 *                     G100 testing
58
 *
59
 *               "H. Peter Arvin" <hpa@transmeta.com>
60
 *                     Ideas
61
 *
62
 *               "Cort Dougan" <cort@cs.nmt.edu>
63
 *                     CHRP fixes and PReP cleanup
64
 *
65
 *               "Mark Vojkovich" <mvojkovi@ucsd.edu>
66
 *                     G400 support
67
 *
68
 * (following author is not in any relation with this code, but his code
69
 *  is included in this driver)
70
 *
71
 * Based on framebuffer driver for VBE 2.0 compliant graphic boards
72
 *     (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
73
 *
74
 * (following author is not in any relation with this code, but his ideas
75
 *  were used when writting this driver)
76
 *
77
 *               FreeVBE/AF (Matrox), "Shawn Hargreaves" <shawn@talula.demon.co.uk>
78
 *
79
 */
80
 
81
/* make checkconfig does not verify included files... */
82
#include <linuxcomp.h>
83
 
84
#include <linux/config.h>
85
 
86
#include "matroxfb_Ti3026.h"
87
#include "matroxfb_misc.h"
88
#include "matroxfb_accel.h"
89
#include <linux/matroxfb.h>
90
 
91
#ifdef CONFIG_FB_MATROX_MILLENIUM
92
#define outTi3026 matroxfb_DAC_out
93
#define inTi3026 matroxfb_DAC_in
94
 
95
#define TVP3026_INDEX           0x00
96
#define TVP3026_PALWRADD        0x00
97
#define TVP3026_PALDATA         0x01
98
#define TVP3026_PIXRDMSK        0x02
99
#define TVP3026_PALRDADD        0x03
100
#define TVP3026_CURCOLWRADD     0x04
101
#define     TVP3026_CLOVERSCAN          0x00
102
#define     TVP3026_CLCOLOR0            0x01
103
#define     TVP3026_CLCOLOR1            0x02
104
#define     TVP3026_CLCOLOR2            0x03
105
#define TVP3026_CURCOLDATA      0x05
106
#define TVP3026_CURCOLRDADD     0x07
107
#define TVP3026_CURCTRL         0x09
108
#define TVP3026_X_DATAREG       0x0A
109
#define TVP3026_CURRAMDATA      0x0B
110
#define TVP3026_CURPOSXL        0x0C
111
#define TVP3026_CURPOSXH        0x0D
112
#define TVP3026_CURPOSYL        0x0E
113
#define TVP3026_CURPOSYH        0x0F
114
 
115
#define TVP3026_XSILICONREV     0x01
116
#define TVP3026_XCURCTRL        0x06
117
#define     TVP3026_XCURCTRL_DIS        0x00    /* transparent, transparent, transparent, transparent */
118
#define     TVP3026_XCURCTRL_3COLOR     0x01    /* transparent, 0, 1, 2 */
119
#define     TVP3026_XCURCTRL_XGA        0x02    /* 0, 1, transparent, complement */
120
#define     TVP3026_XCURCTRL_XWIN       0x03    /* transparent, transparent, 0, 1 */
121
#define     TVP3026_XCURCTRL_BLANK2048  0x00
122
#define     TVP3026_XCURCTRL_BLANK4096  0x10
123
#define     TVP3026_XCURCTRL_INTERLACED 0x20
124
#define     TVP3026_XCURCTRL_ODD        0x00 /* ext.signal ODD/\EVEN */
125
#define     TVP3026_XCURCTRL_EVEN       0x40 /* ext.signal EVEN/\ODD */
126
#define     TVP3026_XCURCTRL_INDIRECT   0x00
127
#define     TVP3026_XCURCTRL_DIRECT     0x80
128
#define TVP3026_XLATCHCTRL      0x0F
129
#define     TVP3026_XLATCHCTRL_1_1      0x06
130
#define     TVP3026_XLATCHCTRL_2_1      0x07
131
#define     TVP3026_XLATCHCTRL_4_1      0x06
132
#define     TVP3026_XLATCHCTRL_8_1      0x06
133
#define     TVP3026_XLATCHCTRL_16_1     0x06
134
#define     TVP3026A_XLATCHCTRL_4_3     0x06    /* ??? do not understand... but it works... !!! */
135
#define     TVP3026A_XLATCHCTRL_8_3     0x07
136
#define     TVP3026B_XLATCHCTRL_4_3     0x08
137
#define     TVP3026B_XLATCHCTRL_8_3     0x06    /* ??? do not understand... but it works... !!! */
138
#define TVP3026_XTRUECOLORCTRL  0x18
139
#define     TVP3026_XTRUECOLORCTRL_VRAM_SHIFT_ACCEL     0x00
140
#define     TVP3026_XTRUECOLORCTRL_VRAM_SHIFT_TVP       0x20
141
#define     TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR          0x80
142
#define     TVP3026_XTRUECOLORCTRL_TRUECOLOR            0x40 /* paletized */
143
#define     TVP3026_XTRUECOLORCTRL_DIRECTCOLOR          0x00
144
#define     TVP3026_XTRUECOLORCTRL_24_ALTERNATE         0x08 /* 5:4/5:2 instead of 4:3/8:3 */
145
#define     TVP3026_XTRUECOLORCTRL_RGB_888              0x16 /* 4:3/8:3 (or 5:4/5:2) */
146
#define     TVP3026_XTRUECOLORCTRL_BGR_888              0x17
147
#define     TVP3026_XTRUECOLORCTRL_ORGB_8888            0x06
148
#define     TVP3026_XTRUECOLORCTRL_BGRO_8888            0x07
149
#define     TVP3026_XTRUECOLORCTRL_RGB_565              0x05
150
#define     TVP3026_XTRUECOLORCTRL_ORGB_1555            0x04
151
#define     TVP3026_XTRUECOLORCTRL_RGB_664              0x03
152
#define     TVP3026_XTRUECOLORCTRL_RGBO_4444            0x01
153
#define TVP3026_XMUXCTRL        0x19
154
#define     TVP3026_XMUXCTRL_MEMORY_8BIT                        0x01 /* - */
155
#define     TVP3026_XMUXCTRL_MEMORY_16BIT                       0x02 /* - */
156
#define     TVP3026_XMUXCTRL_MEMORY_32BIT                       0x03 /* 2MB RAM, 512K * 4 */
157
#define     TVP3026_XMUXCTRL_MEMORY_64BIT                       0x04 /* >2MB RAM, 512K * 8 & more */
158
#define     TVP3026_XMUXCTRL_PIXEL_4BIT                         0x40 /* L0,H0,L1,H1... */
159
#define     TVP3026_XMUXCTRL_PIXEL_4BIT_SWAPPED                 0x60 /* H0,L0,H1,L1... */
160
#define     TVP3026_XMUXCTRL_PIXEL_8BIT                         0x48
161
#define     TVP3026_XMUXCTRL_PIXEL_16BIT                        0x50
162
#define     TVP3026_XMUXCTRL_PIXEL_32BIT                        0x58
163
#define     TVP3026_XMUXCTRL_VGA                                0x98 /* VGA MEMORY, 8BIT PIXEL */
164
#define TVP3026_XCLKCTRL        0x1A
165
#define     TVP3026_XCLKCTRL_DIV1       0x00
166
#define     TVP3026_XCLKCTRL_DIV2       0x10
167
#define     TVP3026_XCLKCTRL_DIV4       0x20
168
#define     TVP3026_XCLKCTRL_DIV8       0x30
169
#define     TVP3026_XCLKCTRL_DIV16      0x40
170
#define     TVP3026_XCLKCTRL_DIV32      0x50
171
#define     TVP3026_XCLKCTRL_DIV64      0x60
172
#define     TVP3026_XCLKCTRL_CLKSTOPPED 0x70
173
#define     TVP3026_XCLKCTRL_SRC_CLK0   0x00
174
#define     TVP3026_XCLKCTRL_SRC_CLK1   0x01
175
#define     TVP3026_XCLKCTRL_SRC_CLK2   0x02    /* CLK2 is TTL source*/
176
#define     TVP3026_XCLKCTRL_SRC_NCLK2  0x03    /* not CLK2 is TTL source */
177
#define     TVP3026_XCLKCTRL_SRC_ECLK2  0x04    /* CLK2 and not CLK2 is ECL source */
178
#define     TVP3026_XCLKCTRL_SRC_PLL    0x05
179
#define     TVP3026_XCLKCTRL_SRC_DIS    0x06    /* disable & poweroff internal clock */
180
#define     TVP3026_XCLKCTRL_SRC_CLK0VGA 0x07
181
#define TVP3026_XPALETTEPAGE    0x1C
182
#define TVP3026_XGENCTRL        0x1D
183
#define     TVP3026_XGENCTRL_HSYNC_POS  0x00
184
#define     TVP3026_XGENCTRL_HSYNC_NEG  0x01
185
#define     TVP3026_XGENCTRL_VSYNC_POS  0x00
186
#define     TVP3026_XGENCTRL_VSYNC_NEG  0x02
187
#define     TVP3026_XGENCTRL_LITTLE_ENDIAN 0x00
188
#define     TVP3026_XGENCTRL_BIG_ENDIAN    0x08
189
#define     TVP3026_XGENCTRL_BLACK_0IRE         0x00
190
#define     TVP3026_XGENCTRL_BLACK_75IRE        0x10
191
#define     TVP3026_XGENCTRL_NO_SYNC_ON_GREEN   0x00
192
#define     TVP3026_XGENCTRL_SYNC_ON_GREEN      0x20
193
#define     TVP3026_XGENCTRL_OVERSCAN_DIS       0x00
194
#define     TVP3026_XGENCTRL_OVERSCAN_EN        0x40
195
#define TVP3026_XMISCCTRL       0x1E
196
#define     TVP3026_XMISCCTRL_DAC_PUP   0x00
197
#define     TVP3026_XMISCCTRL_DAC_PDOWN 0x01
198
#define     TVP3026_XMISCCTRL_DAC_EXT   0x00 /* or 8, bit 3 is ignored */
199
#define     TVP3026_XMISCCTRL_DAC_6BIT  0x04
200
#define     TVP3026_XMISCCTRL_DAC_8BIT  0x0C
201
#define     TVP3026_XMISCCTRL_PSEL_DIS  0x00
202
#define     TVP3026_XMISCCTRL_PSEL_EN   0x10
203
#define     TVP3026_XMISCCTRL_PSEL_LOW  0x00 /* PSEL high selects directcolor */
204
#define     TVP3026_XMISCCTRL_PSEL_HIGH 0x20 /* PSEL high selects truecolor or pseudocolor */
205
#define TVP3026_XGENIOCTRL      0x2A
206
#define TVP3026_XGENIODATA      0x2B
207
#define TVP3026_XPLLADDR        0x2C
208
#define     TVP3026_XPLLADDR_X(LOOP,MCLK,PIX) (((LOOP)<<4) | ((MCLK)<<2) | (PIX))
209
#define     TVP3026_XPLLDATA_N          0x00
210
#define     TVP3026_XPLLDATA_M          0x01
211
#define     TVP3026_XPLLDATA_P          0x02
212
#define     TVP3026_XPLLDATA_STAT       0x03
213
#define TVP3026_XPIXPLLDATA     0x2D
214
#define TVP3026_XMEMPLLDATA     0x2E
215
#define TVP3026_XLOOPPLLDATA    0x2F
216
#define TVP3026_XCOLKEYOVRMIN   0x30
217
#define TVP3026_XCOLKEYOVRMAX   0x31
218
#define TVP3026_XCOLKEYREDMIN   0x32
219
#define TVP3026_XCOLKEYREDMAX   0x33
220
#define TVP3026_XCOLKEYGREENMIN 0x34
221
#define TVP3026_XCOLKEYGREENMAX 0x35
222
#define TVP3026_XCOLKEYBLUEMIN  0x36
223
#define TVP3026_XCOLKEYBLUEMAX  0x37
224
#define TVP3026_XCOLKEYCTRL     0x38
225
#define     TVP3026_XCOLKEYCTRL_OVR_EN  0x01
226
#define     TVP3026_XCOLKEYCTRL_RED_EN  0x02
227
#define     TVP3026_XCOLKEYCTRL_GREEN_EN 0x04
228
#define     TVP3026_XCOLKEYCTRL_BLUE_EN 0x08
229
#define     TVP3026_XCOLKEYCTRL_NEGATE  0x10
230
#define     TVP3026_XCOLKEYCTRL_ZOOM1   0x00
231
#define     TVP3026_XCOLKEYCTRL_ZOOM2   0x20
232
#define     TVP3026_XCOLKEYCTRL_ZOOM4   0x40
233
#define     TVP3026_XCOLKEYCTRL_ZOOM8   0x60
234
#define     TVP3026_XCOLKEYCTRL_ZOOM16  0x80
235
#define     TVP3026_XCOLKEYCTRL_ZOOM32  0xA0
236
#define TVP3026_XMEMPLLCTRL     0x39
237
#define     TVP3026_XMEMPLLCTRL_DIV(X)  (((X)-1)>>1)    /* 2,4,6,8,10,12,14,16, division applied to LOOP PLL after divide by 2^P */
238
#define     TVP3026_XMEMPLLCTRL_STROBEMKC4      0x08
239
#define     TVP3026_XMEMPLLCTRL_MCLK_DOTCLOCK   0x00    /* MKC4 */
240
#define     TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL    0x10    /* MKC4 */
241
#define     TVP3026_XMEMPLLCTRL_RCLK_PIXPLL     0x00
242
#define     TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL    0x20
243
#define     TVP3026_XMEMPLLCTRL_RCLK_DOTDIVN    0x40    /* dot clock divided by loop pclk N prescaler */
244
#define TVP3026_XSENSETEST      0x3A
245
#define TVP3026_XTESTMODEDATA   0x3B
246
#define TVP3026_XCRCREML        0x3C
247
#define TVP3026_XCRCREMH        0x3D
248
#define TVP3026_XCRCBITSEL      0x3E
249
#define TVP3026_XID             0x3F
250
 
251
static const unsigned char DACseq[] =
252
{ TVP3026_XLATCHCTRL, TVP3026_XTRUECOLORCTRL,
253
  TVP3026_XMUXCTRL, TVP3026_XCLKCTRL,
254
  TVP3026_XPALETTEPAGE,
255
  TVP3026_XGENCTRL,
256
  TVP3026_XMISCCTRL,
257
  TVP3026_XGENIOCTRL,
258
  TVP3026_XGENIODATA,
259
  TVP3026_XCOLKEYOVRMIN, TVP3026_XCOLKEYOVRMAX, TVP3026_XCOLKEYREDMIN, TVP3026_XCOLKEYREDMAX,
260
  TVP3026_XCOLKEYGREENMIN, TVP3026_XCOLKEYGREENMAX, TVP3026_XCOLKEYBLUEMIN, TVP3026_XCOLKEYBLUEMAX,
261
  TVP3026_XCOLKEYCTRL,
262
  TVP3026_XMEMPLLCTRL, TVP3026_XSENSETEST, TVP3026_XCURCTRL };
263
 
264
#define POS3026_XLATCHCTRL      0
265
#define POS3026_XTRUECOLORCTRL  1
266
#define POS3026_XMUXCTRL        2
267
#define POS3026_XCLKCTRL        3
268
#define POS3026_XGENCTRL        5
269
#define POS3026_XMISCCTRL       6
270
#define POS3026_XMEMPLLCTRL     18
271
#define POS3026_XCURCTRL        20
272
 
273
static const unsigned char MGADACbpp32[] =
274
{ TVP3026_XLATCHCTRL_2_1, TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_8888,
275
  0x00, TVP3026_XCLKCTRL_DIV1 | TVP3026_XCLKCTRL_SRC_PLL,
276
  0x00,
277
  TVP3026_XGENCTRL_HSYNC_POS | TVP3026_XGENCTRL_VSYNC_POS | TVP3026_XGENCTRL_LITTLE_ENDIAN | TVP3026_XGENCTRL_BLACK_0IRE | TVP3026_XGENCTRL_NO_SYNC_ON_GREEN | TVP3026_XGENCTRL_OVERSCAN_DIS,
278
  TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_HIGH,
279
  0x00,
280
  0x1E,
281
  0xFF, 0xFF, 0xFF, 0xFF,
282
  0xFF, 0xFF, 0xFF, 0xFF,
283
  TVP3026_XCOLKEYCTRL_ZOOM1,
284
  0x00, 0x00, TVP3026_XCURCTRL_DIS };
285
 
286
static int Ti3026_calcclock(CPMINFO unsigned int freq, unsigned int fmax, int* in, int* feed, int* post) {
287
        unsigned int fvco;
288
        unsigned int lin, lfeed, lpost;
289
 
290
        DBG(__FUNCTION__)
291
 
292
        fvco = PLL_calcclock(PMINFO freq, fmax, &lin, &lfeed, &lpost);
293
        fvco >>= (*post = lpost);
294
        *in = 64 - lin;
295
        *feed = 64 - lfeed;
296
        return fvco;
297
}
298
 
299
static int Ti3026_setpclk(WPMINFO int clk) {
300
        unsigned int f_pll;
301
        unsigned int pixfeed, pixin, pixpost;
302
        struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
303
 
304
        DBG(__FUNCTION__)
305
 
306
        f_pll = Ti3026_calcclock(PMINFO clk, ACCESS_FBINFO(max_pixel_clock), &pixin, &pixfeed, &pixpost);
307
 
308
        hw->DACclk[0] = pixin | 0xC0;
309
        hw->DACclk[1] = pixfeed;
310
        hw->DACclk[2] = pixpost | 0xB0;
311
 
312
        {
313
                unsigned int loopfeed, loopin, looppost, loopdiv, z;
314
                unsigned int Bpp;
315
 
316
                Bpp = ACCESS_FBINFO(curr.final_bppShift);
317
 
318
                if (ACCESS_FBINFO(fbcon).var.bits_per_pixel == 24) {
319
                        loopfeed = 3;           /* set lm to any possible value */
320
                        loopin = 3 * 32 / Bpp;
321
                } else {
322
                        loopfeed = 4;
323
                        loopin = 4 * 32 / Bpp;
324
                }
325
                z = (110000 * loopin) / (f_pll * loopfeed);
326
                loopdiv = 0; /* div 2 */
327
                if (z < 2)
328
                        looppost = 0;
329
                else if (z < 4)
330
                        looppost = 1;
331
                else if (z < 8)
332
                        looppost = 2;
333
                else {
334
                        looppost = 3;
335
                        loopdiv = z/16;
336
                }
337
                if (ACCESS_FBINFO(fbcon).var.bits_per_pixel == 24) {
338
                        hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
339
                        hw->DACclk[4] = (65 - loopfeed) | 0x80;
340
                        if (ACCESS_FBINFO(accel.ramdac_rev) > 0x20) {
341
                                if (isInterleave(MINFO))
342
                                        hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3;
343
                                else {
344
                                        hw->DACclk[4] &= ~0xC0;
345
                                        hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3;
346
                                }
347
                        } else {
348
                                if (isInterleave(MINFO))
349
                                        ;       /* default... */
350
                                else {
351
                                        hw->DACclk[4] ^= 0xC0;  /* change from 0x80 to 0x40 */
352
                                        hw->DACreg[POS3026_XLATCHCTRL] = TVP3026A_XLATCHCTRL_4_3;
353
                                }
354
                        }
355
                        hw->DACclk[5] = looppost | 0xF8;
356
                        if (ACCESS_FBINFO(devflags.mga_24bpp_fix))
357
                                hw->DACclk[5] ^= 0x40;
358
                } else {
359
                        hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0;
360
                        hw->DACclk[4] = 65 - loopfeed;
361
                        hw->DACclk[5] = looppost | 0xF0;
362
                }
363
                hw->DACreg[POS3026_XMEMPLLCTRL] = loopdiv | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL;
364
        }
365
        return 0;
366
}
367
 
368
static int Ti3026_init(WPMINFO struct my_timming* m) {
369
        u_int8_t muxctrl = isInterleave(MINFO) ? TVP3026_XMUXCTRL_MEMORY_64BIT : TVP3026_XMUXCTRL_MEMORY_32BIT;
370
        struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
371
 
372
        DBG(__FUNCTION__)
373
 
374
        memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg));
375
        switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) {
376
                case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1;       /* or _8_1, they are same */
377
                        hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
378
                        hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT;
379
                        hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV8;
380
                        hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
381
                        break;
382
                case 8: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_8_1;        /* or _4_1, they are same */
383
                        hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
384
                        hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_8BIT;
385
                        hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
386
                        hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;
387
                        break;
388
                case 16:
389
                        /* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */
390
                        hw->DACreg[POS3026_XTRUECOLORCTRL] = (ACCESS_FBINFO(fbcon).var.green.length == 5)? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555 ) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565);
391
                        hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT;
392
                        hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2;
393
                        break;
394
                case 24:
395
                        /* XLATCHCTRL is: for (A) use _4_3 (?_8_3 is same? TBD), for (B) it is set in setpclk */
396
                        hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_888;
397
                        hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
398
                        hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;
399
                        break;
400
                case 32:
401
                        /* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used everytime) */
402
                        hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;
403
                        break;
404
                default:
405
                        return 1;       /* TODO: failed */
406
        }
407
        if (matroxfb_vgaHWinit(PMINFO m)) return 1;
408
 
409
        /* set SYNC */
410
        hw->MiscOutReg = 0xCB;
411
        if (m->sync & FB_SYNC_HOR_HIGH_ACT)
412
                hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_HSYNC_NEG;
413
        if (m->sync & FB_SYNC_VERT_HIGH_ACT)
414
                hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_VSYNC_NEG;
415
        if (m->sync & FB_SYNC_ON_GREEN)
416
                hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN;
417
 
418
        /* set DELAY */
419
        if (ACCESS_FBINFO(video.len) < 0x400000)
420
                hw->CRTCEXT[3] |= 0x08;
421
        else if (ACCESS_FBINFO(video.len) > 0x400000)
422
                hw->CRTCEXT[3] |= 0x10;
423
 
424
        /* set HWCURSOR */
425
        if (m->interlaced) {
426
                hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_INTERLACED;
427
        }
428
        if (m->HTotal >= 1536)
429
                hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_BLANK4096;
430
 
431
        /* set interleaving */
432
        hw->MXoptionReg &= ~0x00001000;
433
        if (isInterleave(MINFO)) hw->MXoptionReg |= 0x00001000;
434
 
435
        /* set DAC */
436
        Ti3026_setpclk(PMINFO m->pixclock);
437
        return 0;
438
}
439
 
440
static void ti3026_setMCLK(WPMINFO int fout){
441
        unsigned int f_pll;
442
        unsigned int pclk_m, pclk_n, pclk_p;
443
        unsigned int mclk_m, mclk_n, mclk_p;
444
        unsigned int rfhcnt, mclk_ctl;
445
        int tmout;
446
 
447
        DBG(__FUNCTION__)
448
 
449
        f_pll = Ti3026_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &mclk_n, &mclk_m, &mclk_p);
450
 
451
        /* save pclk */
452
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
453
        pclk_n = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
454
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xFD);
455
        pclk_m = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
456
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
457
        pclk_p = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
458
 
459
        /* stop pclk */
460
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
461
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
462
 
463
        /* set pclk to new mclk */
464
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
465
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_n | 0xC0);
466
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_m);
467
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_p | 0xB0);
468
 
469
        /* wait for PLL to lock */
470
        for (tmout = 500000; tmout; tmout--) {
471
                if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)
472
                        break;
473
                udelay(10);
474
        };
475
        if (!tmout)
476
                printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n");
477
 
478
        /* output pclk on mclk pin */
479
        mclk_ctl = inTi3026(PMINFO TVP3026_XMEMPLLCTRL);
480
        outTi3026(PMINFO TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7);
481
        outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4);
482
 
483
        /* stop MCLK */
484
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xFB);
485
        outTi3026(PMINFO TVP3026_XMEMPLLDATA, 0x00);
486
 
487
        /* set mclk to new freq */
488
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xF3);
489
        outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_n | 0xC0);
490
        outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_m);
491
        outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_p | 0xB0);
492
 
493
        /* wait for PLL to lock */
494
        for (tmout = 500000; tmout; tmout--) {
495
                if (inTi3026(PMINFO TVP3026_XMEMPLLDATA) & 0x40)
496
                        break;
497
                udelay(10);
498
        }
499
        if (!tmout)
500
                printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n");
501
 
502
        f_pll = f_pll * 333 / (10000 << mclk_p);
503
        if (isMilleniumII(MINFO)) {
504
                rfhcnt = (f_pll - 128) / 256;
505
                if (rfhcnt > 15)
506
                        rfhcnt = 15;
507
        } else {
508
                rfhcnt = (f_pll - 64) / 128;
509
                if (rfhcnt > 15)
510
                        rfhcnt = 0;
511
        }
512
        ACCESS_FBINFO(hw).MXoptionReg = (ACCESS_FBINFO(hw).MXoptionReg & ~0x000F0000) | (rfhcnt << 16);
513
        pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);
514
 
515
        /* output MCLK to MCLK pin */
516
        outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
517
        outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl       ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4);
518
 
519
        /* stop PCLK */
520
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);
521
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
522
 
523
        /* restore pclk */
524
        outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);
525
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_n);
526
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_m);
527
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_p);
528
 
529
        /* wait for PLL to lock */
530
        for (tmout = 500000; tmout; tmout--) {
531
                if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)
532
                        break;
533
                udelay(10);
534
        }
535
        if (!tmout)
536
                printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
537
}
538
 
539
static void ti3026_ramdac_init(WPMINFO2) {
540
 
541
        DBG(__FUNCTION__)
542
 
543
        ACCESS_FBINFO(features.pll.vco_freq_min) = 110000;
544
        ACCESS_FBINFO(features.pll.ref_freq)     = 114545;
545
        ACCESS_FBINFO(features.pll.feed_div_min) = 2;
546
        ACCESS_FBINFO(features.pll.feed_div_max) = 24;
547
        ACCESS_FBINFO(features.pll.in_div_min)   = 2;
548
        ACCESS_FBINFO(features.pll.in_div_max)   = 63;
549
        ACCESS_FBINFO(features.pll.post_shift_max) = 3;
550
        if (ACCESS_FBINFO(devflags.noinit))
551
                return;
552
        ti3026_setMCLK(PMINFO 60000);
553
}
554
 
555
static void Ti3026_restore(WPMINFO2) {
556
        int i;
557
        unsigned char progdac[6];
558
        struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
559
        CRITFLAGS
560
 
561
        DBG(__FUNCTION__)
562
 
563
#ifdef DEBUG
564
        dprintk(KERN_INFO "EXTVGA regs: ");
565
        for (i = 0; i < 6; i++)
566
                dprintk("%02X:", hw->CRTCEXT[i]);
567
        dprintk("\n");
568
#endif
569
 
570
        CRITBEGIN
571
 
572
        pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
573
 
574
        CRITEND
575
 
576
        matroxfb_vgaHWrestore(PMINFO2);
577
 
578
        CRITBEGIN
579
 
580
        ACCESS_FBINFO(crtc1.panpos) = -1;
581
        for (i = 0; i < 6; i++)
582
                mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
583
 
584
        for (i = 0; i < 21; i++) {
585
                outTi3026(PMINFO DACseq[i], hw->DACreg[i]);
586
        }
587
 
588
        outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
589
        progdac[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
590
        progdac[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
591
        outTi3026(PMINFO TVP3026_XPLLADDR, 0x15);
592
        progdac[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
593
        progdac[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
594
        outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
595
        progdac[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
596
        progdac[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
597
 
598
        CRITEND
599
        if (memcmp(hw->DACclk, progdac, 6)) {
600
                /* agrhh... setting up PLL is very slow on Millennium... */
601
                /* Mystique PLL is locked in few ms, but Millennium PLL lock takes about 0.15 s... */
602
                /* Maybe even we should call schedule() ? */
603
 
604
                CRITBEGIN
605
                outTi3026(PMINFO TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]);
606
                outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
607
                outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0);
608
                outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0);
609
 
610
                outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
611
                for (i = 0; i < 3; i++)
612
                        outTi3026(PMINFO TVP3026_XPIXPLLDATA, hw->DACclk[i]);
613
                /* wait for PLL only if PLL clock requested (always for PowerMode, never for VGA) */
614
                if (hw->MiscOutReg & 0x08) {
615
                        int tmout;
616
                        outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);
617
                        for (tmout = 500000; tmout; --tmout) {
618
                                if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)
619
                                        break;
620
                                udelay(10);
621
                        }
622
 
623
                        CRITEND
624
 
625
                        if (!tmout)
626
                                printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
627
                        else
628
                                dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout);
629
                        CRITBEGIN
630
                }
631
                outTi3026(PMINFO TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]);
632
                outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
633
                for (i = 3; i < 6; i++)
634
                        outTi3026(PMINFO TVP3026_XLOOPPLLDATA, hw->DACclk[i]);
635
                CRITEND
636
                if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) {
637
                        int tmout;
638
 
639
                        CRITBEGIN
640
                        outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);
641
                        for (tmout = 500000; tmout; --tmout) {
642
                                if (inTi3026(PMINFO TVP3026_XLOOPPLLDATA) & 0x40)
643
                                        break;
644
                                udelay(10);
645
                        }
646
                        CRITEND
647
                        if (!tmout)
648
                                printk(KERN_ERR "matroxfb: Loop PLL not locked after 5 secs\n");
649
                        else
650
                                dprintk(KERN_INFO "LoopPLL: %d\n", 500000-tmout);
651
                }
652
        }
653
 
654
#ifdef DEBUG
655
        dprintk(KERN_DEBUG "3026DACregs ");
656
        for (i = 0; i < 21; i++) {
657
                dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]);
658
                if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
659
        }
660
        dprintk("\n" KERN_DEBUG "DACclk ");
661
        for (i = 0; i < 6; i++)
662
                dprintk("C%02X=%02X ", i, hw->DACclk[i]);
663
        dprintk("\n");
664
#endif
665
}
666
 
667
static void Ti3026_reset(WPMINFO2) {
668
 
669
        DBG(__FUNCTION__)
670
 
671
        ti3026_ramdac_init(PMINFO2);
672
}
673
 
674
static struct matrox_altout ti3026_output = {
675
        .name    = "Primary output",
676
};
677
 
678
static int Ti3026_preinit(WPMINFO2) {
679
        static const int vxres_mill2[] = { 512,        640, 768,  800,  832,  960,
680
                                          1024, 1152, 1280,      1600, 1664, 1920,
681
                                          2048, 0};
682
        static const int vxres_mill1[] = {             640, 768,  800,        960,
683
                                          1024, 1152, 1280,      1600,       1920,
684
                                          2048, 0};
685
        struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);
686
 
687
        DBG(__FUNCTION__)
688
 
689
        ACCESS_FBINFO(millenium) = 1;
690
        ACCESS_FBINFO(milleniumII) = (ACCESS_FBINFO(pcidev)->device != PCI_DEVICE_ID_MATROX_MIL);
691
        ACCESS_FBINFO(capable.cfb4) = 1;
692
        ACCESS_FBINFO(capable.text) = 1; /* isMilleniumII(MINFO); */
693
        ACCESS_FBINFO(capable.vxres) = isMilleniumII(MINFO)?vxres_mill2:vxres_mill1;
694
 
695
        ACCESS_FBINFO(outputs[0]).data = MINFO;
696
        ACCESS_FBINFO(outputs[0]).output = &ti3026_output;
697
        ACCESS_FBINFO(outputs[0]).src = MATROXFB_SRC_CRTC1;
698
        ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
699
 
700
        if (ACCESS_FBINFO(devflags.noinit))
701
                return 0;
702
        /* preserve VGA I/O, BIOS and PPC */
703
        hw->MXoptionReg &= 0xC0000100;
704
        hw->MXoptionReg |= 0x002C0000;
705
        if (ACCESS_FBINFO(devflags.novga))
706
                hw->MXoptionReg &= ~0x00000100;
707
        if (ACCESS_FBINFO(devflags.nobios))
708
                hw->MXoptionReg &= ~0x40000000;
709
        if (ACCESS_FBINFO(devflags.nopciretry))
710
                hw->MXoptionReg |=  0x20000000;
711
        pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
712
 
713
        ACCESS_FBINFO(accel.ramdac_rev) = inTi3026(PMINFO TVP3026_XSILICONREV);
714
 
715
        outTi3026(PMINFO TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED);
716
        outTi3026(PMINFO TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR);
717
        outTi3026(PMINFO TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA);
718
 
719
        outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
720
        outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0x00);
721
        outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);
722
 
723
        mga_outb(M_MISC_REG, 0x67);
724
 
725
        outTi3026(PMINFO TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);
726
 
727
        mga_outl(M_RESET, 1);
728
        udelay(250);
729
        mga_outl(M_RESET, 0);
730
        udelay(250);
731
        mga_outl(M_MACCESS, 0x00008000);
732
        udelay(10);
733
        return 0;
734
}
735
 
736
struct matrox_switch matrox_millennium = {
737
        Ti3026_preinit, Ti3026_reset, Ti3026_init, Ti3026_restore
738
};
739
EXPORT_SYMBOL(matrox_millennium);
740
#endif
741
MODULE_LICENSE("GPL");