xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/ramdac/TI.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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