~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/kdrive/trident/trident.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright ļæ½ 1999 Keith Packard
 
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 Keith Packard not be used in
 
9
 * advertising or publicity pertaining to distribution of the software without
 
10
 * specific, written prior permission.  Keith Packard makes no
 
11
 * representations about the suitability of this software for any purpose.  It
 
12
 * is provided "as is" without express or implied warranty.
 
13
 *
 
14
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
15
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
16
 * EVENT SHALL KEITH PACKARD 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
/* $RCSId: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.17 2001/06/03 18:48:19 keithp Exp $ */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#include <kdrive-config.h>
 
26
#endif
 
27
#include "trident.h"
 
28
#include <sys/io.h>
 
29
 
 
30
#undef TRI_DEBUG
 
31
 
 
32
int     trident_clk = 0;
 
33
int     trident_mclk = 0;
 
34
 
 
35
#define CLOCK 14318     /* KHz */
 
36
#define CLK_N(a,b)      (a & 0xff)
 
37
#define CLK_M(a,b)      ((b) & 0x3f)
 
38
#define CLK_K(a,b)      (((b) >> 6) & 3)
 
39
#define CLK_FREQ(a,b)   (((CLK_N(a,b) + 8) * CLOCK) / ((CLK_M(a,b)+2) << CLK_K(a,b)))
 
40
 
 
41
Bool
 
42
tridentCardInit (KdCardInfo *card)
 
43
{
 
44
    int                 k;
 
45
    char                *pixels;
 
46
    TridentCardInfo     *tridentc;
 
47
    CARD8               r39;
 
48
 
 
49
    tridentc = (TridentCardInfo *) xalloc (sizeof (TridentCardInfo));
 
50
    if (!tridentc)
 
51
        return FALSE;
 
52
    
 
53
    iopl (3);
 
54
    tridentc->cop_base = (CARD8 *) KdMapDevice (TRIDENT_COP_BASE(card),
 
55
                                                TRIDENT_COP_SIZE(card));
 
56
    
 
57
    if (tridentc->cop_base)
 
58
    {
 
59
        KdSetMappedMode (TRIDENT_COP_BASE(card),
 
60
                         TRIDENT_COP_SIZE(card),
 
61
                         KD_MAPPED_MODE_REGISTERS);
 
62
    }
 
63
    tridentc->cop = (Cop *) (tridentc->cop_base + TRIDENT_COP_OFF(card));
 
64
    tridentc->mmio = FALSE;
 
65
    r39 = tridentReadIndex (tridentc, 0x3d4, 0x39);
 
66
    if (r39 & 1)
 
67
    {
 
68
        tridentc->mmio = TRUE;
 
69
        r39 = tridentReadIndex (tridentc, 0x3d4, 0x39);
 
70
        if ((r39 & 1) == 0)
 
71
        {
 
72
            ErrorF ("Trident: inconsisent IO mapping values\n");
 
73
            return FALSE;
 
74
        }
 
75
    }
 
76
    
 
77
#ifdef VESA
 
78
    if (!vesaInitialize (card, &tridentc->vesa))
 
79
#else
 
80
    if (!fbdevInitialize (card, &tridentc->fb))
 
81
#endif
 
82
    {
 
83
        xfree (tridentc);
 
84
        return FALSE;
 
85
    }
 
86
    
 
87
#ifdef USE_PCI
 
88
    tridentc->window = (CARD32 *) (tridentc->cop_base + 0x10000);
 
89
#else
 
90
    tridentc->window = 0;
 
91
#endif
 
92
    card->driver = tridentc;
 
93
    
 
94
    return TRUE;
 
95
}
 
96
 
 
97
Bool
 
98
tridentScreenInit (KdScreenInfo *screen)
 
99
{
 
100
    TridentCardInfo     *tridentc = screen->card->driver;
 
101
    TridentScreenInfo   *tridents;
 
102
    int                 screen_size, memory;
 
103
 
 
104
    tridents = (TridentScreenInfo *) xalloc (sizeof (TridentScreenInfo));
 
105
    if (!tridents)
 
106
        return FALSE;
 
107
    memset (tridents, '\0', sizeof (TridentScreenInfo));
 
108
#ifdef VESA
 
109
    if (!vesaScreenInitialize (screen, &tridents->vesa))
 
110
#else
 
111
    if (!fbdevScreenInitialize (screen, &tridents->fbdev))
 
112
#endif
 
113
    {
 
114
        xfree (tridents);
 
115
        return FALSE;
 
116
    }
 
117
    if (!tridentc->cop)
 
118
        screen->dumb = TRUE;
 
119
#ifdef VESA
 
120
    if (tridents->vesa.mapping != VESA_LINEAR)
 
121
        screen->dumb = TRUE;
 
122
    tridents->screen = tridents->vesa.fb;
 
123
    memory = tridents->vesa.fb_size;
 
124
#else
 
125
    tridents->screen = tridentc->fb.fb;
 
126
    memory = (2048 + 512) * 1024;
 
127
#endif
 
128
    screen_size = screen->fb[0].byteStride * screen->height;
 
129
    if (tridents->screen && memory >= screen_size + 2048)
 
130
    {
 
131
        memory -= 2048;
 
132
        tridents->cursor_base = tridents->screen + memory - 2048;
 
133
    }
 
134
    else
 
135
        tridents->cursor_base = 0;
 
136
    memory -= screen_size;
 
137
    if (memory > screen->fb[0].byteStride)
 
138
    {
 
139
        tridents->off_screen = tridents->screen + screen_size;
 
140
        tridents->off_screen_size = memory;
 
141
    }
 
142
    else
 
143
    {
 
144
        tridents->off_screen = 0;
 
145
        tridents->off_screen_size = 0;
 
146
    }
 
147
    screen->driver = tridents;
 
148
    return TRUE;
 
149
}
 
150
 
 
151
Bool
 
152
tridentInitScreen (ScreenPtr pScreen)
 
153
{
 
154
#ifdef VESA
 
155
    return vesaInitScreen (pScreen);
 
156
#else
 
157
    return fbdevInitScreen (pScreen);
 
158
#endif
 
159
}
 
160
 
 
161
Bool
 
162
tridentFinishInitScreen (ScreenPtr pScreen)
 
163
{
 
164
#ifdef VESA
 
165
    return vesaFinishInitScreen (pScreen);
 
166
#endif
 
167
}
 
168
 
 
169
CARD8
 
170
tridentReadIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index)
 
171
{
 
172
    CARD8   value;
 
173
    
 
174
    if (tridentc->mmio)
 
175
    {
 
176
        tridentc->cop_base[port] = index;
 
177
        value = tridentc->cop_base[port+1];
 
178
    }
 
179
    else
 
180
    {
 
181
        outb (index, port);
 
182
        value = inb (port+1);
 
183
    }
 
184
    return value;
 
185
}
 
186
 
 
187
void
 
188
tridentWriteIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index, CARD8 value)
 
189
{
 
190
    if (tridentc->mmio)
 
191
    {
 
192
        tridentc->cop_base[port] = index;
 
193
        tridentc->cop_base[port+1] = value;
 
194
    }
 
195
    else
 
196
    {
 
197
        outb (index, port);
 
198
        outb (value, port+1);
 
199
    }
 
200
}
 
201
 
 
202
CARD8
 
203
tridentReadReg (TridentCardInfo *tridentc, CARD16 port)
 
204
{
 
205
    CARD8   value;
 
206
    
 
207
    if (tridentc->mmio)
 
208
    {
 
209
        value = tridentc->cop_base[port];
 
210
    }
 
211
    else
 
212
    {
 
213
        value = inb (port);
 
214
    }
 
215
    return value;
 
216
}
 
217
 
 
218
void
 
219
tridentWriteReg (TridentCardInfo *tridentc, CARD16 port, CARD8 value)
 
220
{
 
221
    if (tridentc->mmio)
 
222
    {
 
223
        tridentc->cop_base[port] = value;
 
224
    }
 
225
    else
 
226
    {
 
227
        outb (value, port);
 
228
    }
 
229
}
 
230
 
 
231
 
 
232
void
 
233
tridentPause ()
 
234
{
 
235
    struct timeval  tv;
 
236
 
 
237
    tv.tv_sec = 0;
 
238
    tv.tv_usec = 50 * 1000;
 
239
    select (1, 0, 0, 0, &tv);
 
240
}
 
241
 
 
242
void
 
243
tridentPreserve (KdCardInfo *card)
 
244
{
 
245
    TridentCardInfo     *tridentc = card->driver;
 
246
 
 
247
#ifdef VESA
 
248
    vesaPreserve(card);
 
249
#else
 
250
    fbdevPreserve (card);
 
251
#endif
 
252
    tridentPause ();
 
253
    tridentc->save.reg_3c4_0e = tridentReadIndex (tridentc, 0x3c4, 0x0e);
 
254
    tridentc->save.reg_3d4_36 = tridentReadIndex (tridentc, 0x3d4, 0x36);
 
255
    tridentc->save.reg_3d4_39 = tridentReadIndex (tridentc, 0x3d4, 0x39);
 
256
    tridentc->save.reg_3d4_62 = tridentReadIndex (tridentc, 0x3d4, 0x62);
 
257
    tridentc->save.reg_3ce_21 = tridentReadIndex (tridentc, 0x3ce, 0x21);
 
258
    tridentc->save.reg_3c2 = tridentReadReg (tridentc, 0x3cc);
 
259
    tridentc->save.reg_3c4_16 = tridentReadIndex (tridentc, 0x3c4, 0x16);
 
260
    tridentc->save.reg_3c4_17 = tridentReadIndex (tridentc, 0x3c4, 0x17);
 
261
    tridentc->save.reg_3c4_18 = tridentReadIndex (tridentc, 0x3c4, 0x18);
 
262
    tridentc->save.reg_3c4_19 = tridentReadIndex (tridentc, 0x3c4, 0x19);
 
263
    ErrorF ("clk low 0x%x high 0x%x freq %d\n",
 
264
            tridentc->save.reg_3c4_18,
 
265
            tridentc->save.reg_3c4_19,
 
266
            CLK_FREQ(tridentc->save.reg_3c4_18,
 
267
                     tridentc->save.reg_3c4_19));
 
268
#ifdef TRI_DEBUG
 
269
    fprintf (stderr, "3c4 0e: %02x\n", tridentc->save.reg_3c4_0e);
 
270
    fprintf (stderr, "3d4 36: %02x\n", tridentc->save.reg_3d4_36);
 
271
    fprintf (stderr, "3d4 39: %02x\n", tridentc->save.reg_3d4_39);
 
272
    fprintf (stderr, "3d4 62: %02x\n", tridentc->save.reg_3d4_62);
 
273
    fprintf (stderr, "3ce 21: %02x\n", tridentc->save.reg_3ce_21);
 
274
    fflush (stderr);
 
275
#endif
 
276
    tridentPause ();
 
277
}
 
278
 
 
279
void
 
280
tridentSetCLK(int clock, CARD8 *a, CARD8 *b)
 
281
{
 
282
    int powerup[4] = { 1,2,4,8 };
 
283
    int clock_diff = 750;
 
284
    int freq, ffreq;
 
285
    int m, n, k;
 
286
    int p, q, r, s; 
 
287
    int startn, endn;
 
288
    int endm, endk;
 
289
 
 
290
    p = q = r = s = 0;
 
291
 
 
292
    startn = 64;
 
293
    endn = 255;
 
294
    endm = 63;
 
295
    endk = 3;
 
296
 
 
297
    freq = clock;
 
298
 
 
299
    for (k=0;k<=endk;k++)
 
300
        for (n=startn;n<=endn;n++)
 
301
            for (m=1;m<=endm;m++)
 
302
            {
 
303
                ffreq = ( ( ((n + 8) * CLOCK) / ((m + 2) * powerup[k]) ));
 
304
                if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff)) 
 
305
                {
 
306
                    clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
 
307
                    p = n; q = m; r = k; s = ffreq;
 
308
                }
 
309
            }
 
310
 
 
311
    ErrorF ("ffreq %d clock %d\n", s, clock);
 
312
    if (s == 0)
 
313
    {
 
314
        FatalError("Unable to set programmable clock.\n"
 
315
                   "Frequency %d is not a valid clock.\n"
 
316
                   "Please modify XF86Config for a new clock.\n",       
 
317
                   freq);
 
318
    }
 
319
 
 
320
    /* N is all 8bits */
 
321
    *a = p;
 
322
    /* M is first 6bits, with K last 2bits */
 
323
    *b = (q & 0x3F) | (r << 6);
 
324
}
 
325
 
 
326
void
 
327
tridentSetMCLK(int clock, CARD8 *a, CARD8 *b)
 
328
{
 
329
    int powerup[4] = { 1,2,4,8 };
 
330
    int clock_diff = 750;
 
331
    int freq, ffreq;
 
332
    int m,n,k;
 
333
    int p, q, r, s; 
 
334
    int startn, endn;
 
335
    int endm, endk;
 
336
 
 
337
    p = q = r = s = 0;
 
338
 
 
339
    startn = 64;
 
340
    endn = 255;
 
341
    endm = 63;
 
342
    endk = 3;
 
343
 
 
344
    freq = clock;
 
345
 
 
346
    for (k=0;k<=endk;k++)
 
347
        for (n=startn;n<=endn;n++)
 
348
            for (m=1;m<=endm;m++) {
 
349
                ffreq = ((((n+8)*CLOCK)/((m+2)*powerup[k])));
 
350
                if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff)) 
 
351
                {
 
352
                    clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
 
353
                    p = n; q = m; r = k; s = ffreq;
 
354
                }
 
355
            }
 
356
 
 
357
    if (s == 0)
 
358
    {
 
359
        FatalError("Unable to set memory clock.\n"
 
360
                   "Frequency %d is not a valid clock.\n"
 
361
                   "Please modify XF86Config for a new clock.\n",       
 
362
                   freq);
 
363
    }
 
364
 
 
365
    /* N is all 8bits */
 
366
    *a = p;
 
367
    /* M is first 6bits, with K last 2bits */
 
368
    *b = (q & 0x3F) | (r << 6);
 
369
}
 
370
 
 
371
void
 
372
tridentSetMMIO (TridentCardInfo *tridentc)
 
373
{
 
374
    int tries;
 
375
    CARD8   v;
 
376
 
 
377
#ifdef TRI_DEBUG
 
378
    fprintf (stderr, "Set MMIO\n");
 
379
#endif
 
380
    /* enable config port writes */
 
381
    for (tries = 0; tries < 3; tries++)
 
382
    {
 
383
        /* enable direct read when GE busy, enable PCI retries */
 
384
        tridentWriteIndex (tridentc, 0x3d4, 0x62,
 
385
                           tridentc->save.reg_3d4_62 | 0x70);
 
386
        /* make sure the chip is in new mode */
 
387
        tridentReadIndex (tridentc, 0x3c4, 0xb);
 
388
        /* enable access to upper registers */
 
389
        tridentWriteIndex (tridentc, 0x3c4, 0xe, 
 
390
                           tridentc->save.reg_3c4_0e | 0x80);
 
391
        v = tridentReadIndex (tridentc, 0x3c4, 0xe);
 
392
        if (!(v & 0x80))
 
393
        {
 
394
            fprintf (stderr, "Trident GE not enabled 0x%x\n", v);
 
395
            continue;
 
396
        }
 
397
        /* enable screen */
 
398
        tridentWriteIndex (tridentc, 0x3ce, 0x21, 0x80);
 
399
#ifdef USE_PCI
 
400
        /* enable burst r/w, enable memory mapped ports */
 
401
        tridentWriteIndex (tridentc, 0x3d4, 0x39, 7);
 
402
        tridentc->mmio = TRUE;
 
403
        /* reset GE, enable GE, set GE to pci 1 */
 
404
        tridentWriteIndex (tridentc, 0x3d4, 0x36, 0x90);
 
405
#else
 
406
        /* enable burst r/w, disable memory mapped ports */
 
407
        tridentWriteIndex (tridentc, 0x3d4, 0x39, 0x6);
 
408
        /* reset GE, enable GE, set GE to 0xbff00 */
 
409
        tridentWriteIndex (tridentc, 0x3d4, 0x36, 0x92);
 
410
#endif
 
411
        /* set clock */
 
412
        if (trident_clk)
 
413
        {
 
414
            CARD8   a, b;
 
415
 
 
416
            a = tridentReadIndex (tridentc, 0x3c4, 0x18);
 
417
            b = tridentReadIndex (tridentc, 0x3c4, 0x19);
 
418
            ErrorF ("old clock 0x%x 0x%x %d\n", 
 
419
                    a, b, CLK_FREQ(a,b));
 
420
            tridentSetCLK (trident_clk, &a, &b);
 
421
            ErrorF ("clk %d-> 0x%x 0x%x %d\n", trident_clk, a, b,
 
422
                    CLK_FREQ(a,b));
 
423
#if 1
 
424
            tridentWriteIndex (tridentc, 0x3c4, 0x18, a);
 
425
            tridentWriteIndex (tridentc, 0x3c4, 0x19, b);
 
426
#endif
 
427
        }
 
428
        if (trident_mclk)
 
429
        {
 
430
            CARD8   a, b;
 
431
 
 
432
            tridentSetMCLK (trident_mclk, &a, &b);
 
433
            ErrorF ("mclk %d -> 0x%x 0x%x\n", trident_mclk, a, b);
 
434
#if 0
 
435
            tridentWriteIndex (tridentc, 0x3c4, 0x16, a);
 
436
            tridentWriteIndex (tridentc, 0x3c4, 0x17, b);
 
437
#endif
 
438
        }
 
439
        if (trident_clk || trident_mclk)
 
440
        {
 
441
            CARD8   mode;
 
442
 
 
443
            mode = tridentReadReg (tridentc, 0x3cc);
 
444
            ErrorF ("old mode 0x%x\n", mode);
 
445
            mode = (mode & 0xf3) | 0x08;
 
446
            ErrorF ("new mode 0x%x\n", mode);
 
447
#if 1
 
448
            tridentWriteReg (tridentc, 0x3c2, mode);
 
449
#endif
 
450
        }
 
451
#ifdef TRI_DEBUG
 
452
        fprintf (stderr, "0x36: 0x%02x\n",
 
453
                 tridentReadIndex (tridentc, 0x3d4, 0x36));
 
454
#endif
 
455
        if (tridentc->cop->status != 0xffffffff)
 
456
            break;
 
457
    }
 
458
#ifdef TRI_DEBUG
 
459
    fprintf (stderr, "COP status 0x%x\n", tridentc->cop->status);
 
460
#endif
 
461
    if (tridentc->cop->status == 0xffffffff)
 
462
        FatalError ("Trident COP not visible\n");
 
463
}
 
464
 
 
465
void
 
466
tridentResetMMIO (TridentCardInfo *tridentc)
 
467
{
 
468
#ifdef TRI_DEBUG
 
469
    fprintf (stderr, "Reset MMIO\n");
 
470
#endif
 
471
    tridentPause ();
 
472
#if 0
 
473
    tridentWriteIndex (tridentc, 0x3c4, 0x16, tridentc->save.reg_3c4_16);
 
474
    tridentWriteIndex (tridentc, 0x3c4, 0x17, tridentc->save.reg_3c4_17);
 
475
#endif
 
476
    tridentWriteIndex (tridentc, 0x3c4, 0x18, tridentc->save.reg_3c4_18);
 
477
    tridentWriteIndex (tridentc, 0x3c4, 0x19, tridentc->save.reg_3c4_19);
 
478
    tridentWriteReg (tridentc, 0x3c2, tridentc->save.reg_3c2);
 
479
    tridentPause ();
 
480
    tridentWriteIndex (tridentc, 0x3ce, 0x21, tridentc->save.reg_3ce_21);
 
481
    tridentPause ();
 
482
    tridentWriteIndex (tridentc, 0x3d4, 0x62, tridentc->save.reg_3d4_62);
 
483
    tridentWriteIndex (tridentc, 0x3d4, 0x39, tridentc->save.reg_3d4_39);
 
484
    tridentc->mmio = FALSE;
 
485
    tridentWriteIndex (tridentc, 0x3d4, 0x36, tridentc->save.reg_3d4_36);
 
486
    tridentWriteIndex (tridentc, 0x3c4, 0x0e, tridentc->save.reg_3c4_0e);
 
487
    tridentPause ();
 
488
}
 
489
 
 
490
Bool
 
491
tridentEnable (ScreenPtr pScreen)
 
492
{
 
493
    KdScreenPriv(pScreen);
 
494
    TridentCardInfo     *tridentc = pScreenPriv->card->driver;
 
495
 
 
496
#ifdef VESA
 
497
    if (!vesaEnable (pScreen))
 
498
        return FALSE;
 
499
#else
 
500
    if (!fbdevEnable (pScreen))
 
501
        return FALSE;
 
502
#endif
 
503
    tridentSetMMIO (tridentc);
 
504
    return TRUE;
 
505
}
 
506
 
 
507
void
 
508
tridentDisable (ScreenPtr pScreen)
 
509
{
 
510
#ifdef VESA
 
511
    vesaDisable (pScreen);
 
512
#else
 
513
    fbdevDisable (pScreen);
 
514
#endif
 
515
}
 
516
 
 
517
const CARD8     tridentDPMSModes[4] = {
 
518
    0x80,           /* KD_DPMS_NORMAL */
 
519
    0x8c,           /* KD_DPMS_STANDBY */
 
520
    0x8c,           /* KD_DPMS_STANDBY */
 
521
    0x8c,           /* KD_DPMS_STANDBY */
 
522
/*    0xb0,         /* KD_DPMS_SUSPEND */
 
523
/*    0xbc,         /* KD_DPMS_POWERDOWN */
 
524
};
 
525
 
 
526
Bool
 
527
tridentDPMS (ScreenPtr pScreen, int mode)
 
528
{
 
529
    KdScreenPriv(pScreen);
 
530
    TridentCardInfo     *tridentc = pScreenPriv->card->driver;
 
531
 
 
532
    tridentWriteIndex (tridentc, 0x3ce, 0x21, tridentDPMSModes[mode]);
 
533
    tridentPause ();
 
534
    return TRUE;
 
535
}
 
536
 
 
537
void
 
538
tridentRestore (KdCardInfo *card)
 
539
{
 
540
    TridentCardInfo     *tridentc = card->driver;
 
541
 
 
542
    tridentResetMMIO (tridentc);
 
543
#ifdef VESA
 
544
    vesaRestore (card);
 
545
#else
 
546
    fbdevRestore (card);
 
547
#endif
 
548
}
 
549
 
 
550
void
 
551
tridentScreenFini (KdScreenInfo *screen)
 
552
{
 
553
    TridentScreenInfo   *tridents = (TridentScreenInfo *) screen->driver;
 
554
 
 
555
#ifdef VESA
 
556
    vesaScreenFini (screen);
 
557
#endif
 
558
    xfree (tridents);
 
559
    screen->driver = 0;
 
560
}
 
561
 
 
562
void
 
563
tridentCardFini (KdCardInfo *card)
 
564
{
 
565
    TridentCardInfo     *tridentc = card->driver;
 
566
 
 
567
    if (tridentc->cop_base)
 
568
    {
 
569
        KdUnmapDevice ((void *) tridentc->cop_base, TRIDENT_COP_SIZE(card));
 
570
        KdResetMappedMode (TRIDENT_COP_BASE(card),
 
571
                           TRIDENT_COP_SIZE(card),
 
572
                           KD_MAPPED_MODE_REGISTERS);
 
573
    }
 
574
#ifdef VESA
 
575
    vesaCardFini (card);
 
576
#else
 
577
    fbdevCardFini (card);
 
578
#endif
 
579
}
 
580
 
 
581
KdCardFuncs     tridentFuncs = {
 
582
    tridentCardInit,        /* cardinit */
 
583
    tridentScreenInit,      /* scrinit */
 
584
    tridentInitScreen,      /* initScreen */
 
585
    tridentPreserve,        /* preserve */
 
586
    tridentEnable,          /* enable */
 
587
    tridentDPMS,            /* dpms */
 
588
    tridentDisable,         /* disable */
 
589
    tridentRestore,         /* restore */
 
590
    tridentScreenFini,      /* scrfini */
 
591
    tridentCardFini,        /* cardfini */
 
592
    
 
593
    tridentCursorInit,      /* initCursor */
 
594
    tridentCursorEnable,    /* enableCursor */
 
595
    tridentCursorDisable,   /* disableCursor */
 
596
    tridentCursorFini,      /* finiCursor */
 
597
    tridentRecolorCursor,   /* recolorCursor */
 
598
    
 
599
    tridentDrawInit,        /* initAccel */
 
600
    tridentDrawEnable,      /* enableAccel */
 
601
    tridentDrawSync,        /* syncAccel */
 
602
    tridentDrawDisable,     /* disableAccel */
 
603
    tridentDrawFini,        /* finiAccel */
 
604
    
 
605
#ifdef VESA
 
606
    vesaGetColors,          /* getColors */
 
607
    vesaPutColors,          /* putColors */
 
608
#else
 
609
    fbdevGetColors,         /* getColors */
 
610
    fbdevPutColors,         /* putColors */
 
611
#endif
 
612
    tridentFinishInitScreen /* finishInitScreen */
 
613
};