1
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.c,v 1.18 2003/02/25 17:58:13 tsi Exp $ */
3
* Copyright 1997 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
5
* Permission to use, copy, modify, distribute, and sell this software and its
6
* documentation for any purpose is hereby granted without fee, provided that
7
* the above copyright notice appear in all copies and that both that copyright
8
* notice and this permission notice appear in supporting documentation, and
9
* that the name of Marc Aurele La France not be used in advertising or
10
* publicity pertaining to distribution of the software without specific,
11
* written prior permission. Marc Aurele La France makes no representations
12
* about the suitability of this software for any purpose. It is provided
13
* "as-is" without express or implied warranty.
15
* MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
17
* EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21
* PERFORMANCE OF THIS SOFTWARE.
26
#include "atimach64io.h"
30
* RAMDAC-related definitions.
32
const SymTabRec ATIDACDescriptors[] =
33
{ /* Keep this table in ascending DACType order */
34
{ATI_DAC_ATI68830, "ATI 68830 or similar"},
35
{ATI_DAC_SC11483, "Sierra 11483 or similar"},
36
{ATI_DAC_ATI68875, "ATI 68875 or similar"},
37
{ATI_DAC_TVP3026_A, "TI ViewPoint3026 or similar"},
38
{ATI_DAC_GENERIC, "Brooktree 476 or similar"},
39
{ATI_DAC_BT481, "Brooktree 481 or similar"},
40
{ATI_DAC_ATT20C491, "AT&T 20C491 or similar"},
41
{ATI_DAC_SC15026, "Sierra 15026 or similar"},
42
{ATI_DAC_MU9C1880, "Music 9C1880 or similar"},
43
{ATI_DAC_IMSG174, "Inmos G174 or similar"},
44
{ATI_DAC_ATI68860_B, "ATI 68860 (Revision B) or similar"},
45
{ATI_DAC_ATI68860_C, "ATI 68860 (Revision C) or similar"},
46
{ATI_DAC_TVP3026_B, "TI ViewPoint3026 or similar"},
47
{ATI_DAC_STG1700, "SGS-Thompson 1700 or similar"},
48
{ATI_DAC_ATT20C498, "AT&T 20C498 or similar"},
49
{ATI_DAC_STG1702, "SGS-Thompson 1702 or similar"},
50
{ATI_DAC_SC15021, "Sierra 15021 or similar"},
51
{ATI_DAC_ATT21C498, "AT&T 21C498 or similar"},
52
{ATI_DAC_STG1703, "SGS-Thompson 1703 or similar"},
53
{ATI_DAC_CH8398, "Chrontel 8398 or similar"},
54
{ATI_DAC_ATT20C408, "AT&T 20C408 or similar"},
55
{ATI_DAC_INTERNAL, "Internal"},
56
{ATI_DAC_IBMRGB514, "IBM RGB 514 or similar"},
57
{ATI_DAC_UNKNOWN, "Unknown"} /* Must be last */
65
* This function sets up DAC access I/O port numbers.
77
pATI->CPIO_DAC_DATA = VGA_DAC_DATA;
78
pATI->CPIO_DAC_MASK = VGA_DAC_MASK;
79
pATI->CPIO_DAC_READ = VGA_DAC_READ;
80
pATI->CPIO_DAC_WRITE = VGA_DAC_WRITE;
81
pATI->CPIO_DAC_WAIT = GENS1(pATI->CPIO_VGABase);
85
pATI->CPIO_DAC_DATA = IBM_DAC_DATA;
86
pATI->CPIO_DAC_MASK = IBM_DAC_MASK;
87
pATI->CPIO_DAC_READ = IBM_DAC_READ;
88
pATI->CPIO_DAC_WRITE = IBM_DAC_WRITE;
89
pATI->CPIO_DAC_WAIT = pATI->CPIO_DAC_MASK;
93
pATI->CPIO_DAC_DATA = ATIIOPort(DAC_REGS) + 1;
94
pATI->CPIO_DAC_MASK = ATIIOPort(DAC_REGS) + 2;
95
pATI->CPIO_DAC_READ = ATIIOPort(DAC_REGS) + 3;
96
pATI->CPIO_DAC_WRITE = ATIIOPort(DAC_REGS) + 0;
97
pATI->CPIO_DAC_WAIT = pATI->CPIOBase;
105
#endif /* AVOID_CPIO */
110
* Setup to access a RAMDAC's command register.
121
(void)in8(M64_DAC_WRITE); /* Reset to PEL mode */
122
(void)in8(M64_DAC_MASK);
123
(void)in8(M64_DAC_MASK);
124
(void)in8(M64_DAC_MASK);
125
return in8(M64_DAC_MASK);
127
#else /* AVOID_CPIO */
129
(void)inb(pATI->CPIO_DAC_WRITE); /* Reset to PEL mode */
130
(void)inb(pATI->CPIO_DAC_MASK);
131
(void)inb(pATI->CPIO_DAC_MASK);
132
(void)inb(pATI->CPIO_DAC_MASK);
133
return inb(pATI->CPIO_DAC_MASK);
135
#endif /* AVOID_CPIO */
142
* This function initialises the fields in an ATIHWRec that relate to DACs.
147
ScrnInfoPtr pScreenInfo,
153
CARD8 maxColour = (1 << pATI->rgbBits) - 1;
155
pATIHW->dac_read = pATIHW->dac_write = 0x00U;
156
pATIHW->dac_mask = 0xFFU;
159
* Set colour lookup table. The first entry has already been zeroed out.
162
for (Index = 1; Index < (NumberOf(pATIHW->lut) / 3); Index++)
165
pATIHW->lut[Index2 + 0] =
166
pATIHW->lut[Index2 + 1] =
167
pATIHW->lut[Index2 + 2] = Index;
172
* Initialise hardware colour map so that use of uninitialised
173
* software colour map entries can easily be seen. For 256-colour
174
* modes, this doesn't remain effective for very long...
176
pATIHW->lut[3] = pATIHW->lut[4] = pATIHW->lut[5] = 0xFFU;
177
for (Index = 2; Index < (NumberOf(pATIHW->lut) / 3); Index++)
180
pATIHW->lut[Index2 + 0] = maxColour;
181
pATIHW->lut[Index2 + 1] = 0x00U;
182
pATIHW->lut[Index2 + 2] = maxColour;
187
if (pATI->depth == 1)
189
rgb blackColour = pScreenInfo->display->blackColour,
190
whiteColour = pScreenInfo->display->whiteColour;
192
if (blackColour.red > maxColour)
193
blackColour.red = maxColour;
194
if (blackColour.green > maxColour)
195
blackColour.green = maxColour;
196
if (blackColour.blue > maxColour)
197
blackColour.blue = maxColour;
198
if (whiteColour.red > maxColour)
199
whiteColour.red = maxColour;
200
if (whiteColour.green > maxColour)
201
whiteColour.green = maxColour;
202
if (whiteColour.blue > maxColour)
203
whiteColour.blue = maxColour;
205
if ((blackColour.red == whiteColour.red) &&
206
(blackColour.green == whiteColour.green) &&
207
(blackColour.blue == whiteColour.blue))
209
blackColour.red ^= maxColour;
210
blackColour.green ^= maxColour;
211
blackColour.blue ^= maxColour;
214
pATIHW->lut[(MONO_BLACK * 3) + 0] = blackColour.red;
215
pATIHW->lut[(MONO_BLACK * 3) + 1] = blackColour.green;
216
pATIHW->lut[(MONO_BLACK * 3) + 2] = blackColour.blue;
217
pATIHW->lut[(MONO_WHITE * 3) + 0] = whiteColour.red;
218
pATIHW->lut[(MONO_WHITE * 3) + 1] = whiteColour.green;
219
pATIHW->lut[(MONO_WHITE * 3) + 2] = whiteColour.blue;
222
if (pATIHW->crtc == ATI_CRTC_VGA)
224
/* Initialise overscan to black */
225
Index = pATIHW->attr[17] * 3;
226
pATIHW->lut[Index + 0] =
227
pATIHW->lut[Index + 1] =
228
pATIHW->lut[Index + 2] = 0x00U;
231
#endif /* AVOID_CPIO */
239
* This function is called to save the current RAMDAC state into an ATIHWRec
240
* structure occurrence.
253
pATIHW->dac_read = in8(M64_DAC_READ);
255
pATIHW->dac_write = in8(M64_DAC_WRITE);
257
pATIHW->dac_mask = in8(M64_DAC_MASK);
260
/* Save DAC's colour lookup table */
261
out8(M64_DAC_MASK, 0xFFU);
263
out8(M64_DAC_READ, 0x00U);
265
for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
267
pATIHW->lut[Index] = in8(M64_DAC_DATA);
271
out8(M64_DAC_MASK, pATIHW->dac_mask);
273
out8(M64_DAC_READ, pATIHW->dac_read);
276
#else /* AVOID_CPIO */
278
ATISetDACIOPorts(pATI, pATIHW->crtc);
280
pATIHW->dac_read = inb(pATI->CPIO_DAC_READ);
282
pATIHW->dac_write = inb(pATI->CPIO_DAC_WRITE);
284
pATIHW->dac_mask = inb(pATI->CPIO_DAC_MASK);
287
/* Save DAC's colour lookup table */
288
outb(pATI->CPIO_DAC_MASK, 0xFFU);
290
outb(pATI->CPIO_DAC_READ, 0x00U);
292
for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
294
pATIHW->lut[Index] = inb(pATI->CPIO_DAC_DATA);
298
outb(pATI->CPIO_DAC_MASK, pATIHW->dac_mask);
300
outb(pATI->CPIO_DAC_READ, pATIHW->dac_read);
303
#endif /* AVOID_CPIO */
310
* This function loads RAMDAC data from an ATIHWRec structure occurrence.
323
/* Load DAC's colour lookup table */
324
out8(M64_DAC_MASK, 0xFFU);
326
out8(M64_DAC_WRITE, 0x00U);
328
for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
330
out8(M64_DAC_DATA, pATIHW->lut[Index]);
334
out8(M64_DAC_MASK, pATIHW->dac_mask);
336
out8(M64_DAC_READ, pATIHW->dac_read);
338
out8(M64_DAC_WRITE, pATIHW->dac_write);
341
#else /* AVOID_CPIO */
343
ATISetDACIOPorts(pATI, pATIHW->crtc);
345
/* Load DAC's colour lookup table */
346
outb(pATI->CPIO_DAC_MASK, 0xFFU);
348
outb(pATI->CPIO_DAC_WRITE, 0x00U);
350
for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
352
outb(pATI->CPIO_DAC_DATA, pATIHW->lut[Index]);
356
outb(pATI->CPIO_DAC_MASK, pATIHW->dac_mask);
358
outb(pATI->CPIO_DAC_READ, pATIHW->dac_read);
360
outb(pATI->CPIO_DAC_WRITE, pATIHW->dac_write);
363
#endif /* AVOID_CPIO */
370
* This function updates the RAMDAC's LUT and the in-memory copy of it in
376
ScrnInfoPtr pScreenInfo,
383
ATIPtr pATI = ATIPTR(pScreenInfo);
387
if (((pVisual->class | DynamicClass) == DirectColor) &&
388
((1 << pVisual->nplanes) > (SizeOf(pATI->NewHW.lut) / 3)))
390
int reds = pVisual->redMask >> pVisual->offsetRed;
391
int greens = pVisual->greenMask >> pVisual->offsetGreen;
392
int blues = pVisual->blueMask >> pVisual->offsetBlue;
394
int redShift = 8 - pATI->weight.red;
395
int greenShift = 8 - pATI->weight.green;
396
int blueShift = 8 - pATI->weight.blue;
398
int redMult = 3 << redShift;
399
int greenMult = 3 << greenShift;
400
int blueMult = 3 << blueShift;
404
CARD8 fChanged[SizeOf(pATI->NewHW.lut) / 3];
406
(void)memset(fChanged, SizeOf(fChanged), 0);
409
if (minShift > greenShift)
410
minShift = greenShift;
411
if (minShift > blueShift)
412
minShift = blueShift;
414
for (i = 0; i < nColours; i++)
416
if((Index = Indices[i]) < 0)
422
pATI->NewHW.lut[j + 0] = Colours[Index].red;
423
fChanged[j / 3] = TRUE;
427
j = Index * greenMult;
428
pATI->NewHW.lut[j + 1] = Colours[Index].green;
429
fChanged[j / 3] = TRUE;
433
j = Index * blueMult;
434
pATI->NewHW.lut[j + 2] = Colours[Index].blue;
435
fChanged[j / 3] = TRUE;
439
if (pScreenInfo->vtSema || pATI->currentMode)
441
/* Rewrite LUT entries that could have been changed */
443
LUTEntry = pATI->NewHW.lut;
446
Index < (SizeOf(pATI->NewHW.lut) / 3);
447
Index += i, LUTEntry += i * 3)
449
if (!fChanged[Index])
454
out8(M64_DAC_WRITE, Index);
456
out8(M64_DAC_DATA, LUTEntry[0]);
458
out8(M64_DAC_DATA, LUTEntry[1]);
460
out8(M64_DAC_DATA, LUTEntry[2]);
463
#else /* AVOID_CPIO */
465
outb(pATI->CPIO_DAC_WRITE, Index);
467
outb(pATI->CPIO_DAC_DATA, LUTEntry[0]);
469
outb(pATI->CPIO_DAC_DATA, LUTEntry[1]);
471
outb(pATI->CPIO_DAC_DATA, LUTEntry[2]);
474
#endif /* AVOID_CPIO */
481
for (i = 0; i < nColours; i++)
484
if ((Index < 0) || (Index >= (SizeOf(pATI->NewHW.lut) / 3)))
487
LUTEntry = &pATI->NewHW.lut[Index * 3];
488
LUTEntry[0] = Colours[Index].red;
489
LUTEntry[1] = Colours[Index].green;
490
LUTEntry[2] = Colours[Index].blue;
492
if (pScreenInfo->vtSema || pATI->currentMode)
497
out8(M64_DAC_WRITE, Index);
499
out8(M64_DAC_DATA, LUTEntry[0]);
501
out8(M64_DAC_DATA, LUTEntry[1]);
503
out8(M64_DAC_DATA, LUTEntry[2]);
506
#else /* AVOID_CPIO */
508
outb(pATI->CPIO_DAC_WRITE, Index);
510
outb(pATI->CPIO_DAC_DATA, LUTEntry[0]);
512
outb(pATI->CPIO_DAC_DATA, LUTEntry[1]);
514
outb(pATI->CPIO_DAC_DATA, LUTEntry[2]);
517
#endif /* AVOID_CPIO */