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

« back to all changes in this revision

Viewing changes to hw/xfree86/ramdac/TI.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 1998 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
 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
 
23
 *
 
24
 * Modified from IBM.c to support TI RAMDAC routines 
 
25
 *   by Jens Owen, <jens@tungstengraphics.com>.
 
26
 */
 
27
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/TI.c,v 1.7 2003/02/17 16:08:29 dawes Exp $ */
 
28
 
 
29
#ifdef HAVE_XORG_CONFIG_H
 
30
#include <xorg-config.h>
 
31
#endif
 
32
 
 
33
#include "xf86.h"
 
34
#include "xf86_OSproc.h"
 
35
#include "xf86_ansic.h"
 
36
 
 
37
#include "xf86Cursor.h"
 
38
 
 
39
#define INIT_TI_RAMDAC_INFO
 
40
#include "TIPriv.h"
 
41
#include "xf86RamDacPriv.h"
 
42
 
 
43
/* The following values are in kHz */
 
44
#define TI_MIN_VCO_FREQ  110000
 
45
#define TI_MAX_VCO_FREQ  220000
 
46
 
 
47
unsigned long
 
48
TIramdacCalculateMNPForClock(
 
49
    unsigned long RefClock,     /* In 100Hz units */
 
50
    unsigned long ReqClock,     /* In 100Hz units */
 
51
    char IsPixClock,    /* boolean, is this the pixel or the sys clock */
 
52
    unsigned long MinClock,     /* Min VCO rating */
 
53
    unsigned long MaxClock,     /* Max VCO rating */
 
54
    unsigned long *rM,  /* M Out */
 
55
    unsigned long *rN,  /* N Out */
 
56
    unsigned long *rP   /* Min P In, P Out */
 
57
)
 
58
{
 
59
    unsigned long   n, p;
 
60
    unsigned long   best_m = 0, best_n = 0;
 
61
    double          VCO, IntRef = (double)RefClock;
 
62
    double          m_err, inc_m, calc_m;
 
63
    unsigned long   ActualClock;
 
64
 
 
65
    /* Make sure that MinClock <= ReqClock <= MaxClock */
 
66
    if ( ReqClock < MinClock)
 
67
        ReqClock = MinClock;
 
68
    if ( ReqClock > MaxClock )
 
69
        ReqClock = MaxClock;
 
70
 
 
71
    /*
 
72
     * ActualClock = VCO / 2 ^ p
 
73
     * Choose p so that TI_MIN_VCO_FREQ <= VCO <= TI_MAX_VCO_FREQ
 
74
     * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ
 
75
     * we don't have to bother checking for this maximum limit.
 
76
     */
 
77
    VCO = (double)ReqClock;
 
78
    for ( p = 0; p < 3 && VCO < TI_MIN_VCO_FREQ; ( p )++ )
 
79
         VCO *= 2.0;
 
80
 
 
81
    /*
 
82
     * We avoid doing multiplications by ( 65 - n ),
 
83
     * and add an increment instead - this keeps any error small.
 
84
     */
 
85
    inc_m = VCO / ( IntRef * 8.0 );
 
86
 
 
87
    /* Initial value of calc_m for the loop */
 
88
    calc_m = inc_m + inc_m + inc_m;
 
89
 
 
90
    /* Initial amount of error for an integer - impossibly large */
 
91
    m_err = 2.0;
 
92
 
 
93
    /* Search for the closest INTEGER value of ( 65 - m ) */
 
94
    for ( n = 3; n <= 25; ( n )++, calc_m += inc_m ) {
 
95
 
 
96
        /* Ignore values of ( 65 - m ) which we can't use */
 
97
        if ( calc_m < 3.0 || calc_m > 64.0 )
 
98
            continue;
 
99
 
 
100
        /*
 
101
         * Pick the closest INTEGER (has smallest fractional part).
 
102
         * The optimizer should clean this up for us.
 
103
         */
 
104
        if (( calc_m - ( int ) calc_m ) < m_err ) {
 
105
            m_err = calc_m - ( int ) calc_m;
 
106
            best_m = ( int ) calc_m;
 
107
            best_n = n;
 
108
        }
 
109
    }
 
110
 
 
111
    /* 65 - ( 65 - x ) = x */
 
112
    *rM = 65 - best_m;
 
113
    *rN = 65 - best_n;
 
114
    *rP = p;
 
115
 
 
116
    /* Now all the calculations can be completed */
 
117
    VCO = 8.0 * IntRef * best_m / best_n;
 
118
    ActualClock = VCO / ( 1 << p );
 
119
 
 
120
#ifdef DEBUG
 
121
    ErrorF( "f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n",
 
122
            ActualClock, VCO, *rN, *rM, *rP);
 
123
#endif
 
124
 
 
125
    return (ActualClock);
 
126
}
 
127
 
 
128
void
 
129
TIramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
 
130
                                   RamDacRegRecPtr ramdacReg)
 
131
{
 
132
    int i;
 
133
    unsigned long status;
 
134
 
 
135
    /* Here we pass a short, so that we can evaluate a mask too
 
136
     * So that the mask is the high byte and the data the low byte
 
137
     * Order is important
 
138
     */
 
139
    TIRESTORE(TIDAC_latch_ctrl);
 
140
    TIRESTORE(TIDAC_true_color_ctrl);
 
141
    TIRESTORE(TIDAC_multiplex_ctrl);
 
142
    TIRESTORE(TIDAC_clock_select);
 
143
    TIRESTORE(TIDAC_palette_page);
 
144
    TIRESTORE(TIDAC_general_ctrl);
 
145
    TIRESTORE(TIDAC_misc_ctrl);
 
146
            /* 0x2A & 0x2B are reserved */
 
147
    TIRESTORE(TIDAC_key_over_low);
 
148
    TIRESTORE(TIDAC_key_over_high);
 
149
    TIRESTORE(TIDAC_key_red_low);
 
150
    TIRESTORE(TIDAC_key_red_high);
 
151
    TIRESTORE(TIDAC_key_green_low);
 
152
    TIRESTORE(TIDAC_key_green_high);
 
153
    TIRESTORE(TIDAC_key_blue_low);
 
154
    TIRESTORE(TIDAC_key_blue_high);
 
155
    TIRESTORE(TIDAC_key_ctrl);
 
156
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x30);
 
157
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x38);
 
158
    TIRESTORE(TIDAC_clock_ctrl);
 
159
    TIRESTORE(TIDAC_sense_test);
 
160
    TIRESTORE(TIDAC_ind_curs_ctrl);
 
161
 
 
162
    /* only restore clocks if they were valid to begin with */
 
163
 
 
164
    if (ramdacReg->DacRegs[TIDAC_PIXEL_VALID]) {
 
165
    /* Reset pixel clock */
 
166
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
 
167
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0, 0x3c);
 
168
 
 
169
    /* Restore N, M & P values for pixel clocks */
 
170
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
 
171
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
 
172
                                        ramdacReg->DacRegs[TIDAC_PIXEL_N]);
 
173
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
 
174
                                        ramdacReg->DacRegs[TIDAC_PIXEL_M]);
 
175
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
 
176
                                        ramdacReg->DacRegs[TIDAC_PIXEL_P]);
 
177
 
 
178
    /* wait for pixel clock to lock */
 
179
    i = 1000000;
 
180
    do {
 
181
        status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
 
182
    } while ((!(status & 0x40)) && (--i));
 
183
    if (!(status & 0x40)) {
 
184
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
 
185
                        "Pixel clock setup timed out\n");
 
186
        return;
 
187
    }
 
188
    }
 
189
 
 
190
    if (ramdacReg->DacRegs[TIDAC_LOOP_VALID]) {
 
191
    /* Reset loop clock */
 
192
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
 
193
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0, 0x70);
 
194
 
 
195
    /* Restore N, M & P values for pixel clocks */
 
196
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
 
197
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
 
198
                                        ramdacReg->DacRegs[TIDAC_LOOP_N]);
 
199
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
 
200
                                        ramdacReg->DacRegs[TIDAC_LOOP_M]);
 
201
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
 
202
                                        ramdacReg->DacRegs[TIDAC_LOOP_P]);
 
203
 
 
204
    /* wait for loop clock to lock */
 
205
    i = 1000000;
 
206
    do {
 
207
        status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
 
208
    } while ((!(status & 0x40)) && (--i));
 
209
    if (!(status & 0x40)) {
 
210
            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 
 
211
                        "Loop clock setup timed out\n");
 
212
            return;
 
213
    }
 
214
    }
 
215
 
 
216
    /* restore palette */
 
217
    (*ramdacPtr->WriteAddress)(pScrn, 0);
 
218
#ifndef NOT_DONE
 
219
    for (i=0;i<768;i++)
 
220
        (*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]);
 
221
#else
 
222
        (*ramdacPtr->WriteData)(pScrn, 0);
 
223
        (*ramdacPtr->WriteData)(pScrn, 0);
 
224
        (*ramdacPtr->WriteData)(pScrn, 0);
 
225
    for (i=0;i<765;i++)
 
226
        (*ramdacPtr->WriteData)(pScrn, 0xff);
 
227
#endif
 
228
}
 
229
 
 
230
void
 
231
TIramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 
 
232
                                RamDacRegRecPtr ramdacReg)
 
233
{
 
234
    int i;
 
235
 
 
236
    (*ramdacPtr->ReadAddress)(pScrn, 0);
 
237
    for (i=0;i<768;i++)
 
238
        ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn);
 
239
 
 
240
    /* Read back N,M and P values for pixel clock */
 
241
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
 
242
    ramdacReg->DacRegs[TIDAC_PIXEL_N] = 
 
243
                        (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
 
244
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11);
 
245
    ramdacReg->DacRegs[TIDAC_PIXEL_M] = 
 
246
                        (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
 
247
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
 
248
    ramdacReg->DacRegs[TIDAC_PIXEL_P] = 
 
249
                    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
 
250
 
 
251
    /* Read back N,M and P values for loop clock */
 
252
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
 
253
    ramdacReg->DacRegs[TIDAC_LOOP_N] = 
 
254
                    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
 
255
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11);
 
256
    ramdacReg->DacRegs[TIDAC_LOOP_M] = 
 
257
                    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
 
258
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
 
259
    ramdacReg->DacRegs[TIDAC_LOOP_P] = 
 
260
                    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
 
261
 
 
262
    /* Order is important */
 
263
    TISAVE(TIDAC_latch_ctrl);
 
264
    TISAVE(TIDAC_true_color_ctrl);
 
265
    TISAVE(TIDAC_multiplex_ctrl);
 
266
    TISAVE(TIDAC_clock_select);
 
267
    TISAVE(TIDAC_palette_page);
 
268
    TISAVE(TIDAC_general_ctrl);
 
269
    TISAVE(TIDAC_misc_ctrl);
 
270
            /* 0x2A & 0x2B are reserved */
 
271
    TISAVE(TIDAC_key_over_low);
 
272
    TISAVE(TIDAC_key_over_high);
 
273
    TISAVE(TIDAC_key_red_low);
 
274
    TISAVE(TIDAC_key_red_high);
 
275
    TISAVE(TIDAC_key_green_low);
 
276
    TISAVE(TIDAC_key_green_high);
 
277
    TISAVE(TIDAC_key_blue_low);
 
278
    TISAVE(TIDAC_key_blue_high);
 
279
    TISAVE(TIDAC_key_ctrl);
 
280
    TISAVE(TIDAC_clock_ctrl);
 
281
    TISAVE(TIDAC_sense_test);
 
282
    TISAVE(TIDAC_ind_curs_ctrl);
 
283
}
 
284
 
 
285
RamDacHelperRecPtr
 
286
TIramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs)
 
287
{
 
288
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
 
289
    RamDacHelperRecPtr ramdacHelperPtr = NULL;
 
290
    Bool RamDacIsSupported = FALSE;
 
291
    int TIramdac_ID = -1;
 
292
    int i;
 
293
    unsigned char id, rev, rev2, id2;
 
294
 
 
295
    /* read ID and revision */
 
296
    rev = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev);
 
297
    id = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id);
 
298
 
 
299
    /* check if ID and revision are read only */
 
300
    (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, TIDAC_rev);
 
301
    (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, TIDAC_id);
 
302
    rev2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev);
 
303
    id2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id);
 
304
 
 
305
    switch (id) {
 
306
        case TIDAC_TVP_3030_ID:
 
307
                if (id == id2 && rev == rev2)  /* check for READ ONLY */
 
308
                    TIramdac_ID = TI3030_RAMDAC;
 
309
                break;
 
310
        case TIDAC_TVP_3026_ID:
 
311
                if (id == id2 && rev == rev2)  /* check for READ ONLY */
 
312
                    TIramdac_ID = TI3026_RAMDAC;
 
313
                break;
 
314
    }
 
315
 
 
316
    (*ramdacPtr->WriteDAC)(pScrn, rev, 0, TIDAC_rev);
 
317
    (*ramdacPtr->WriteDAC)(pScrn, id, 0, TIDAC_id);
 
318
 
 
319
    if (TIramdac_ID == -1) {
 
320
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
 
321
                "Cannot determine TI RAMDAC type, aborting\n");
 
322
        return NULL;
 
323
    } else {
 
324
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
 
325
                "Attached RAMDAC is %s\n", TIramdacDeviceInfo[TIramdac_ID&0xFFFF].DeviceName);
 
326
    }
 
327
 
 
328
    for (i=0;ramdacs[i].token != -1;i++) {
 
329
        if (ramdacs[i].token == TIramdac_ID)
 
330
            RamDacIsSupported = TRUE;
 
331
    }
 
332
 
 
333
    if (!RamDacIsSupported) {
 
334
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 
 
335
                "This TI RAMDAC is NOT supported by this driver, aborting\n");
 
336
        return NULL;
 
337
    }
 
338
 
 
339
    ramdacHelperPtr = RamDacHelperCreateInfoRec();
 
340
    switch (TIramdac_ID) {
 
341
        case TI3030_RAMDAC:
 
342
            ramdacHelperPtr->SetBpp = TIramdac3030SetBpp;
 
343
            ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit;
 
344
            break;
 
345
        case TI3026_RAMDAC:
 
346
            ramdacHelperPtr->SetBpp = TIramdac3026SetBpp;
 
347
            ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit;
 
348
            break;
 
349
    }
 
350
    ramdacPtr->RamDacType = TIramdac_ID;
 
351
    ramdacHelperPtr->RamDacType = TIramdac_ID;
 
352
    ramdacHelperPtr->Save = TIramdacSave;
 
353
    ramdacHelperPtr->Restore = TIramdacRestore;
 
354
 
 
355
    return ramdacHelperPtr;
 
356
}
 
357
 
 
358
void
 
359
TIramdac3026SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
 
360
{
 
361
    switch (pScrn->bitsPerPixel) {
 
362
    case 32:
 
363
        /* order is important */
 
364
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
 
365
        ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
 
366
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5c;
 
367
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
 
368
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
369
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
 
370
        ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
 
371
        /* 0x2A & 0x2B are reserved */
 
372
        ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
 
373
        ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
 
374
        ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
 
375
        ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
 
376
        ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
 
377
        ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
 
378
        ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
 
379
        ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
 
380
        ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
 
381
        ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
 
382
        if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
 
383
            ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
 
384
            ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
 
385
            ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
 
386
        }
 
387
        ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
 
388
        break;
 
389
    case 24:
 
390
        /* order is important */
 
391
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
 
392
        ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
 
393
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
 
394
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
 
395
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
396
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
 
397
        ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
 
398
        /* 0x2A & 0x2B are reserved */
 
399
        ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
 
400
        ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
 
401
        ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
 
402
        ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
 
403
        ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
 
404
        ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
 
405
        ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
 
406
        ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
 
407
        ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
 
408
        ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
 
409
        ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
 
410
        break;
 
411
    case 16:
 
412
        /* order is important */
 
413
#if 0
 
414
        /* Matrox driver uses this */
 
415
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
 
416
#else
 
417
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
 
418
#endif
 
419
        if (pScrn->depth == 16) {
 
420
            ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
 
421
        } else {
 
422
            ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
 
423
        }
 
424
#if 0
 
425
        /* Matrox driver uses this */
 
426
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
 
427
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
 
428
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
429
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
 
430
#else
 
431
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x54;
 
432
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
 
433
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
434
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
 
435
#endif
 
436
        ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
 
437
        /* 0x2A & 0x2B are reserved */
 
438
        ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
 
439
        ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
 
440
        ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
 
441
        ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
 
442
        ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
 
443
        ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
 
444
        ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
 
445
        ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
 
446
        ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
 
447
        ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
 
448
        ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
 
449
        break;
 
450
    case 8:
 
451
        /* order is important */
 
452
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
 
453
        ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
 
454
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4c;
 
455
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
 
456
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
457
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
 
458
        ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
 
459
        /* 0x2A & 0x2B are reserved */
 
460
        ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
 
461
        ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
 
462
        ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
 
463
        ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
 
464
        ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
 
465
        ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
 
466
        ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00;
 
467
        ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
 
468
        ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
 
469
        ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
 
470
        ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
 
471
        break;
 
472
    }
 
473
}
 
474
 
 
475
void
 
476
TIramdac3030SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
 
477
{
 
478
    switch (pScrn->bitsPerPixel) {
 
479
    case 32:
 
480
        /* order is important */
 
481
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
 
482
        ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
 
483
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5D;
 
484
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
 
485
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
486
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
 
487
        ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
 
488
        /* 0x2A & 0x2B are reserved */
 
489
        ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
 
490
        ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
 
491
        ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
 
492
        ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
 
493
        ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
 
494
        ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
 
495
        ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
 
496
        ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
 
497
        ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
 
498
        ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
 
499
        if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
 
500
            ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
 
501
            ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
 
502
            ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
 
503
        }
 
504
        ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
 
505
        break;
 
506
    case 24:
 
507
        /* order is important */
 
508
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
 
509
        ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
 
510
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
 
511
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
 
512
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
513
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
 
514
        ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
 
515
        /* 0x2A & 0x2B are reserved */
 
516
        ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
 
517
        ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
 
518
        ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
 
519
        ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
 
520
        ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
 
521
        ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
 
522
        ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
 
523
        ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
 
524
        ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
 
525
        ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
 
526
        ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
 
527
        break;
 
528
    case 16:
 
529
        /* order is important */
 
530
#if 0
 
531
        /* Matrox driver uses this */
 
532
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
 
533
#else
 
534
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
 
535
#endif
 
536
        if (pScrn->depth == 16) {
 
537
            ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
 
538
        } else {
 
539
            ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
 
540
        }
 
541
#if 0
 
542
        /* Matrox driver uses this */
 
543
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
 
544
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
 
545
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
546
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
 
547
#else
 
548
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x55;
 
549
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x85;
 
550
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
551
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
 
552
#endif
 
553
        ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
 
554
        /* 0x2A & 0x2B are reserved */
 
555
        ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
 
556
        ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
 
557
        ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
 
558
        ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
 
559
        ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
 
560
        ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
 
561
        ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
 
562
        ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
 
563
        ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
 
564
        ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
 
565
        ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
 
566
        break;
 
567
    case 8:
 
568
        /* order is important */
 
569
        ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
 
570
        ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
 
571
        ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4d;
 
572
        ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
 
573
        ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
 
574
        ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
 
575
        ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
 
576
        /* 0x2A & 0x2B are reserved */
 
577
        ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
 
578
        ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
 
579
        ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
 
580
        ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
 
581
        ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
 
582
        ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
 
583
        ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00;
 
584
        ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
 
585
        ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
 
586
        ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
 
587
        ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
 
588
        break;
 
589
    }
 
590
}
 
591
 
 
592
static void 
 
593
TIramdacShowCursor(ScrnInfoPtr pScrn)
 
594
{
 
595
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
 
596
 
 
597
    /* Enable cursor - X11 mode */
 
598
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x03);
 
599
}
 
600
 
 
601
static void
 
602
TIramdacHideCursor(ScrnInfoPtr pScrn)
 
603
{
 
604
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
 
605
 
 
606
    /* Disable cursor - X11 mode */
 
607
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x00);
 
608
}
 
609
 
 
610
static void
 
611
TIramdacSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
 
612
{
 
613
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
 
614
 
 
615
    x += 64;
 
616
    y += 64;
 
617
 
 
618
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XLOW,  0, x & 0xff);
 
619
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XHIGH, 0, (x >> 8) & 0x0f);
 
620
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YLOW,  0, y & 0xff);
 
621
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YHIGH, 0, (y >> 8) & 0x0f);
 
622
}
 
623
 
 
624
static void
 
625
TIramdacSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
 
626
{
 
627
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
 
628
 
 
629
    /* Background color */
 
630
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 1);
 
631
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x00ff0000) >> 16));
 
632
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x0000ff00) >>  8));
 
633
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0,  (bg&0x000000ff)       );
 
634
 
 
635
    /* Foreground color */
 
636
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 2);
 
637
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x00ff0000) >> 16));
 
638
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x0000ff00) >>  8));
 
639
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0,  (fg&0x000000ff)       );
 
640
}
 
641
 
 
642
static void 
 
643
TIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
 
644
{
 
645
    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
 
646
    int i = 1024;
 
647
 
 
648
    /* reset A9,A8 */
 
649
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x00); 
 
650
    /* reset cursor RAM load address A7..A0 */
 
651
    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_INDEX, 0x00, 0x00); 
 
652
 
 
653
    while(i--) {
 
654
        /* NOT_DONE: might need a delay here */
 
655
        (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_RAM_DATA, 0, *(src++));
 
656
    }
 
657
}
 
658
 
 
659
static Bool 
 
660
TIramdacUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
 
661
{
 
662
    return TRUE;
 
663
}
 
664
 
 
665
void
 
666
TIramdacHWCursorInit(xf86CursorInfoPtr infoPtr)
 
667
{
 
668
    infoPtr->MaxWidth = 64;
 
669
    infoPtr->MaxHeight = 64;
 
670
    infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
 
671
                     HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
 
672
                     HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
 
673
    infoPtr->SetCursorColors = TIramdacSetCursorColors;
 
674
    infoPtr->SetCursorPosition = TIramdacSetCursorPosition;
 
675
    infoPtr->LoadCursorImage = TIramdacLoadCursorImage;
 
676
    infoPtr->HideCursor = TIramdacHideCursor;
 
677
    infoPtr->ShowCursor = TIramdacShowCursor;
 
678
    infoPtr->UseHWCursor = TIramdacUseHWCursor;
 
679
}
 
680
 
 
681
void TIramdacLoadPalette(
 
682
    ScrnInfoPtr pScrn, 
 
683
    int numColors, 
 
684
    int *indices,
 
685
    LOCO *colors,
 
686
    VisualPtr pVisual
 
687
){
 
688
    RamDacRecPtr hwp = RAMDACSCRPTR(pScrn);
 
689
    int i, index, shift;
 
690
 
 
691
    if (pScrn->depth == 16) {
 
692
    for(i = 0; i < numColors; i++) {
 
693
        index = indices[i];
 
694
        (*hwp->WriteAddress)(pScrn, index << 2);
 
695
        (*hwp->WriteData)(pScrn, colors[index >> 1].red);
 
696
        (*hwp->WriteData)(pScrn, colors[index].green);
 
697
        (*hwp->WriteData)(pScrn, colors[index >> 1].blue);
 
698
 
 
699
        if(index <= 31) {
 
700
            (*hwp->WriteAddress)(pScrn, index << 3);
 
701
            (*hwp->WriteData)(pScrn, colors[index].red);
 
702
            (*hwp->WriteData)(pScrn, colors[(index << 1) + 1].green);
 
703
            (*hwp->WriteData)(pScrn, colors[index].blue);
 
704
        }
 
705
    }
 
706
} else {
 
707
    shift = (pScrn->depth == 15) ? 3 : 0;
 
708
 
 
709
    for(i = 0; i < numColors; i++) {
 
710
        index = indices[i];
 
711
        (*hwp->WriteAddress)(pScrn, index << shift);
 
712
        (*hwp->WriteData)(pScrn, colors[index].red);
 
713
        (*hwp->WriteData)(pScrn, colors[index].green);
 
714
        (*hwp->WriteData)(pScrn, colors[index].blue);
 
715
    }
 
716
}
 
717
}
 
718
 
 
719
TIramdacLoadPaletteProc *TIramdacLoadPaletteWeak(void) {
 
720
    return TIramdacLoadPalette;
 
721
}