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

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2v_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 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk>
 
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
 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
 
23
 *           Dirk Hohndel,   <hohndel@suse.de>
 
24
 *           Stefan Dirsch,  <sndirsch@suse.de>
 
25
 *           Helmut Fahrion, <hf@suse.de>
 
26
 *
 
27
 * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
 
28
 * Siemens Nixdorf Informationssysteme
 
29
 */
 
30
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2v_dac.c,v 1.29 2002/05/07 23:15:59 alanh Exp $ */
 
31
 
 
32
#include "xf86.h"
 
33
#include "xf86_OSproc.h"
 
34
#include "xf86_ansic.h"
 
35
 
 
36
#include "xf86PciInfo.h"
 
37
#include "xf86Pci.h"
 
38
 
 
39
#include "glint_regs.h"
 
40
#include "glint.h"
 
41
 
 
42
static unsigned long
 
43
PM2VDAC_CalculateClock
 
44
(
 
45
 unsigned long reqclock,                /* In kHz units */
 
46
 unsigned long refclock,                /* In kHz units */
 
47
 unsigned char *prescale,               /* ClkPreScale */
 
48
 unsigned char *feedback,               /* ClkFeedBackScale */
 
49
 unsigned char *postscale               /* ClkPostScale */
 
50
 )
 
51
{
 
52
    int                 f, pre, post;
 
53
    unsigned long       freq;
 
54
    long                freqerr = 1000;
 
55
    unsigned long       actualclock = 0;
 
56
    unsigned char       divide[5] = { 1, 2, 4, 8, 16 };
 
57
 
 
58
    for (f=1;f<256;f++) {
 
59
        for (pre=1;pre<256;pre++) {
 
60
            for (post=0;post<2;post++) { 
 
61
                freq = ((refclock * f) / (pre * (1 << divide[post])));
 
62
                if ((reqclock > freq - freqerr)&&(reqclock < freq + freqerr)){
 
63
                    freqerr = (reqclock > freq) ? 
 
64
                                        reqclock - freq : freq - reqclock;
 
65
                    *feedback = f;
 
66
                    *prescale = pre;
 
67
                    *postscale = post;
 
68
                    actualclock = freq;
 
69
                }
 
70
            }
 
71
        }
 
72
    }
 
73
 
 
74
    return(actualclock);
 
75
}
 
76
 
 
77
static void
 
78
Permedia2VPreInitSecondary(ScrnInfoPtr pScrn)
 
79
{
 
80
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
81
 
 
82
    /* disable MCLK */
 
83
    Permedia2vOutIndReg(pScrn, PM2VDACRDMClkControl, 0x00, 0); 
 
84
 
 
85
    /* boot new mclk values */
 
86
    Permedia2vOutIndReg(pScrn, PM2VDACRDMClkPreScale, 0x00, 0x09);
 
87
    Permedia2vOutIndReg(pScrn, PM2VDACRDMClkFeedbackScale, 0x00, 0x58);
 
88
    Permedia2vOutIndReg(pScrn, PM2VDACRDMClkPostScale, 0x00, 0x01);
 
89
 
 
90
    /* re-enable MCLK */
 
91
    Permedia2vOutIndReg(pScrn, PM2VDACRDMClkControl, 0x00, 1); 
 
92
 
 
93
    /* spin until locked MCLK */
 
94
    while ( (Permedia2vInIndReg(pScrn, PM2VDACRDMClkControl) & 0x2) == 0);
 
95
 
 
96
    /* Now re-boot the SGRAM's */
 
97
    GLINT_SLOW_WRITE_REG(0xe6002021,PMMemConfig);
 
98
    GLINT_SLOW_WRITE_REG(0x00000020,PMBootAddress);
 
99
}
 
100
 
 
101
void
 
102
Permedia2VPreInit(ScrnInfoPtr pScrn)
 
103
{
 
104
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
105
 
 
106
    if (IS_JPRO) {
 
107
        /* Appian Jeronimo Pro 4x8mb (pm2v version) */
 
108
        /* BIOS doesn't initialize the secondary heads, so we need to */
 
109
 
 
110
        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 
111
            "Appian Jeronimo Pro 4x8mb board detected and initialized.\n");
 
112
 
 
113
        Permedia2VPreInitSecondary(pScrn);
 
114
    }
 
115
 
 
116
#if defined(__alpha__)
 
117
    /*
 
118
     * On Alpha, we have to init secondary PM2V cards, since
 
119
     * int10 cannot be run on the OEMed cards with VGA disable
 
120
     * jumpers.
 
121
     */
 
122
    if (!xf86IsPrimaryPci(pGlint->PciInfo)) {
 
123
        if ( IS_QPM2V ) {
 
124
 
 
125
            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 
126
                       "PM2V secondary: initializing\n");
 
127
            Permedia2VPreInitSecondary(pScrn);
 
128
        }
 
129
    }
 
130
#endif /* __alpha__ */
 
131
}
 
132
 
 
133
Bool
 
134
Permedia2VInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
 
135
{
 
136
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
137
    GLINTRegPtr pReg = &pGlint->ModeReg[0];
 
138
    CARD32 temp1, temp2, temp3, temp4;
 
139
 
 
140
    temp1 = 0;
 
141
    temp2 = 0;
 
142
#if X_BYTE_ORDER == X_BIG_ENDIAN
 
143
    switch (pGlint->HwBpp) {
 
144
    case 8:
 
145
    case 24:
 
146
            temp1 = 0x00;
 
147
            temp2 = 0x00;
 
148
            break;
 
149
 
 
150
    case 15:
 
151
    case 16:
 
152
            temp1 = 0x02;
 
153
            temp2 = 0x02;
 
154
            break;
 
155
 
 
156
    case 32:
 
157
            temp1 = 0x01;
 
158
            temp2 = 0x01;
 
159
            break;
 
160
    default:
 
161
            break;
 
162
    };
 
163
#endif /* BIG_ENDIAN */
 
164
 
 
165
    pReg->glintRegs[Aperture0 >> 3] = temp1;
 
166
    pReg->glintRegs[Aperture1 >> 3] = temp2;
 
167
 
 
168
    pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF;
 
169
    pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF;
 
170
 
 
171
    pReg->glintRegs[DFIFODis >> 3] = 0;
 
172
    pReg->glintRegs[FIFODis >> 3] = 1;
 
173
 
 
174
    if (pGlint->UseBlockWrite)
 
175
        pReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig) | 1<<21;
 
176
 
 
177
    temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
 
178
    temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
 
179
    temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
 
180
    temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
 
181
 
 
182
    pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal);
 
183
    pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3);
 
184
    pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1);
 
185
    pReg->glintRegs[PMHbEnd >> 3] = 
 
186
                        Shiftbpp(pScrn,mode->CrtcHTotal-mode->CrtcHDisplay);
 
187
    pReg->glintRegs[PMScreenStride >> 3] = 
 
188
                                        Shiftbpp(pScrn,pScrn->displayWidth>>1);
 
189
 
 
190
    pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal;
 
191
    pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4;
 
192
    pReg->glintRegs[PMVsStart >> 3] = temp2;
 
193
    pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay;
 
194
 
 
195
    /* The hw cursor needs /VSYNC to recognize vert retrace. We'll stick
 
196
       both sync lines to active low here and if needed invert them
 
197
       using the RAMDAC's RDSyncControl below. */
 
198
    pReg->glintRegs[PMVideoControl >> 3] =
 
199
        (1 << 5) | (1 << 3) | 1;
 
200
 
 
201
    /* We stick the RAMDAC into 64bit mode */
 
202
    /* And reduce the horizontal timings and clock by half */
 
203
    pReg->glintRegs[PMVideoControl >> 3] |= 1<<16;
 
204
    pReg->glintRegs[PMHTotal >> 3] >>= 1;
 
205
    pReg->glintRegs[PMHsEnd >> 3] >>= 1;
 
206
    pReg->glintRegs[PMHsStart >> 3] >>= 1;
 
207
    pReg->glintRegs[PMHbEnd >> 3] >>= 1;
 
208
 
 
209
    pReg->glintRegs[VClkCtl >> 3] = (GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC);
 
210
    pReg->glintRegs[PMScreenBase >> 3] = 0; 
 
211
    pReg->glintRegs[PMHTotal >> 3] -= 1; 
 
212
    pReg->glintRegs[PMHsStart >> 3] -= 1; /* PMHsStart */
 
213
    pReg->glintRegs[PMVTotal >> 3] -= 1; /* PMVTotal */
 
214
 
 
215
    pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFDD;
 
216
    pReg->DacRegs[PM2VDACRDDACControl] = 0x00;
 
217
  
 
218
    {
 
219
        /* Get the programmable clock values */
 
220
        unsigned char m,n,p;
 
221
        unsigned long clockused;
 
222
        
 
223
        clockused = PM2VDAC_CalculateClock(mode->Clock/2,pGlint->RefClock,
 
224
                                                                &m,&n,&p);
 
225
        pReg->DacRegs[PM2VDACRDDClk0PreScale] = m;
 
226
        pReg->DacRegs[PM2VDACRDDClk0FeedbackScale] = n;
 
227
        pReg->DacRegs[PM2VDACRDDClk0PostScale] = p;
 
228
    }
 
229
 
 
230
    pReg->glintRegs[PM2VDACRDIndexControl >> 3] = 0x00;
 
231
 
 
232
    if (pScrn->rgbBits == 8)
 
233
        pReg->DacRegs[PM2VDACRDMiscControl] = 0x01; /* 8bit DAC */
 
234
    else
 
235
        pReg->DacRegs[PM2VDACRDMiscControl] = 0x00; /* 6bit DAC */
 
236
 
 
237
    pReg->DacRegs[PM2VDACRDSyncControl] = 0x00;
 
238
    if (mode->Flags & V_PHSYNC)
 
239
        pReg->DacRegs[PM2VDACRDSyncControl] |= 0x01; /* invert hsync */
 
240
    if (mode->Flags & V_PVSYNC)
 
241
        pReg->DacRegs[PM2VDACRDSyncControl] |= 0x08; /* invert vsync */
 
242
 
 
243
    switch (pScrn->bitsPerPixel)
 
244
    {
 
245
    case 8:
 
246
        pReg->DacRegs[PM2VDACRDPixelSize] = 0x00;
 
247
        pReg->DacRegs[PM2VDACRDColorFormat] = 0x2E;
 
248
        break;
 
249
    case 16:
 
250
        pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; 
 
251
        pReg->DacRegs[PM2VDACRDPixelSize] = 0x01;
 
252
        if (pScrn->depth == 15)
 
253
            pReg->DacRegs[PM2VDACRDColorFormat] = 0x61;
 
254
        else
 
255
            pReg->DacRegs[PM2VDACRDColorFormat] = 0x70;
 
256
        break;
 
257
    case 24:
 
258
        pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; 
 
259
        pReg->DacRegs[PM2VDACRDPixelSize] = 0x04;
 
260
        pReg->DacRegs[PM2VDACRDColorFormat] = 0x60;
 
261
        break;
 
262
    case 32:
 
263
        pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; 
 
264
        pReg->DacRegs[PM2VDACRDPixelSize] = 0x02;
 
265
        pReg->DacRegs[PM2VDACRDColorFormat] = 0x20;
 
266
        if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
 
267
            pReg->DacRegs[PM2VDACRDMiscControl] |= 0x18;
 
268
            pReg->DacRegs[PM2VDACRDOverlayKey] = pScrn->colorKey;
 
269
        }
 
270
        break;
 
271
    }
 
272
 
 
273
    return(TRUE);
 
274
}
 
275
 
 
276
void
 
277
Permedia2VSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
 
278
{
 
279
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
280
    int i;
 
281
 
 
282
    /* We can't rely on the vgahw layer copying the font information
 
283
     * back properly, due to problems with MMIO access to VGA space
 
284
     * so we memcpy the information */
 
285
    memcpy((CARD8*)pGlint->VGAdata,(CARD8*)pGlint->FbBase, 65536); 
 
286
 
 
287
    glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig);
 
288
    glintReg->glintRegs[Aperture0 >> 3]  = GLINT_READ_REG(Aperture0);
 
289
    glintReg->glintRegs[Aperture1 >> 3]  = GLINT_READ_REG(Aperture1);
 
290
    glintReg->glintRegs[PMFramebufferWriteMask >> 3] = 
 
291
                                        GLINT_READ_REG(PMFramebufferWriteMask);
 
292
    glintReg->glintRegs[PMBypassWriteMask >> 3] = 
 
293
                                        GLINT_READ_REG(PMBypassWriteMask);
 
294
    glintReg->glintRegs[DFIFODis >> 3]  = GLINT_READ_REG(DFIFODis);
 
295
    glintReg->glintRegs[FIFODis >> 3]  = GLINT_READ_REG(FIFODis);
 
296
    /* We only muck about with PMMemConfig, if user wants to */
 
297
    if (pGlint->UseBlockWrite)
 
298
        glintReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig);
 
299
    glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal);
 
300
    glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd);
 
301
    glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHgEnd);
 
302
    glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride);
 
303
    glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart);
 
304
    glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd);
 
305
    glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal);
 
306
    glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd);
 
307
    glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart);
 
308
    glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd);
 
309
    glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase);
 
310
    glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl);
 
311
    glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl);
 
312
 
 
313
    for (i=0;i<768;i++) {
 
314
        Permedia2ReadAddress(pScrn, i);
 
315
        glintReg->cmap[i] = Permedia2ReadData(pScrn);
 
316
    }
 
317
 
 
318
    glintReg->glintRegs[PM2VDACRDIndexControl >> 3] = 
 
319
                                GLINT_READ_REG(PM2VDACRDIndexControl);
 
320
    glintReg->DacRegs[PM2VDACRDOverlayKey] = 
 
321
                                Permedia2vInIndReg(pScrn, PM2VDACRDOverlayKey);
 
322
    glintReg->DacRegs[PM2VDACRDSyncControl] = 
 
323
                                Permedia2vInIndReg(pScrn, PM2VDACRDSyncControl);
 
324
    glintReg->DacRegs[PM2VDACRDMiscControl] = 
 
325
                                Permedia2vInIndReg(pScrn, PM2VDACRDMiscControl);
 
326
    glintReg->DacRegs[PM2VDACRDDACControl] = 
 
327
                                Permedia2vInIndReg(pScrn, PM2VDACRDDACControl);
 
328
    glintReg->DacRegs[PM2VDACRDPixelSize] = 
 
329
                                Permedia2vInIndReg(pScrn, PM2VDACRDPixelSize);
 
330
    glintReg->DacRegs[PM2VDACRDColorFormat] = 
 
331
                                Permedia2vInIndReg(pScrn, PM2VDACRDColorFormat);
 
332
 
 
333
    glintReg->DacRegs[PM2VDACRDDClk0PreScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0PreScale);
 
334
    glintReg->DacRegs[PM2VDACRDDClk0FeedbackScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0FeedbackScale);
 
335
    glintReg->DacRegs[PM2VDACRDDClk0PostScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0PostScale);
 
336
}
 
337
 
 
338
void
 
339
Permedia2VRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
 
340
{
 
341
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
342
    CARD32 temp;
 
343
    int i;
 
344
 
 
345
    /* We can't rely on the vgahw layer copying the font information
 
346
     * back properly, due to problems with MMIO access to VGA space
 
347
     * so we memcpy the information */
 
348
    if (pGlint->STATE)
 
349
        memcpy((CARD8*)pGlint->FbBase,(CARD8*)pGlint->VGAdata, 65536); 
 
350
 
 
351
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig);
 
352
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0);
 
353
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1);
 
354
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3], 
 
355
                                                        PMFramebufferWriteMask);
 
356
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3], 
 
357
                                                        PMBypassWriteMask);
 
358
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis);
 
359
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis);
 
360
    /* We only muck about with PMMemConfig, if user wants to */
 
361
    if (pGlint->UseBlockWrite)
 
362
        GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMMemConfig >> 3],PMMemConfig);
 
363
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3], 
 
364
                                                                PMVideoControl);
 
365
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHgEnd);
 
366
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase);
 
367
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl);
 
368
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3], 
 
369
                                                                PMScreenStride);
 
370
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal);
 
371
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHbEnd);
 
372
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart);
 
373
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd);
 
374
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal);
 
375
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd);
 
376
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart);
 
377
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd);
 
378
 
 
379
    GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PM2VDACRDIndexControl >> 3],
 
380
                                PM2VDACRDIndexControl);
 
381
    Permedia2vOutIndReg(pScrn, PM2VDACRDOverlayKey, 0x00, 
 
382
                                glintReg->DacRegs[PM2VDACRDOverlayKey]);
 
383
    Permedia2vOutIndReg(pScrn, PM2VDACRDSyncControl, 0x00, 
 
384
                                glintReg->DacRegs[PM2VDACRDSyncControl]);
 
385
    Permedia2vOutIndReg(pScrn, PM2VDACRDMiscControl, 0x00, 
 
386
                                glintReg->DacRegs[PM2VDACRDMiscControl]);
 
387
    Permedia2vOutIndReg(pScrn, PM2VDACRDDACControl, 0x00, 
 
388
                                glintReg->DacRegs[PM2VDACRDDACControl]);
 
389
    Permedia2vOutIndReg(pScrn, PM2VDACRDPixelSize, 0x00, 
 
390
                                glintReg->DacRegs[PM2VDACRDPixelSize]);
 
391
    Permedia2vOutIndReg(pScrn, PM2VDACRDColorFormat, 0x00, 
 
392
                                glintReg->DacRegs[PM2VDACRDColorFormat]);
 
393
 
 
394
    for (i=0;i<768;i++) {
 
395
        Permedia2WriteAddress(pScrn, i);
 
396
        Permedia2WriteData(pScrn, glintReg->cmap[i]);
 
397
    }
 
398
 
 
399
    temp = Permedia2vInIndReg(pScrn, PM2VDACIndexClockControl) & 0xFC;
 
400
    Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0PreScale, 0x00, 
 
401
                                glintReg->DacRegs[PM2VDACRDDClk0PreScale]);
 
402
    Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0FeedbackScale, 0x00, 
 
403
                                glintReg->DacRegs[PM2VDACRDDClk0FeedbackScale]);
 
404
    Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0PostScale, 0x00, 
 
405
                                glintReg->DacRegs[PM2VDACRDDClk0PostScale]);
 
406
    Permedia2vOutIndReg(pScrn, PM2VDACIndexClockControl, 0x00, temp|0x03);
 
407
}
 
408
 
 
409
static void 
 
410
Permedia2vShowCursor(ScrnInfoPtr pScrn)
 
411
{
 
412
    /* Enable cursor - X11 mode */
 
413
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorMode, 0x00, 0x11);
 
414
}
 
415
 
 
416
static void Permedia2vLoadCursorCallback(ScrnInfoPtr pScrn);
 
417
 
 
418
static void
 
419
Permedia2vHideCursor(ScrnInfoPtr pScrn)
 
420
{
 
421
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
422
 
 
423
    /* Disable cursor - X11 mode */
 
424
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorMode, 0x00, 0x10);
 
425
 
 
426
    /*
 
427
     * For some reason, we need to clear the image as well as disable
 
428
     * the cursor on PM2V, but not on PM3. The problem is noticeable
 
429
     * only when running multi-head, as you can see the cursor get
 
430
     * "left behind" on the screen it is leaving...
 
431
     */
 
432
    if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) {
 
433
        memset(pGlint->HardwareCursorPattern, 0, 1024);
 
434
        pGlint->LoadCursorCallback = Permedia2vLoadCursorCallback;
 
435
    }
 
436
}
 
437
 
 
438
static void
 
439
Permedia2vLoadCursorCallback(
 
440
    ScrnInfoPtr pScrn
 
441
)
 
442
{
 
443
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
444
    int i;
 
445
 
 
446
    for (i=0; i<1024; i++) 
 
447
        Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPattern+i, 0x00, 
 
448
                                        pGlint->HardwareCursorPattern[i]);
 
449
 
 
450
    pGlint->LoadCursorCallback = NULL;
 
451
}
 
452
 
 
453
static void
 
454
Permedia2vLoadCursorImage(
 
455
    ScrnInfoPtr pScrn, 
 
456
    unsigned char *src
 
457
)
 
458
{
 
459
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
460
    int i;
 
461
       
 
462
    for (i=0; i<1024; i++) 
 
463
        pGlint->HardwareCursorPattern[i] = *(src++);
 
464
 
 
465
    pGlint->LoadCursorCallback = Permedia2vLoadCursorCallback;
 
466
}
 
467
 
 
468
static void
 
469
Permedia2vSetCursorPosition(
 
470
   ScrnInfoPtr pScrn, 
 
471
   int x, int y
 
472
)
 
473
{
 
474
    x += 64;
 
475
    y += 64;
 
476
    /* Output position - "only" 11 bits of location documented */
 
477
   
 
478
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorHotSpotX, 0x00, 0x3f);
 
479
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorHotSpotY, 0x00, 0x3f);
 
480
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorXLow, 0x00, x & 0xFF);
 
481
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorXHigh, 0x00, (x>>8) & 0x0F);
 
482
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorYLow, 0x00, y & 0xFF);
 
483
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorYHigh, 0x00, (y>>8) & 0x0F);
 
484
    Permedia2vOutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x00);
 
485
}
 
486
 
 
487
static void
 
488
Permedia2vCursorColorCallback(
 
489
   ScrnInfoPtr pScrn
 
490
)
 
491
{
 
492
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
493
    int fg = pGlint->FGCursor;
 
494
    int bg = pGlint->BGCursor;
 
495
 
 
496
    if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) ||
 
497
        ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
 
498
         (pGlint->MultiChip == PCI_CHIP_PERMEDIA3)) ) {
 
499
    /* PM3 uses last 2 indexes into hardware cursor palette fg first...*/
 
500
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+39, 0x00, (fg>>16)&0xff);
 
501
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+40, 0x00, (fg>>8)&0xff);
 
502
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+41, 0x00, fg & 0xff);
 
503
 
 
504
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+42, 0x00, (bg>>16)&0xff);
 
505
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+43, 0x00, (bg>>8)&0xff);
 
506
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+44, 0x00, bg & 0xff);
 
507
    } else {
 
508
    /* PM2v uses first 2 indexes into hardware cursor palette bg first...*/
 
509
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+0, 0x00, (bg>>16)&0xff);
 
510
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+1, 0x00, (bg>>8)&0xff);
 
511
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+2, 0x00, bg & 0xff);
 
512
 
 
513
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+3, 0x00, (fg>>16)&0xff);
 
514
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+4, 0x00, (fg>>8)&0xff);
 
515
    Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+5, 0x00, fg & 0xff);
 
516
    }
 
517
    pGlint->CursorColorCallback = NULL;
 
518
}
 
519
 
 
520
static void
 
521
Permedia2vSetCursorColors(
 
522
   ScrnInfoPtr pScrn, 
 
523
   int bg, int fg
 
524
)
 
525
{
 
526
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
527
 
 
528
    pGlint->FGCursor = fg;
 
529
    pGlint->BGCursor = bg;
 
530
 
 
531
    pGlint->CursorColorCallback = Permedia2vCursorColorCallback;
 
532
}
 
533
 
 
534
static Bool 
 
535
Permedia2vUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
 
536
{
 
537
    return TRUE;
 
538
}
 
539
 
 
540
Bool 
 
541
Permedia2vHWCursorInit(ScreenPtr pScreen)
 
542
{
 
543
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
544
    GLINTPtr pGlint = GLINTPTR(pScrn);
 
545
    xf86CursorInfoPtr infoPtr;
 
546
 
 
547
    infoPtr = xf86CreateCursorInfoRec();
 
548
    if(!infoPtr) return FALSE;
 
549
    
 
550
    pGlint->CursorInfoRec = infoPtr;
 
551
 
 
552
    infoPtr->MaxWidth = 64;
 
553
    infoPtr->MaxHeight = 64;
 
554
    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
 
555
#if X_BYTE_ORDER == X_BIG_ENDIAN
 
556
                HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
 
557
#endif
 
558
                HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
 
559
    infoPtr->SetCursorColors = Permedia2vSetCursorColors;
 
560
    infoPtr->SetCursorPosition = Permedia2vSetCursorPosition;
 
561
    infoPtr->LoadCursorImage = Permedia2vLoadCursorImage;
 
562
    infoPtr->HideCursor = Permedia2vHideCursor;
 
563
    infoPtr->ShowCursor = Permedia2vShowCursor;
 
564
    infoPtr->UseHWCursor = Permedia2vUseHWCursor;
 
565
 
 
566
    return(xf86InitCursor(pScreen, infoPtr));
 
567
}