1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 1998 by Alan Hourihane, Wigan, England.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Permission to use, copy, modify, distribute, and sell this software and its
5*4882a593Smuzhiyun * documentation for any purpose is hereby granted without fee, provided that
6*4882a593Smuzhiyun * the above copyright notice appear in all copies and that both that
7*4882a593Smuzhiyun * copyright notice and this permission notice appear in supporting
8*4882a593Smuzhiyun * documentation, and that the name of Alan Hourihane not be used in
9*4882a593Smuzhiyun * advertising or publicity pertaining to distribution of the software without
10*4882a593Smuzhiyun * specific, written prior permission. Alan Hourihane makes no representations
11*4882a593Smuzhiyun * about the suitability of this software for any purpose. It is provided
12*4882a593Smuzhiyun * "as is" without express or implied warranty.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*4882a593Smuzhiyun * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*4882a593Smuzhiyun * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*4882a593Smuzhiyun * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*4882a593Smuzhiyun * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*4882a593Smuzhiyun * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20*4882a593Smuzhiyun * PERFORMANCE OF THIS SOFTWARE.
21*4882a593Smuzhiyun *
22*4882a593Smuzhiyun * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun * BT RAMDAC routines.
25*4882a593Smuzhiyun */
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
28*4882a593Smuzhiyun #include <xorg-config.h>
29*4882a593Smuzhiyun #endif
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include "xf86.h"
32*4882a593Smuzhiyun #include "xf86_OSproc.h"
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define INIT_BT_RAMDAC_INFO
35*4882a593Smuzhiyun #include "BTPriv.h"
36*4882a593Smuzhiyun #include "xf86RamDacPriv.h"
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun void
BTramdacRestore(ScrnInfoPtr pScrn,RamDacRecPtr ramdacPtr,RamDacRegRecPtr ramdacReg)39*4882a593Smuzhiyun BTramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
40*4882a593Smuzhiyun RamDacRegRecPtr ramdacReg)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun int i;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* Here we pass a short, so that we can evaluate a mask too */
45*4882a593Smuzhiyun /* So that the mask is the high byte and the data the low byte */
46*4882a593Smuzhiyun /* Just the command/status registers */
47*4882a593Smuzhiyun for (i = 0x06; i < 0x0A; i++)
48*4882a593Smuzhiyun (*ramdacPtr->WriteDAC)
49*4882a593Smuzhiyun (pScrn, i, (ramdacReg->DacRegs[i] & 0xFF00) >> 8,
50*4882a593Smuzhiyun ramdacReg->DacRegs[i]);
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun void
BTramdacSave(ScrnInfoPtr pScrn,RamDacRecPtr ramdacPtr,RamDacRegRecPtr ramdacReg)54*4882a593Smuzhiyun BTramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
55*4882a593Smuzhiyun RamDacRegRecPtr ramdacReg)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun int i;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun (*ramdacPtr->ReadAddress) (pScrn, 0); /* Start at index 0 */
60*4882a593Smuzhiyun for (i = 0; i < 768; i++)
61*4882a593Smuzhiyun ramdacReg->DAC[i] = (*ramdacPtr->ReadData) (pScrn);
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun /* Just the command/status registers */
64*4882a593Smuzhiyun for (i = 0x06; i < 0x0A; i++)
65*4882a593Smuzhiyun ramdacReg->DacRegs[i] = (*ramdacPtr->ReadDAC) (pScrn, i);
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun RamDacHelperRecPtr
BTramdacProbe(ScrnInfoPtr pScrn,RamDacSupportedInfoRecPtr ramdacs)69*4882a593Smuzhiyun BTramdacProbe(ScrnInfoPtr pScrn,
70*4882a593Smuzhiyun RamDacSupportedInfoRecPtr ramdacs /*, RamDacRecPtr ramdacPtr */ )
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
73*4882a593Smuzhiyun Bool RamDacIsSupported = FALSE;
74*4882a593Smuzhiyun RamDacHelperRecPtr ramdacHelperPtr = NULL;
75*4882a593Smuzhiyun int BTramdac_ID = -1;
76*4882a593Smuzhiyun int i, status, cmd0;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /* Save COMMAND Register 0 */
79*4882a593Smuzhiyun cmd0 = (*ramdacPtr->ReadDAC) (pScrn, BT_COMMAND_REG_0);
80*4882a593Smuzhiyun /* Ensure were going to access the STATUS Register on next read */
81*4882a593Smuzhiyun (*ramdacPtr->WriteDAC) (pScrn, BT_COMMAND_REG_0, 0x7F, 0x00);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun status = (*ramdacPtr->ReadDAC) (pScrn, BT_STATUS_REG);
84*4882a593Smuzhiyun switch (status) {
85*4882a593Smuzhiyun case 0x40:
86*4882a593Smuzhiyun BTramdac_ID = ATT20C504_RAMDAC;
87*4882a593Smuzhiyun break;
88*4882a593Smuzhiyun case 0xD0:
89*4882a593Smuzhiyun BTramdac_ID = ATT20C505_RAMDAC;
90*4882a593Smuzhiyun break;
91*4882a593Smuzhiyun default:
92*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
93*4882a593Smuzhiyun "Unknown BT RAMDAC type (0x%x), assuming BT485\n", status);
94*4882a593Smuzhiyun case 0x80:
95*4882a593Smuzhiyun case 0x90:
96*4882a593Smuzhiyun case 0xA0:
97*4882a593Smuzhiyun case 0xB0:
98*4882a593Smuzhiyun case 0x28: /* This is for the DEC TGA - Questionable ? */
99*4882a593Smuzhiyun BTramdac_ID = BT485_RAMDAC;
100*4882a593Smuzhiyun break;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun /* Restore COMMAND Register 0 */
104*4882a593Smuzhiyun (*ramdacPtr->WriteDAC) (pScrn, BT_COMMAND_REG_0, 0x00, cmd0);
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun if (BTramdac_ID == -1) {
107*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
108*4882a593Smuzhiyun "Cannot determine BT RAMDAC type, aborting\n");
109*4882a593Smuzhiyun return NULL;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun else {
112*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
113*4882a593Smuzhiyun "Attached RAMDAC is %s\n",
114*4882a593Smuzhiyun BTramdacDeviceInfo[BTramdac_ID & 0xFFFF].DeviceName);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun for (i = 0; ramdacs[i].token != -1; i++) {
118*4882a593Smuzhiyun if (ramdacs[i].token == BTramdac_ID)
119*4882a593Smuzhiyun RamDacIsSupported = TRUE;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun if (!RamDacIsSupported) {
123*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
124*4882a593Smuzhiyun "This BT RAMDAC is NOT supported by this driver, aborting\n");
125*4882a593Smuzhiyun return NULL;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun ramdacHelperPtr = RamDacHelperCreateInfoRec();
129*4882a593Smuzhiyun switch (BTramdac_ID) {
130*4882a593Smuzhiyun case BT485_RAMDAC:
131*4882a593Smuzhiyun ramdacHelperPtr->SetBpp = BTramdacSetBpp;
132*4882a593Smuzhiyun break;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun ramdacPtr->RamDacType = BTramdac_ID;
135*4882a593Smuzhiyun ramdacHelperPtr->RamDacType = BTramdac_ID;
136*4882a593Smuzhiyun ramdacHelperPtr->Save = BTramdacSave;
137*4882a593Smuzhiyun ramdacHelperPtr->Restore = BTramdacRestore;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun return ramdacHelperPtr;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun void
BTramdacSetBpp(ScrnInfoPtr pScrn,RamDacRegRecPtr ramdacReg)143*4882a593Smuzhiyun BTramdacSetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun /* We need to deal with Direct Colour visuals for 8bpp and other
146*4882a593Smuzhiyun * good stuff for colours */
147*4882a593Smuzhiyun switch (pScrn->bitsPerPixel) {
148*4882a593Smuzhiyun case 32:
149*4882a593Smuzhiyun ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x10;
150*4882a593Smuzhiyun break;
151*4882a593Smuzhiyun case 24:
152*4882a593Smuzhiyun ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x10;
153*4882a593Smuzhiyun break;
154*4882a593Smuzhiyun case 16:
155*4882a593Smuzhiyun ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x38;
156*4882a593Smuzhiyun break;
157*4882a593Smuzhiyun case 15:
158*4882a593Smuzhiyun ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x30;
159*4882a593Smuzhiyun break;
160*4882a593Smuzhiyun case 8:
161*4882a593Smuzhiyun ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x40;
162*4882a593Smuzhiyun break;
163*4882a593Smuzhiyun case 4:
164*4882a593Smuzhiyun ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x60;
165*4882a593Smuzhiyun break;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun }
168