~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 1992-2000 by Alan Hourihane, Wigan, England.
 
3
 *
 
4
 * Permission to use, copy, modify, distribute, and sell this software and its
 
5
 * documentation for any purpose is hereby granted without fee, provided that
 
6
 * the above copyright notice appear in all copies and that both that
 
7
 * copyright notice and this permission notice appear in supporting
 
8
 * documentation, and that the name of Alan Hourihane not be used in
 
9
 * advertising or publicity pertaining to distribution of the software without
 
10
 * specific, written prior permission.  Alan Hourihane makes no representations
 
11
 * about the suitability of this software for any purpose.  It is provided
 
12
 * "as is" without express or implied warranty.
 
13
 *
 
14
 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
15
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
16
 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
17
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
18
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
19
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
20
 * PERFORMANCE OF THIS SOFTWARE.
 
21
 *
 
22
 * Author:  Alan Hourihane, alanh@fairlite.demon.co.uk
 
23
 */
 
24
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.70 2003/01/05 18:09:00 alanh Exp $ */
 
25
 
 
26
#include "xf86.h"
 
27
#include "xf86_OSproc.h"
 
28
#include "xf86_ansic.h"
 
29
#include "xf86Version.h"
 
30
#include "xf86PciInfo.h"
 
31
#include "xf86Pci.h"
 
32
 
 
33
#include "vgaHW.h"
 
34
 
 
35
#include "trident.h"
 
36
#include "trident_regs.h"
 
37
 
 
38
 
 
39
static biosMode bios1[] = { 
 
40
    { 640, 480, 0x11 }
 
41
};
 
42
 
 
43
static biosMode bios4[] = {
 
44
    { 320, 200, 0xd },
 
45
    { 640, 200, 0xe },
 
46
    { 640, 350, 0x11 },
 
47
    { 640, 480, 0x12 },
 
48
    { 800, 600, 0x5b },
 
49
    { 1024, 768 , 0x5f },
 
50
    { 1280, 1024, 0x63 },
 
51
    { 1600, 1200, 0x65 }
 
52
};
 
53
 
 
54
static biosMode bios8[] = {     
 
55
    { 320, 200, 0x13 },
 
56
    { 640, 400, 0x5c },
 
57
    { 640, 480, 0x5d },
 
58
    { 720, 480, 0x60 },
 
59
    { 800, 600, 0x5e },
 
60
    { 1024, 768, 0x62 },
 
61
    { 1280, 1024, 0x64 },
 
62
    { 1600, 1200, 0x66 }
 
63
};
 
64
 
 
65
static biosMode bios15[] = {
 
66
    { 640, 400, 0x72 },
 
67
    { 640, 480, 0x74 },
 
68
    { 720, 480, 0x70 },
 
69
    { 800, 600, 0x76 },
 
70
    { 1024, 768, 0x78 },
 
71
    { 1280, 1024, 0x7a },
 
72
    { 1600, 1200, 0x7c }
 
73
};
 
74
 
 
75
static biosMode bios16[] = {
 
76
    { 640, 400, 0x73 },
 
77
    { 640, 480, 0x75 },
 
78
    { 720, 480, 0x71 },
 
79
    { 800, 600, 0x77 },
 
80
    { 1024, 768, 0x79 },
 
81
    { 1280, 1024, 0x7b },
 
82
    { 1600, 1200, 0x7d }
 
83
};
 
84
 
 
85
static biosMode bios24[] = {
 
86
    { 640, 400, 0x6b },
 
87
    { 640, 480, 0x6c },
 
88
    { 720, 480, 0x61 },
 
89
    { 800, 600, 0x6d },
 
90
    { 1024, 768, 0x6e }
 
91
};
 
92
 
 
93
static newModes newModeRegs [] = {
 
94
  { 320, 200, 0x13, 0x30 },
 
95
  { 640, 480, 0x13, 0x61 },
 
96
  { 800, 600, 0x13, 0x61 },
 
97
  { 1024, 768, 0x3b, 0x63 },
 
98
  { 1280, 1024, 0x7b, 0x64 },
 
99
  { 1400, 1050, 0x11, 0x7b } 
 
100
};
 
101
 
 
102
int
 
103
TridentFindMode(int xres, int yres, int depth)
 
104
{
 
105
    int xres_s;
 
106
    int i, size;
 
107
    biosMode *mode;
 
108
 
 
109
    switch (depth) {
 
110
    case 1:
 
111
        size = sizeof(bios1) / sizeof(biosMode);
 
112
        mode = bios1;
 
113
        break;
 
114
    case 4:
 
115
        size = sizeof(bios4) / sizeof(biosMode);
 
116
        mode = bios4;
 
117
        break;
 
118
    case 8:
 
119
        size = sizeof(bios8) / sizeof(biosMode);
 
120
        mode = bios8;
 
121
        break;
 
122
    case 15:
 
123
        size = sizeof(bios15) / sizeof(biosMode);
 
124
        mode = bios15;
 
125
        break;
 
126
    case 16:
 
127
        size = sizeof(bios16) / sizeof(biosMode);
 
128
        mode = bios16;
 
129
        break;
 
130
    case 24:
 
131
        size = sizeof(bios24) / sizeof(biosMode);
 
132
        mode = bios24;
 
133
        break;
 
134
    default:
 
135
        return 0;
 
136
    }
 
137
 
 
138
    for (i = 0; i < size; i++) {
 
139
        if (xres <= mode[i].x_res) {
 
140
            xres_s = mode[i].x_res;
 
141
            for (; i < size; i++) {
 
142
                if (mode[i].x_res != xres_s)
 
143
                    return mode[i-1].mode;
 
144
                if (yres <= mode[i].y_res)
 
145
                    return mode[i].mode;
 
146
            }
 
147
        }
 
148
    }
 
149
    return mode[size - 1].mode;
 
150
}
 
151
 
 
152
static void
 
153
TridentFindNewMode(int xres, int yres, CARD8 *gr5a, CARD8 *gr5c)
 
154
{
 
155
    int xres_s;
 
156
    int i, size;
 
157
    
 
158
    size = sizeof(newModeRegs) / sizeof(newModes);
 
159
 
 
160
    for (i = 0; i < size; i++) {
 
161
        if (xres <= newModeRegs[i].x_res) {
 
162
            xres_s = newModeRegs[i].x_res;
 
163
            for (; i < size; i++) {
 
164
                if (newModeRegs[i].x_res != xres_s 
 
165
                    || yres <= newModeRegs[i].y_res) {
 
166
                  *gr5a = newModeRegs[i].GR5a;
 
167
                  *gr5c = newModeRegs[i].GR5c;
 
168
                  return;
 
169
                }
 
170
            }
 
171
        }
 
172
    }
 
173
    *gr5a = newModeRegs[size - 1].GR5a;
 
174
    *gr5c = newModeRegs[size - 1].GR5c;
 
175
    return;
 
176
}
 
177
 
 
178
static void
 
179
tridentSetBrightnessAndGamma(TRIDENTRegPtr tridentReg,
 
180
                             Bool on, double exp,int brightness)
 
181
{
 
182
    int pivots[] = {0,3,15,63,255};
 
183
 
 
184
    double slope;
 
185
    double y_0;
 
186
    double x, x_prev = 0, y, y_prev = 0;
 
187
    int i;
 
188
    CARD8 i_slopes[4];
 
189
    CARD8 intercepts[4];
 
190
 
 
191
    if (!on) {
 
192
        tridentReg->tridentRegs3C4[0xB4] &= ~0x80;
 
193
        return;
 
194
    }
 
195
 
 
196
    for (i = 0; i < 4; i++) {
 
197
        x = pivots[i + 1] / 255.0;
 
198
        y = pow(x,exp);
 
199
        slope = (y - y_prev) / (x - x_prev);
 
200
        y_0 = y - x * slope;
 
201
        {
 
202
#define RND(x) ((((x) - (int) (x)) < 0.5) ? (int)(x) : (int)(x) + 1)
 
203
            int val = slope;
 
204
            if (val > 7) 
 
205
                i_slopes[i] = (3 << 4) | (RND(slope) & 0xf);
 
206
            else if (val > 3) 
 
207
                i_slopes[i] = (2 << 4) | (RND(slope * 2) & 0xf);
 
208
            else if (val > 1) 
 
209
                i_slopes[i] = (1 << 4) | (RND(slope * 4) & 0xf);
 
210
            else 
 
211
                i_slopes[i] = (RND(slope * 8) & 0xf);
 
212
#undef RND
 
213
        }
 
214
        intercepts[i] = (char)(y_0 * 256 / 4);
 
215
        x_prev = x;
 
216
        y_prev = y;
 
217
    }
 
218
    
 
219
    tridentReg->tridentRegs3C4[0xB4] = 0x80 | i_slopes[0];
 
220
    tridentReg->tridentRegs3C4[0xB5] = i_slopes[1];
 
221
    tridentReg->tridentRegs3C4[0xB6] = i_slopes[2];
 
222
    tridentReg->tridentRegs3C4[0xB7] = i_slopes[3];
 
223
    tridentReg->tridentRegs3C4[0xB8] = (intercepts[0] + brightness);
 
224
    tridentReg->tridentRegs3C4[0xB9] = (intercepts[1] + brightness);
 
225
    tridentReg->tridentRegs3C4[0xBA] = (intercepts[2] + brightness);
 
226
    tridentReg->tridentRegs3C4[0xBB] = (intercepts[3] + brightness);
 
227
}
 
228
 
 
229
Bool
 
230
TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
 
231
{
 
232
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
233
    TRIDENTRegPtr pReg = &pTrident->ModeReg;
 
234
 
 
235
    int vgaIOBase;
 
236
    int offset = 0;
 
237
    int clock = pTrident->currentClock;
 
238
    CARD8 protect = 0;
 
239
    Bool fullSize = FALSE;
 
240
    Bool isShadow = FALSE;
 
241
 
 
242
    vgaHWPtr hwp = VGAHWPTR(pScrn);
 
243
    vgaRegPtr regp = &hwp->ModeReg;
 
244
    vgaRegPtr vgaReg = &hwp->ModeReg;
 
245
    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
246
 
 
247
    /* Unprotect */
 
248
    if (pTrident->Chipset > PROVIDIA9685) {
 
249
        OUTB(0x3C4, Protection);
 
250
        protect = INB(0x3C5);
 
251
        OUTB(0x3C5, 0x92);
 
252
    }
 
253
 
 
254
    OUTB(0x3C4, 0x0B); INB(0x3C5); /* Ensure we are in New Mode */
 
255
 
 
256
    pReg->tridentRegs3x4[PixelBusReg] = 0x00;
 
257
    pReg->tridentRegsDAC[0x00] = 0x00;
 
258
    pReg->tridentRegs3C4[NewMode2] = 0x20;
 
259
    OUTB(0x3CE, MiscExtFunc);
 
260
    pReg->tridentRegs3CE[MiscExtFunc] = INB(0x3CF) & 0xF0;
 
261
    pReg->tridentRegs3x4[GraphEngReg] = 0x00; 
 
262
    pReg->tridentRegs3x4[PreEndControl] = 0;
 
263
    pReg->tridentRegs3x4[PreEndFetch] = 0;
 
264
 
 
265
    pReg->tridentRegs3x4[CRTHiOrd] = (((mode->CrtcVBlankEnd-1) & 0x400)>>4) |
 
266
                                     (((mode->CrtcVTotal - 2) & 0x400) >> 3) |
 
267
                                     ((mode->CrtcVSyncStart & 0x400) >> 5) |
 
268
                                     (((mode->CrtcVDisplay - 1) & 0x400) >> 6)|
 
269
                                     0x08;
 
270
 
 
271
    pReg->tridentRegs3x4[HorizOverflow] = ((mode->CrtcHTotal & 0x800) >> 11) |
 
272
                                          ((mode->CrtcHBlankStart & 0x800)>>7);
 
273
 
 
274
    if (pTrident->IsCyber) {
 
275
        Bool LCDActive;
 
276
#ifdef READOUT
 
277
        Bool ShadowModeActive;
 
278
#endif
 
279
        int i = pTrident->lcdMode;
 
280
#ifdef READOUT
 
281
        OUTB(0x3CE, CyberControl);
 
282
        ShadowModeActive = ((INB(0x3CF) & 0x81) == 0x81);
 
283
#endif
 
284
        OUTB(0x3CE, FPConfig);
 
285
        pReg->tridentRegs3CE[FPConfig] = INB(0x3CF);
 
286
        if (pTrident->dspOverride) {
 
287
            if (pTrident->dspOverride & LCD_ACTIVE) {
 
288
                pReg->tridentRegs3CE[FPConfig] |= 0x10;
 
289
                    LCDActive = TRUE;
 
290
            } else {
 
291
                pReg->tridentRegs3CE[FPConfig] &= ~0x10;
 
292
                    LCDActive = FALSE;
 
293
            }
 
294
            if (pTrident->dspOverride & CRT_ACTIVE)
 
295
                pReg->tridentRegs3CE[FPConfig] |= 0x20;
 
296
            else
 
297
                pReg->tridentRegs3CE[FPConfig] &= ~0x20;
 
298
        } else {
 
299
            LCDActive = (pReg->tridentRegs3CE[FPConfig] & 0x10);
 
300
        }
 
301
 
 
302
        OUTB(0x3CE, CyberEnhance); 
 
303
#if 0
 
304
        pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF);
 
305
#else
 
306
        pReg->tridentRegs3CE[CyberEnhance] = INB(0x3CF) & 0x8F;
 
307
        if (mode->CrtcVDisplay > 1024)
 
308
            pReg->tridentRegs3CE[CyberEnhance] |= 0x50;
 
309
        else
 
310
        if (mode->CrtcVDisplay > 768)
 
311
            pReg->tridentRegs3CE[CyberEnhance] |= 0x30;
 
312
        else
 
313
        if (mode->CrtcVDisplay > 600)
 
314
            pReg->tridentRegs3CE[CyberEnhance] |= 0x20;
 
315
        else
 
316
        if (mode->CrtcVDisplay > 480)
 
317
            pReg->tridentRegs3CE[CyberEnhance] |= 0x10;
 
318
#endif
 
319
        OUTB(0x3CE, CyberControl);
 
320
        pReg->tridentRegs3CE[CyberControl] = INB(0x3CF);
 
321
 
 
322
        OUTB(0x3CE,HorStretch);
 
323
        pReg->tridentRegs3CE[HorStretch] = INB(0x3CF);
 
324
        OUTB(0x3CE,VertStretch);
 
325
        pReg->tridentRegs3CE[VertStretch] = INB(0x3CF);
 
326
 
 
327
#ifdef READOUT
 
328
        if ((!((pReg->tridentRegs3CE[VertStretch] & 1) ||
 
329
               (pReg->tridentRegs3CE[HorStretch] & 1)))
 
330
            && (!LCDActive || ShadowModeActive)) 
 
331
          {
 
332
            unsigned char tmp;
 
333
            
 
334
            SHADOW_ENABLE(tmp);
 
335
            OUTB(vgaIOBase + 4,0);
 
336
            pReg->tridentRegs3x4[0x0] = INB(vgaIOBase + 5);
 
337
            OUTB(vgaIOBase + 4,3);
 
338
            pReg->tridentRegs3x4[0x3] = INB(vgaIOBase + 5);
 
339
            OUTB(vgaIOBase + 4,4);
 
340
            pReg->tridentRegs3x4[0x4] = INB(vgaIOBase + 5);
 
341
            OUTB(vgaIOBase + 4,5);
 
342
            pReg->tridentRegs3x4[0x5] = INB(vgaIOBase + 5);
 
343
            OUTB(vgaIOBase + 4,0x6);
 
344
            pReg->tridentRegs3x4[0x6] = INB(vgaIOBase + 5);
 
345
            SHADOW_RESTORE(tmp);
 
346
        } else
 
347
#endif
 
348
        {
 
349
            if (i != 0xff) {
 
350
                pReg->tridentRegs3x4[0x0] = LCD[i].shadow_0;
 
351
                pReg->tridentRegs3x4[0x1] = regp->CRTC[1];
 
352
                pReg->tridentRegs3x4[0x2] = regp->CRTC[2];
 
353
                pReg->tridentRegs3x4[0x3] = LCD[i].shadow_3;
 
354
                pReg->tridentRegs3x4[0x4] = LCD[i].shadow_4;
 
355
                pReg->tridentRegs3x4[0x5] = LCD[i].shadow_5;
 
356
                pReg->tridentRegs3x4[0x6] = LCD[i].shadow_6;
 
357
                xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,
 
358
                               "Overriding Horizontal timings.\n");
 
359
            }
 
360
        }
 
361
 
 
362
        if (i != 0xff) {
 
363
            pReg->tridentRegs3x4[0x7] = LCD[i].shadow_7;
 
364
            pReg->tridentRegs3x4[0x10] = LCD[i].shadow_10;
 
365
            pReg->tridentRegs3x4[0x11] = LCD[i].shadow_11;
 
366
            pReg->tridentRegs3x4[0x12] = regp->CRTC[0x12];
 
367
            pReg->tridentRegs3x4[0x15] = regp->CRTC[0x15];
 
368
            pReg->tridentRegs3x4[0x16] = LCD[i].shadow_16;
 
369
            if (LCDActive) {
 
370
                pReg->tridentRegs3x4[CRTHiOrd] = LCD[i].shadow_HiOrd;
 
371
            }
 
372
            
 
373
            fullSize = (pScrn->currentMode->HDisplay == LCD[i].display_x) 
 
374
                && (pScrn->currentMode->VDisplay == LCD[i].display_y);
 
375
        }
 
376
        
 
377
        /* copy over common bits from normal VGA */
 
378
        
 
379
        pReg->tridentRegs3x4[0x7] &= ~0x4A;
 
380
        pReg->tridentRegs3x4[0x7] |= (vgaReg->CRTC[0x7] & 0x4A);
 
381
 
 
382
        if (LCDActive && fullSize) {    
 
383
            regp->CRTC[0] = pReg->tridentRegs3x4[0];
 
384
            regp->CRTC[3] = pReg->tridentRegs3x4[3];
 
385
            regp->CRTC[4] = pReg->tridentRegs3x4[4];
 
386
            regp->CRTC[5] = pReg->tridentRegs3x4[5];
 
387
            regp->CRTC[6] = pReg->tridentRegs3x4[6];
 
388
            regp->CRTC[7] = pReg->tridentRegs3x4[7];
 
389
            regp->CRTC[0x10] = pReg->tridentRegs3x4[0x10];
 
390
            regp->CRTC[0x11] = pReg->tridentRegs3x4[0x11];
 
391
            regp->CRTC[0x16] = pReg->tridentRegs3x4[0x16];
 
392
        }
 
393
        if (LCDActive && !fullSize) {
 
394
            /*
 
395
             * Set negative h/vsync polarity to center display nicely
 
396
             * Seems to work on several systems.
 
397
             */
 
398
            regp->MiscOutReg |= 0xC0;
 
399
          /* 
 
400
           * If the LCD is active and we don't fill the entire screen
 
401
           * and the previous mode was stretched we may need help from
 
402
           * the BIOS to set all registers for the unstreched mode.
 
403
           */
 
404
            pTrident->doInit =  ((pReg->tridentRegs3CE[HorStretch] & 1)
 
405
                                || (pReg->tridentRegs3CE[VertStretch] & 1));
 
406
            pReg->tridentRegs3CE[CyberControl] |= 0x81;
 
407
            xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow on\n");
 
408
            isShadow = TRUE;
 
409
        } else {
 
410
            pReg->tridentRegs3CE[CyberControl] &= 0x7E;
 
411
            xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Shadow off\n");
 
412
        }
 
413
        if (pTrident->FPDelay < 6) {
 
414
            pReg->tridentRegs3CE[CyberControl] &= 0xC7;
 
415
            pReg->tridentRegs3CE[CyberControl] |= (pTrident->FPDelay + 2) << 3;
 
416
        }
 
417
        
 
418
        if (pTrident->CyberShadow) {
 
419
            pReg->tridentRegs3CE[CyberControl] &= 0x7E;
 
420
            isShadow = FALSE;
 
421
            xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Forcing Shadow off\n");
 
422
        }
 
423
 
 
424
        xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing shadow registers:"
 
425
                       " 0x%2.2x           0x%2.2x 0x%2.2x 0x%2.2x\n",
 
426
                       pReg->tridentRegs3x4[0], pReg->tridentRegs3x4[3],
 
427
                       pReg->tridentRegs3x4[4], pReg->tridentRegs3x4[5]);
 
428
        xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"H-timing registers:       "
 
429
                       " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
 
430
                       regp->CRTC[0], regp->CRTC[1], regp->CRTC[2],
 
431
                       regp->CRTC[3], regp->CRTC[4], regp->CRTC[5]);
 
432
        xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing shadow registers: "
 
433
                       "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x"
 
434
                       "           0x%2.2x (0x%2.2x)\n",
 
435
                       pReg->tridentRegs3x4[6], pReg->tridentRegs3x4[7],
 
436
                       pReg->tridentRegs3x4[0x10],pReg->tridentRegs3x4[0x11],
 
437
                       pReg->tridentRegs3x4[0x16],
 
438
                       pReg->tridentRegs3x4[CRTHiOrd]);
 
439
        xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"V-timing registers:        "
 
440
                       "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
 
441
                       "0x%2.2x 0x%2.2x 0x%2.2x\n",
 
442
                       regp->CRTC[6], regp->CRTC[7], regp->CRTC[0x10],
 
443
                       regp->CRTC[0x11],regp->CRTC[0x12],
 
444
                       regp->CRTC[0x14],regp->CRTC[0x16]);
 
445
        
 
446
        
 
447
        /* disable stretching, enable centering */
 
448
        pReg->tridentRegs3CE[VertStretch] &= 0xFC;
 
449
        pReg->tridentRegs3CE[VertStretch] |= 0x80;
 
450
        pReg->tridentRegs3CE[HorStretch] &= 0xFC;
 
451
        pReg->tridentRegs3CE[HorStretch] |= 0x80;
 
452
#if 1
 
453
        {
 
454
            int mul = pScrn->bitsPerPixel >> 3; 
 
455
            int val;
 
456
            
 
457
            if (!mul) mul = 1;
 
458
            
 
459
            /* this is what my BIOS does */ 
 
460
            val = (pScrn->currentMode->HDisplay * mul / 8) + 16;
 
461
 
 
462
            pReg->tridentRegs3x4[PreEndControl] = ((val >> 8) < 2 ? 2 :0)
 
463
              | ((val >> 8) & 0x01);
 
464
            pReg->tridentRegs3x4[PreEndFetch] = val & 0xff;
 
465
        }
 
466
#else
 
467
        OUTB(vgaIOBase + 4,PreEndControl);
 
468
        pReg->tridentRegs3x4[PreEndControl] = INB(vgaIOBase + 5);
 
469
        OUTB(vgaIOBase + 4,PreEndFetch);
 
470
        pReg->tridentRegs3x4[PreEndFetch] = INB(vgaIOBase + 5);
 
471
#endif
 
472
        /* set mode */
 
473
        if (pTrident->Chipset < BLADEXP) {
 
474
          pReg->tridentRegs3CE[BiosMode] = TridentFindMode(
 
475
                                           pScrn->currentMode->HDisplay,
 
476
                                           pScrn->currentMode->VDisplay,
 
477
                                           pScrn->depth);
 
478
          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, 
 
479
                         "Setting BIOS Mode: %x\n",
 
480
                         pReg->tridentRegs3CE[BiosMode]);
 
481
        } else {
 
482
          TridentFindNewMode(pScrn->currentMode->HDisplay,
 
483
                             pScrn->currentMode->VDisplay,
 
484
                             &pReg->tridentRegs3CE[BiosNewMode1],
 
485
                             &pReg->tridentRegs3CE[BiosNewMode2]);
 
486
          xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, 
 
487
                         "Setting BIOS Mode Regs: %x %x\n",
 
488
                         pReg->tridentRegs3CE[BiosNewMode1],
 
489
                         pReg->tridentRegs3CE[BiosNewMode2]);
 
490
        };
 
491
        
 
492
        /* no stretch */
 
493
        if (pTrident->Chipset != CYBERBLADEXPAI1)
 
494
            pReg->tridentRegs3CE[BiosReg] = 0;
 
495
        else
 
496
            pReg->tridentRegs3CE[BiosReg] = 8;
 
497
 
 
498
        if (pTrident->CyberStretch) {
 
499
            pReg->tridentRegs3CE[VertStretch] |= 0x01;
 
500
            pReg->tridentRegs3CE[HorStretch] |= 0x01;
 
501
            xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"Enabling StretchMode\n");
 
502
        }
 
503
    }
 
504
 
 
505
    /* Enable Chipset specific options */
 
506
    switch (pTrident->Chipset) {
 
507
        case CYBERBLADEXPAI1:
 
508
        case BLADEXP:
 
509
        case CYBERBLADEI7:
 
510
        case CYBERBLADEI7D:
 
511
        case CYBERBLADEI1:
 
512
        case CYBERBLADEI1D:
 
513
        case CYBERBLADEAI1:
 
514
        case CYBERBLADEAI1D:
 
515
        case CYBERBLADEE4:
 
516
        case BLADE3D:
 
517
            OUTB(vgaIOBase + 4, RAMDACTiming);
 
518
            pReg->tridentRegs3x4[RAMDACTiming] = INB(vgaIOBase + 5) | 0x0F;
 
519
            /* Fall Through */
 
520
        case CYBER9520:
 
521
        case CYBER9525DVD:
 
522
        case CYBER9397DVD:
 
523
        case CYBER9397:
 
524
        case IMAGE975:
 
525
        case IMAGE985:
 
526
        case CYBER9388:
 
527
            if (pScrn->bitsPerPixel >= 8)
 
528
                pReg->tridentRegs3CE[MiscExtFunc] |= 0x10;
 
529
            else
 
530
                pReg->tridentRegs3CE[MiscExtFunc] &= ~0x10;
 
531
            if (!pReg->tridentRegs3x4[PreEndControl])
 
532
                pReg->tridentRegs3x4[PreEndControl] = 0x01;
 
533
            if (!pReg->tridentRegs3x4[PreEndFetch])
 
534
                pReg->tridentRegs3x4[PreEndFetch] = 0xFF;
 
535
            /* Fall Through */
 
536
        case PROVIDIA9685:
 
537
        case CYBER9385:
 
538
            pReg->tridentRegs3x4[Enhancement0] = 0x40;
 
539
            /* Fall Through */
 
540
        case PROVIDIA9682:
 
541
        case CYBER9382:
 
542
            if (pTrident->UsePCIRetry) 
 
543
                pReg->tridentRegs3x4[PCIRetry] = 0xDF;
 
544
            else
 
545
                pReg->tridentRegs3x4[PCIRetry] = 0x1F;
 
546
            /* Fall Through */
 
547
        case TGUI9660:
 
548
        case TGUI9680:
 
549
            if (pTrident->MUX && pScrn->bitsPerPixel == 8) {
 
550
                pReg->tridentRegs3x4[PixelBusReg] |= 0x01; /* 16bit bus */
 
551
                pReg->tridentRegs3C4[NewMode2] |= 0x02; /* half clock */
 
552
                pReg->tridentRegsDAC[0x00] |= 0x20;     /* mux mode */
 
553
            }   
 
554
    }
 
555
 
 
556
    /* Defaults for all trident chipsets follows */
 
557
    switch (pScrn->bitsPerPixel) {
 
558
        case 1:
 
559
        case 4:
 
560
            offset = pScrn->displayWidth >> 4;
 
561
            break;
 
562
        case 8:
 
563
            pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
 
564
            offset = pScrn->displayWidth >> 3;
 
565
            break;
 
566
        case 16:
 
567
            pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
 
568
            offset = pScrn->displayWidth >> 2;
 
569
            if (pScrn->depth == 15)
 
570
                pReg->tridentRegsDAC[0x00] = 0x10;
 
571
            else
 
572
                pReg->tridentRegsDAC[0x00] = 0x30;
 
573
            pReg->tridentRegs3x4[PixelBusReg] = 0x04;
 
574
            /* Reload with any chipset specific stuff here */
 
575
            if (pTrident->Chipset >= TGUI9660) 
 
576
                pReg->tridentRegs3x4[PixelBusReg] |= 0x01;
 
577
            if (pTrident->Chipset == TGUI9440AGi) {
 
578
                pReg->tridentRegs3CE[MiscExtFunc] |= 0x08;/*Clock Division / 2*/
 
579
                clock *= 2;     /* Double the clock */
 
580
            }
 
581
            break;
 
582
        case 24:
 
583
            pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
 
584
            offset = (pScrn->displayWidth * 3) >> 3;
 
585
            pReg->tridentRegs3x4[PixelBusReg] = 0x29;
 
586
            pReg->tridentRegsDAC[0x00] = 0xD0;
 
587
            if (pTrident->Chipset == CYBERBLADEE4) {
 
588
                OUTB(vgaIOBase+ 4, New32);
 
589
                pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) & 0x7F;
 
590
            }
 
591
            break;
 
592
        case 32:
 
593
            pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
 
594
            if (pTrident->Chipset != CYBERBLADEE4
 
595
                && pTrident->Chipset != CYBERBLADEXPAI1) {
 
596
                /* Clock Division by 2*/
 
597
                pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; 
 
598
                clock *= 2;     /* Double the clock */
 
599
            }
 
600
            offset = pScrn->displayWidth >> 1;
 
601
            pReg->tridentRegs3x4[PixelBusReg] = 0x09;
 
602
            pReg->tridentRegsDAC[0x00] = 0xD0;
 
603
            if (pTrident->Chipset == CYBERBLADEE4
 
604
                || pTrident->Chipset == CYBERBLADEXPAI1) {
 
605
                OUTB(vgaIOBase+ 4, New32);
 
606
                pReg->tridentRegs3x4[New32] = INB(vgaIOBase + 5) | 0x80;
 
607
                /* With new mode 32bpp we set the packed flag */
 
608
                pReg->tridentRegs3x4[PixelBusReg] |= 0x20; 
 
609
            }
 
610
            break;
 
611
    }
 
612
    pReg->tridentRegs3x4[Offset] = offset & 0xFF;
 
613
 
 
614
    {
 
615
        CARD8 a, b;
 
616
        TGUISetClock(pScrn, clock, &a, &b);
 
617
        pReg->tridentRegsClock[0x00] = (regp->MiscOutReg & 0xF3) | 0x08;
 
618
        pReg->tridentRegsClock[0x01] = a;
 
619
        pReg->tridentRegsClock[0x02] = b;
 
620
        if (pTrident->MCLK > 0) {
 
621
            TGUISetMCLK(pScrn, pTrident->MCLK, &a, &b);
 
622
            pReg->tridentRegsClock[0x03] = a;
 
623
            pReg->tridentRegsClock[0x04] = b;
 
624
        }
 
625
    }
 
626
 
 
627
    pReg->tridentRegs3C4[NewMode1] = 0xC0;
 
628
    pReg->tridentRegs3C4[Protection] = 0x92;
 
629
 
 
630
    pReg->tridentRegs3x4[LinearAddReg] = 0;
 
631
    if (pTrident->Linear) {
 
632
        /* This is used for VLB, when we support it again in 4.0 */
 
633
        if (pTrident->Chipset < CYBER9385)
 
634
            pReg->tridentRegs3x4[LinearAddReg] |=
 
635
                                        ((pTrident->FbAddress >> 24) << 6)|
 
636
                                        ((pTrident->FbAddress >> 20) & 0x0F);
 
637
        /* Turn on linear mapping */
 
638
        pReg->tridentRegs3x4[LinearAddReg] |= 0x20; 
 
639
    } else {
 
640
        pReg->tridentRegs3CE[MiscExtFunc] |= 0x04;
 
641
    }
 
642
    
 
643
    pReg->tridentRegs3x4[CRTCModuleTest] = 
 
644
                                (mode->Flags & V_INTERLACE ? 0x84 : 0x80);
 
645
 
 
646
    OUTB(vgaIOBase+ 4, InterfaceSel);
 
647
    pReg->tridentRegs3x4[InterfaceSel] = INB(vgaIOBase + 5) | 0x40;
 
648
 
 
649
    OUTB(vgaIOBase+ 4, Performance);
 
650
    pReg->tridentRegs3x4[Performance] = INB(vgaIOBase + 5);
 
651
    if (pTrident->Chipset < BLADEXP)
 
652
        pReg->tridentRegs3x4[Performance] |= 0x10;
 
653
 
 
654
    OUTB(vgaIOBase+ 4, DRAMControl);
 
655
    pReg->tridentRegs3x4[DRAMControl] = INB(vgaIOBase + 5) | 0x10;
 
656
 
 
657
    if (pTrident->IsCyber && !pTrident->MMIOonly)
 
658
        pReg->tridentRegs3x4[DRAMControl] |= 0x20;
 
659
 
 
660
    if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD) {
 
661
            OUTB(vgaIOBase + 4, ClockControl);
 
662
            pReg->tridentRegs3x4[ClockControl] = INB(vgaIOBase + 5) | 0x01;
 
663
    }
 
664
 
 
665
    OUTB(vgaIOBase+ 4, AddColReg);
 
666
    pReg->tridentRegs3x4[AddColReg] = INB(vgaIOBase + 5) & 0xEF;
 
667
    pReg->tridentRegs3x4[AddColReg] |= (offset & 0x100) >> 4;
 
668
 
 
669
    if (pTrident->Chipset >= TGUI9660) {
 
670
        pReg->tridentRegs3x4[AddColReg] &= 0xDF;
 
671
        pReg->tridentRegs3x4[AddColReg] |= (offset & 0x200) >> 4;
 
672
    }
 
673
   
 
674
    if (IsPciCard && UseMMIO) {
 
675
        if (!pTrident->NoAccel)
 
676
            pReg->tridentRegs3x4[GraphEngReg] |= 0x80; 
 
677
    } else {
 
678
        if (!pTrident->NoAccel)
 
679
            pReg->tridentRegs3x4[GraphEngReg] |= 0x82; 
 
680
    }
 
681
 
 
682
    OUTB(0x3CE, MiscIntContReg);
 
683
    pReg->tridentRegs3CE[MiscIntContReg] = INB(0x3CF) | 0x04;
 
684
 
 
685
    /* Fix hashing problem in > 8bpp on 9320 chipset */
 
686
    if (pTrident->Chipset == CYBER9320 && pScrn->bitsPerPixel > 8) 
 
687
        pReg->tridentRegs3CE[MiscIntContReg] &= ~0x80;
 
688
 
 
689
    OUTB(vgaIOBase+ 4, PCIReg);
 
690
    if (IsPciCard && UseMMIO)
 
691
        pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF9; 
 
692
    else
 
693
        pReg->tridentRegs3x4[PCIReg] = INB(vgaIOBase + 5) & 0xF8; 
 
694
 
 
695
    /* Enable PCI Bursting on capable chips */
 
696
    if (pTrident->Chipset >= TGUI9660) {
 
697
        if(pTrident->UsePCIBurst) {
 
698
            pReg->tridentRegs3x4[PCIReg] |= 0x06;
 
699
        } else {
 
700
            pReg->tridentRegs3x4[PCIReg] &= 0xF9;
 
701
        }
 
702
    }
 
703
 
 
704
    if (pTrident->Chipset >= CYBER9388) {
 
705
        if (pTrident->GammaBrightnessOn)
 
706
            xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,
 
707
                           "Setting Gamma: %f Brightness: %i\n",
 
708
                           pTrident->gamma, pTrident->brightness);
 
709
        tridentSetBrightnessAndGamma(pReg,
 
710
                                     pTrident->GammaBrightnessOn,
 
711
                                     pTrident->gamma, pTrident->brightness);
 
712
    }
 
713
    
 
714
    /* Video */
 
715
    OUTB(0x3C4,0x20);
 
716
    pReg->tridentRegs3C4[SSetup] = INB(0x3C5) | 0x4;
 
717
    pReg->tridentRegs3C4[SKey] = 0x00;
 
718
    pReg->tridentRegs3C4[SPKey] = 0xC0;
 
719
    OUTB(0x3C4,0x12);
 
720
    pReg->tridentRegs3C4[Threshold] = INB(0x3C5);
 
721
    if (pScrn->bitsPerPixel > 16)
 
722
        pReg->tridentRegs3C4[Threshold] =
 
723
            (pReg->tridentRegs3C4[Threshold] & 0xf0) | 0x2;
 
724
    
 
725
     /* restore */
 
726
    if (pTrident->Chipset > PROVIDIA9685) {
 
727
        OUTB(0x3C4, Protection);
 
728
        OUTB(0x3C5, protect);
 
729
    }
 
730
   
 
731
    return(TRUE);
 
732
}
 
733
 
 
734
void
 
735
TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
 
736
{
 
737
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
738
    CARD8 temp;
 
739
    int vgaIOBase;
 
740
    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
741
 
 
742
    if (pTrident->Chipset > PROVIDIA9685) {
 
743
        OUTB(0x3C4, Protection);
 
744
        OUTB(0x3C5, 0x92);
 
745
    }
 
746
#if 0
 
747
    if (pTrident->doInit && pTrident->Int10) {
 
748
        OUTW_3CE(BiosReg);      
 
749
    }
 
750
#endif
 
751
    /* Goto New Mode */
 
752
    OUTB(0x3C4, 0x0B);
 
753
    temp = INB(0x3C5);
 
754
 
 
755
    /* Unprotect registers */
 
756
    OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1);
 
757
    
 
758
    temp = INB(0x3C8);
 
759
    temp = INB(0x3C6);
 
760
    temp = INB(0x3C6);
 
761
    temp = INB(0x3C6);
 
762
    temp = INB(0x3C6);
 
763
    OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]);
 
764
    temp = INB(0x3C8);
 
765
 
 
766
    OUTW_3x4(CRTCModuleTest);
 
767
    OUTW_3x4(LinearAddReg);
 
768
    OUTW_3C4(NewMode2);
 
769
    OUTW_3x4(CursorControl);
 
770
    OUTW_3x4(CRTHiOrd);
 
771
    OUTW_3x4(HorizOverflow);
 
772
    OUTW_3x4(AddColReg);
 
773
    OUTW_3x4(GraphEngReg);
 
774
    OUTW_3x4(Performance);
 
775
    OUTW_3x4(InterfaceSel);
 
776
    OUTW_3x4(DRAMControl);
 
777
    OUTW_3x4(PixelBusReg);
 
778
    OUTW_3x4(PCIReg);
 
779
    OUTW_3x4(PCIRetry);
 
780
    OUTW_3CE(MiscIntContReg);
 
781
    OUTW_3CE(MiscExtFunc);
 
782
    OUTW_3x4(Offset);
 
783
    if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD)
 
784
        OUTW_3x4(ClockControl);
 
785
    if (pTrident->Chipset >= CYBER9388) {
 
786
        OUTW_3C4(Threshold);
 
787
        OUTW_3C4(SSetup);
 
788
        OUTW_3C4(SKey);
 
789
        OUTW_3C4(SPKey);
 
790
        OUTW_3x4(PreEndControl);
 
791
        OUTW_3x4(PreEndFetch);
 
792
        OUTW_3C4(GBslope1);
 
793
        OUTW_3C4(GBslope2);
 
794
        OUTW_3C4(GBslope3);
 
795
        OUTW_3C4(GBslope4);
 
796
        OUTW_3C4(GBintercept1);
 
797
        OUTW_3C4(GBintercept2);
 
798
        OUTW_3C4(GBintercept3);
 
799
        OUTW_3C4(GBintercept4);
 
800
    }
 
801
    if (pTrident->Chipset >= CYBER9385)    OUTW_3x4(Enhancement0);
 
802
    if (pTrident->Chipset >= BLADE3D)      OUTW_3x4(RAMDACTiming);
 
803
    if (pTrident->Chipset == CYBERBLADEE4) OUTW_3x4(New32);
 
804
    if (pTrident->IsCyber) {
 
805
        CARD8 tmp;
 
806
 
 
807
        OUTW_3CE(VertStretch);
 
808
        OUTW_3CE(HorStretch);
 
809
        if (pTrident->Chipset < BLADEXP) {
 
810
            OUTW_3CE(BiosMode);
 
811
        } else {
 
812
            OUTW_3CE(BiosNewMode1);
 
813
            OUTW_3CE(BiosNewMode2);
 
814
        };
 
815
        OUTW_3CE(BiosReg);
 
816
        OUTW_3CE(FPConfig);
 
817
        OUTW_3CE(CyberControl);
 
818
        OUTW_3CE(CyberEnhance);
 
819
        SHADOW_ENABLE(tmp);
 
820
        OUTW_3x4(0x0);
 
821
        if (pTrident->shadowNew) {
 
822
            OUTW_3x4(0x1);
 
823
            OUTW_3x4(0x2);          
 
824
        }
 
825
        OUTW_3x4(0x3);
 
826
        OUTW_3x4(0x4);
 
827
        OUTW_3x4(0x5);
 
828
        OUTW_3x4(0x6);
 
829
        OUTW_3x4(0x7);  
 
830
        OUTW_3x4(0x10);
 
831
        OUTW_3x4(0x11); 
 
832
        if (pTrident->shadowNew) {
 
833
            OUTW_3x4(0x12);
 
834
            OUTW_3x4(0x15);
 
835
        }
 
836
        OUTW_3x4(0x16);
 
837
        SHADOW_RESTORE(tmp);
 
838
    }
 
839
 
 
840
    if (Is3Dchip) {
 
841
#ifdef READOUT
 
842
        if (!pTrident->DontSetClock)
 
843
#endif
 
844
        {
 
845
            OUTW(0x3C4, (tridentReg->tridentRegsClock[0x01])<<8 | ClockLow);
 
846
            OUTW(0x3C4, (tridentReg->tridentRegsClock[0x02])<<8 | ClockHigh);
 
847
        }
 
848
        if (pTrident->MCLK > 0) {
 
849
            OUTW(0x3C4,(tridentReg->tridentRegsClock[0x03])<<8 | MCLKLow);
 
850
            OUTW(0x3C4,(tridentReg->tridentRegsClock[0x04])<<8 | MCLKHigh);
 
851
        }
 
852
    } else {
 
853
#ifdef READOUT
 
854
        if (!pTrident->DontSetClock)
 
855
#endif
 
856
        {
 
857
            OUTB(0x43C8, tridentReg->tridentRegsClock[0x01]);
 
858
            OUTB(0x43C9, tridentReg->tridentRegsClock[0x02]);
 
859
        }
 
860
        if (pTrident->MCLK > 0) {
 
861
            OUTB(0x43C6, tridentReg->tridentRegsClock[0x03]);
 
862
            OUTB(0x43C7, tridentReg->tridentRegsClock[0x04]);
 
863
        }
 
864
    }
 
865
#ifdef READOUT
 
866
    if (!pTrident->DontSetClock)
 
867
#endif
 
868
    {
 
869
        OUTB(0x3C2, tridentReg->tridentRegsClock[0x00]);
 
870
    }
 
871
    
 
872
    if (pTrident->Chipset > PROVIDIA9685) {
 
873
        OUTB(0x3C4, Protection);
 
874
        OUTB(0x3C5, tridentReg->tridentRegs3C4[Protection]);
 
875
    }
 
876
 
 
877
    OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1] ^ 0x02) << 8)| NewMode1);    
 
878
}
 
879
 
 
880
void
 
881
TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
 
882
{
 
883
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
884
    CARD8 temp;
 
885
    int vgaIOBase;
 
886
    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
887
 
 
888
    /* Goto New Mode */
 
889
    OUTB(0x3C4, 0x0B);
 
890
    temp = INB(0x3C5);
 
891
 
 
892
    INB_3C4(NewMode1);
 
893
    if (pTrident->Chipset > PROVIDIA9685)
 
894
        INB_3C4(Protection);
 
895
    
 
896
    /* Unprotect registers */
 
897
    OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1);
 
898
    if (pTrident->Chipset > PROVIDIA9685)
 
899
        OUTW(0x3C4, (0x92 << 8) | Protection);
 
900
 
 
901
    INB_3x4(Offset);
 
902
    INB_3x4(LinearAddReg);
 
903
    INB_3x4(CRTCModuleTest);
 
904
    INB_3x4(CRTHiOrd);
 
905
    INB_3x4(HorizOverflow);
 
906
    INB_3x4(Performance);
 
907
    INB_3x4(InterfaceSel);
 
908
    INB_3x4(DRAMControl);
 
909
    INB_3x4(AddColReg);
 
910
    INB_3x4(PixelBusReg);
 
911
    INB_3x4(GraphEngReg);
 
912
    INB_3x4(PCIReg);
 
913
    INB_3x4(PCIRetry);
 
914
    if (pTrident->NewClockCode && pTrident->Chipset <= CYBER9397DVD)
 
915
        INB_3x4(ClockControl);
 
916
    if (pTrident->Chipset >= CYBER9388) {
 
917
        INB_3C4(Threshold);
 
918
        INB_3C4(SSetup);
 
919
        INB_3C4(SKey);
 
920
        INB_3C4(SPKey);
 
921
        INB_3x4(PreEndControl);
 
922
        INB_3x4(PreEndFetch);
 
923
        INB_3C4(GBslope1);
 
924
        INB_3C4(GBslope2);
 
925
        INB_3C4(GBslope3);
 
926
        INB_3C4(GBslope4);
 
927
        INB_3C4(GBintercept1);
 
928
        INB_3C4(GBintercept2);
 
929
        INB_3C4(GBintercept3);
 
930
        INB_3C4(GBintercept4);
 
931
    }
 
932
    if (pTrident->Chipset >= CYBER9385)    INB_3x4(Enhancement0);
 
933
    if (pTrident->Chipset >= BLADE3D)      INB_3x4(RAMDACTiming);
 
934
    if (pTrident->Chipset == CYBERBLADEE4) INB_3x4(New32);
 
935
    if (pTrident->IsCyber) {
 
936
        CARD8 tmp;
 
937
        INB_3CE(VertStretch);
 
938
        INB_3CE(HorStretch);
 
939
        if (pTrident->Chipset < BLADEXP) {
 
940
            INB_3CE(BiosMode);
 
941
        } else {
 
942
        INB_3CE(BiosNewMode1);
 
943
        INB_3CE(BiosNewMode2);
 
944
        }
 
945
        INB_3CE(BiosReg);       
 
946
        INB_3CE(FPConfig);
 
947
        INB_3CE(CyberControl);
 
948
        INB_3CE(CyberEnhance);
 
949
        SHADOW_ENABLE(tmp);
 
950
        INB_3x4(0x0);
 
951
        if (pTrident->shadowNew) {
 
952
            INB_3x4(0x1);
 
953
            INB_3x4(0x2);           
 
954
        }
 
955
        INB_3x4(0x3);
 
956
        INB_3x4(0x4);
 
957
        INB_3x4(0x5);
 
958
        INB_3x4(0x6);
 
959
        INB_3x4(0x7);
 
960
        INB_3x4(0x10);
 
961
        INB_3x4(0x11);
 
962
        if (pTrident->shadowNew) {
 
963
            INB_3x4(0x12);
 
964
            INB_3x4(0x15);
 
965
        }
 
966
        INB_3x4(0x16);
 
967
        SHADOW_RESTORE(tmp);
 
968
    }
 
969
 
 
970
    /* save cursor registers */
 
971
    INB_3x4(CursorControl);
 
972
 
 
973
    INB_3CE(MiscExtFunc);
 
974
    INB_3CE(MiscIntContReg);
 
975
 
 
976
    temp = INB(0x3C8);
 
977
    temp = INB(0x3C6);
 
978
    temp = INB(0x3C6);
 
979
    temp = INB(0x3C6);
 
980
    temp = INB(0x3C6);
 
981
    tridentReg->tridentRegsDAC[0x00] = INB(0x3C6);
 
982
    temp = INB(0x3C8);
 
983
 
 
984
    tridentReg->tridentRegsClock[0x00] = INB(0x3CC);
 
985
    if (Is3Dchip) {
 
986
        OUTB(0x3C4, ClockLow);
 
987
        tridentReg->tridentRegsClock[0x01] = INB(0x3C5);
 
988
        OUTB(0x3C4, ClockHigh);
 
989
        tridentReg->tridentRegsClock[0x02] = INB(0x3C5);
 
990
        if (pTrident->MCLK > 0) {
 
991
            OUTB(0x3C4, MCLKLow);
 
992
            tridentReg->tridentRegsClock[0x03] = INB(0x3C5);
 
993
            OUTB(0x3C4, MCLKHigh);
 
994
            tridentReg->tridentRegsClock[0x04] = INB(0x3C5);
 
995
        }
 
996
    } else {
 
997
        tridentReg->tridentRegsClock[0x01] = INB(0x43C8);
 
998
        tridentReg->tridentRegsClock[0x02] = INB(0x43C9);
 
999
        if (pTrident->MCLK > 0) {
 
1000
            tridentReg->tridentRegsClock[0x03] = INB(0x43C6);
 
1001
            tridentReg->tridentRegsClock[0x04] = INB(0x43C7);
 
1002
        }
 
1003
    }
 
1004
 
 
1005
    INB_3C4(NewMode2);
 
1006
 
 
1007
    /* Protect registers */
 
1008
    OUTW_3C4(NewMode1);
 
1009
}
 
1010
 
 
1011
static void 
 
1012
TridentShowCursor(ScrnInfoPtr pScrn) 
 
1013
{
 
1014
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1015
    int vgaIOBase;
 
1016
    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
1017
 
 
1018
    /* 64x64 */
 
1019
    OUTW(vgaIOBase + 4, 0xC150);
 
1020
}
 
1021
 
 
1022
static void 
 
1023
TridentHideCursor(ScrnInfoPtr pScrn) {
 
1024
    int vgaIOBase;
 
1025
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1026
    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
1027
 
 
1028
    OUTW(vgaIOBase + 4, 0x4150);
 
1029
}
 
1030
 
 
1031
static void 
 
1032
TridentSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
 
1033
{
 
1034
    int vgaIOBase;
 
1035
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1036
    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
1037
    
 
1038
    if (x < 0) {
 
1039
        OUTW(vgaIOBase + 4, (-x)<<8 | 0x46);
 
1040
        x = 0;
 
1041
    } else
 
1042
        OUTW(vgaIOBase + 4, 0x0046);
 
1043
 
 
1044
    if (y < 0) {
 
1045
        OUTW(vgaIOBase + 4, (-y)<<8 | 0x47);
 
1046
        y = 0;
 
1047
    } else
 
1048
        OUTW(vgaIOBase + 4, 0x0047);
 
1049
 
 
1050
    OUTW(vgaIOBase + 4, (x&0xFF)<<8 | 0x40);
 
1051
    OUTW(vgaIOBase + 4, (x&0x0F00)  | 0x41);
 
1052
    OUTW(vgaIOBase + 4, (y&0xFF)<<8 | 0x42);
 
1053
    OUTW(vgaIOBase + 4, (y&0x0F00)  | 0x43);
 
1054
}
 
1055
 
 
1056
static void
 
1057
TridentSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
 
1058
{
 
1059
    int vgaIOBase;
 
1060
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1061
    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
1062
    OUTW(vgaIOBase + 4, (fg & 0x000000FF)<<8  | 0x48);
 
1063
    OUTW(vgaIOBase + 4, (fg & 0x0000FF00)     | 0x49);
 
1064
    OUTW(vgaIOBase + 4, (fg & 0x00FF0000)>>8  | 0x4A);
 
1065
    OUTW(vgaIOBase + 4, (fg & 0xFF000000)>>16 | 0x4B);
 
1066
    OUTW(vgaIOBase + 4, (bg & 0x000000FF)<<8  | 0x4C);
 
1067
    OUTW(vgaIOBase + 4, (bg & 0x0000FF00)     | 0x4D);
 
1068
    OUTW(vgaIOBase + 4, (bg & 0x00FF0000)>>8  | 0x4E);
 
1069
    OUTW(vgaIOBase + 4, (bg & 0xFF000000)>>16 | 0x4F);
 
1070
}
 
1071
 
 
1072
static void
 
1073
TridentLoadCursorImage(
 
1074
    ScrnInfoPtr pScrn, 
 
1075
    CARD8 *src
 
1076
)
 
1077
{
 
1078
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1079
    int vgaIOBase;
 
1080
    vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
1081
 
 
1082
    memcpy((CARD8 *)pTrident->FbBase + (pScrn->videoRam * 1024) - 4096,
 
1083
                        src, pTrident->CursorInfoRec->MaxWidth * 
 
1084
                        pTrident->CursorInfoRec->MaxHeight / 4);
 
1085
 
 
1086
    OUTW(vgaIOBase + 4, (((pScrn->videoRam-4) & 0xFF) << 8) | 0x44);
 
1087
    OUTW(vgaIOBase + 4, ((pScrn->videoRam-4) & 0xFF00) | 0x45);
 
1088
}
 
1089
 
 
1090
static Bool 
 
1091
TridentUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
 
1092
{
 
1093
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
1094
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1095
    
 
1096
    if (pTrident->MUX && pScrn->bitsPerPixel == 8) return FALSE;
 
1097
 
 
1098
    if (!pTrident->HWCursor) return FALSE;
 
1099
 
 
1100
    return TRUE;
 
1101
}
 
1102
 
 
1103
Bool 
 
1104
TridentHWCursorInit(ScreenPtr pScreen)
 
1105
{
 
1106
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
1107
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1108
    xf86CursorInfoPtr infoPtr;
 
1109
    int memory = pScrn->displayWidth * pScrn->virtualY * pScrn->bitsPerPixel/8;
 
1110
 
 
1111
    if (memory > (pScrn->videoRam * 1024 - 4096)) return FALSE;
 
1112
    infoPtr = xf86CreateCursorInfoRec();
 
1113
    if(!infoPtr) return FALSE;
 
1114
    
 
1115
    pTrident->CursorInfoRec = infoPtr;
 
1116
 
 
1117
    infoPtr->MaxWidth = 64;
 
1118
    infoPtr->MaxHeight = 64;
 
1119
    infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
 
1120
                HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
 
1121
                HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
 
1122
                ((pTrident->Chipset == CYBERBLADEE4) ? 
 
1123
                HARDWARE_CURSOR_TRUECOLOR_AT_8BPP : 0);
 
1124
    infoPtr->SetCursorColors = TridentSetCursorColors;
 
1125
    infoPtr->SetCursorPosition = TridentSetCursorPosition;
 
1126
    infoPtr->LoadCursorImage = TridentLoadCursorImage;
 
1127
    infoPtr->HideCursor = TridentHideCursor;
 
1128
    infoPtr->ShowCursor = TridentShowCursor;
 
1129
    infoPtr->UseHWCursor = TridentUseHWCursor;
 
1130
 
 
1131
    return(xf86InitCursor(pScreen, infoPtr));
 
1132
}
 
1133
 
 
1134
unsigned int
 
1135
Tridentddc1Read(ScrnInfoPtr pScrn)
 
1136
{
 
1137
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1138
    int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
 
1139
    CARD8 temp;
 
1140
 
 
1141
    /* New mode */
 
1142
    OUTB(0x3C4, 0x0B); temp = INB(0x3C5);
 
1143
 
 
1144
    OUTB(0x3C4, NewMode1);
 
1145
    temp = INB(0x3C5);
 
1146
    OUTB(0x3C5, temp | 0x80);
 
1147
 
 
1148
    /* Define SDA as input */
 
1149
    OUTW(vgaIOBase + 4, (0x04 << 8) | I2C);
 
1150
 
 
1151
    OUTW(0x3C4, (temp << 8) | NewMode1);
 
1152
 
 
1153
    /* Wait until vertical retrace is in progress. */
 
1154
    while (INB(vgaIOBase + 0xA) & 0x08);
 
1155
    while (!(INB(vgaIOBase + 0xA) & 0x08));
 
1156
 
 
1157
    /* Get the result */
 
1158
    OUTB(vgaIOBase + 4, I2C);
 
1159
    return ( INB(vgaIOBase + 5) & 0x01 );
 
1160
}
 
1161
 
 
1162
void TridentSetOverscan(
 
1163
    ScrnInfoPtr pScrn, 
 
1164
    int overscan
 
1165
){
 
1166
    vgaHWPtr hwp = VGAHWPTR(pScrn);
 
1167
 
 
1168
    if (overscan < 0 || overscan > 255)
 
1169
        return;
 
1170
 
 
1171
    hwp->enablePalette(hwp);
 
1172
    hwp->writeAttr(hwp, OVERSCAN, overscan);
 
1173
    hwp->disablePalette(hwp);
 
1174
}
 
1175
 
 
1176
void TridentLoadPalette(
 
1177
    ScrnInfoPtr pScrn, 
 
1178
    int numColors, 
 
1179
    int *indicies,
 
1180
    LOCO *colors,
 
1181
    VisualPtr pVisual
 
1182
){
 
1183
    vgaHWPtr hwp = VGAHWPTR(pScrn);
 
1184
    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
 
1185
    int i, index;
 
1186
    for(i = 0; i < numColors; i++) {
 
1187
        index = indicies[i];
 
1188
        OUTB(0x3C6, 0xFF);
 
1189
        DACDelay(hwp);
 
1190
        OUTB(0x3c8, index);
 
1191
        DACDelay(hwp);
 
1192
        OUTB(0x3c9, colors[index].red);
 
1193
        DACDelay(hwp);
 
1194
        OUTB(0x3c9, colors[index].green);
 
1195
        DACDelay(hwp);
 
1196
        OUTB(0x3c9, colors[index].blue);
 
1197
        DACDelay(hwp);
 
1198
    }
 
1199
}
 
1200