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