1706f2543Smrg/*
2706f2543Smrg * Copyright 1998 by Alan Hourihane, Wigan, England.
3706f2543Smrg *
4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
6706f2543Smrg * the above copyright notice appear in all copies and that both that
7706f2543Smrg * copyright notice and this permission notice appear in supporting
8706f2543Smrg * documentation, and that the name of Alan Hourihane not be used in
9706f2543Smrg * advertising or publicity pertaining to distribution of the software without
10706f2543Smrg * specific, written prior permission.  Alan Hourihane makes no representations
11706f2543Smrg * about the suitability of this software for any purpose.  It is provided
12706f2543Smrg * "as is" without express or implied warranty.
13706f2543Smrg *
14706f2543Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16706f2543Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
21706f2543Smrg *
22706f2543Smrg * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23706f2543Smrg *
24706f2543Smrg * Modified from IBM.c to support TI RAMDAC routines
25706f2543Smrg *   by Jens Owen, <jens@tungstengraphics.com>.
26706f2543Smrg */
27706f2543Smrg
28706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
29706f2543Smrg#include <xorg-config.h>
30706f2543Smrg#endif
31706f2543Smrg
32706f2543Smrg#include "xf86.h"
33706f2543Smrg#include "xf86_OSproc.h"
34706f2543Smrg
35706f2543Smrg#include "xf86Cursor.h"
36706f2543Smrg
37706f2543Smrg#define INIT_TI_RAMDAC_INFO
38706f2543Smrg#include "TIPriv.h"
39706f2543Smrg#include "xf86RamDacPriv.h"
40706f2543Smrg
41706f2543Smrg/* The following values are in kHz */
42706f2543Smrg#define TI_MIN_VCO_FREQ  110000
43706f2543Smrg#define TI_MAX_VCO_FREQ  220000
44706f2543Smrg
45706f2543Smrgunsigned long
46706f2543SmrgTIramdacCalculateMNPForClock(
47706f2543Smrg    unsigned long RefClock,	/* In 100Hz units */
48706f2543Smrg    unsigned long ReqClock,	/* In 100Hz units */
49706f2543Smrg    char IsPixClock,	/* boolean, is this the pixel or the sys clock */
50706f2543Smrg    unsigned long MinClock,	/* Min VCO rating */
51706f2543Smrg    unsigned long MaxClock,	/* Max VCO rating */
52706f2543Smrg    unsigned long *rM,	/* M Out */
53706f2543Smrg    unsigned long *rN,	/* N Out */
54706f2543Smrg    unsigned long *rP 	/* Min P In, P Out */
55706f2543Smrg)
56706f2543Smrg{
57706f2543Smrg    unsigned long   n, p;
58706f2543Smrg    unsigned long   best_m = 0, best_n = 0;
59706f2543Smrg    double          VCO, IntRef = (double)RefClock;
60706f2543Smrg    double          m_err, inc_m, calc_m;
61706f2543Smrg    unsigned long   ActualClock;
62706f2543Smrg
63706f2543Smrg    /* Make sure that MinClock <= ReqClock <= MaxClock */
64706f2543Smrg    if ( ReqClock < MinClock)
65706f2543Smrg	ReqClock = MinClock;
66706f2543Smrg    if ( ReqClock > MaxClock )
67706f2543Smrg	ReqClock = MaxClock;
68706f2543Smrg
69706f2543Smrg    /*
70706f2543Smrg     * ActualClock = VCO / 2 ^ p
71706f2543Smrg     * Choose p so that TI_MIN_VCO_FREQ <= VCO <= TI_MAX_VCO_FREQ
72706f2543Smrg     * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ
73706f2543Smrg     * we don't have to bother checking for this maximum limit.
74706f2543Smrg     */
75706f2543Smrg    VCO = (double)ReqClock;
76706f2543Smrg    for ( p = 0; p < 3 && VCO < TI_MIN_VCO_FREQ; ( p )++ )
77706f2543Smrg	 VCO *= 2.0;
78706f2543Smrg
79706f2543Smrg    /*
80706f2543Smrg     * We avoid doing multiplications by ( 65 - n ),
81706f2543Smrg     * and add an increment instead - this keeps any error small.
82706f2543Smrg     */
83706f2543Smrg    inc_m = VCO / ( IntRef * 8.0 );
84706f2543Smrg
85706f2543Smrg    /* Initial value of calc_m for the loop */
86706f2543Smrg    calc_m = inc_m + inc_m + inc_m;
87706f2543Smrg
88706f2543Smrg    /* Initial amount of error for an integer - impossibly large */
89706f2543Smrg    m_err = 2.0;
90706f2543Smrg
91706f2543Smrg    /* Search for the closest INTEGER value of ( 65 - m ) */
92706f2543Smrg    for ( n = 3; n <= 25; ( n )++, calc_m += inc_m ) {
93706f2543Smrg
94706f2543Smrg	/* Ignore values of ( 65 - m ) which we can't use */
95706f2543Smrg	if ( calc_m < 3.0 || calc_m > 64.0 )
96706f2543Smrg	    continue;
97706f2543Smrg
98706f2543Smrg	/*
99706f2543Smrg	 * Pick the closest INTEGER (has smallest fractional part).
100706f2543Smrg	 * The optimizer should clean this up for us.
101706f2543Smrg	 */
102706f2543Smrg	if (( calc_m - ( int ) calc_m ) < m_err ) {
103706f2543Smrg	    m_err = calc_m - ( int ) calc_m;
104706f2543Smrg	    best_m = ( int ) calc_m;
105706f2543Smrg	    best_n = n;
106706f2543Smrg	}
107706f2543Smrg    }
108706f2543Smrg
109706f2543Smrg    /* 65 - ( 65 - x ) = x */
110706f2543Smrg    *rM = 65 - best_m;
111706f2543Smrg    *rN = 65 - best_n;
112706f2543Smrg    *rP = p;
113706f2543Smrg
114706f2543Smrg    /* Now all the calculations can be completed */
115706f2543Smrg    VCO = 8.0 * IntRef * best_m / best_n;
116706f2543Smrg    ActualClock = VCO / ( 1 << p );
117706f2543Smrg
118706f2543Smrg    DebugF( "f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n",
119706f2543Smrg	    ActualClock, VCO, *rN, *rM, *rP);
120706f2543Smrg
121706f2543Smrg    return ActualClock;
122706f2543Smrg}
123706f2543Smrg
124706f2543Smrgvoid
125706f2543SmrgTIramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
126706f2543Smrg				   RamDacRegRecPtr ramdacReg)
127706f2543Smrg{
128706f2543Smrg    int i;
129706f2543Smrg    unsigned long status;
130706f2543Smrg
131706f2543Smrg    /* Here we pass a short, so that we can evaluate a mask too
132706f2543Smrg     * So that the mask is the high byte and the data the low byte
133706f2543Smrg     * Order is important
134706f2543Smrg     */
135706f2543Smrg    TIRESTORE(TIDAC_latch_ctrl);
136706f2543Smrg    TIRESTORE(TIDAC_true_color_ctrl);
137706f2543Smrg    TIRESTORE(TIDAC_multiplex_ctrl);
138706f2543Smrg    TIRESTORE(TIDAC_clock_select);
139706f2543Smrg    TIRESTORE(TIDAC_palette_page);
140706f2543Smrg    TIRESTORE(TIDAC_general_ctrl);
141706f2543Smrg    TIRESTORE(TIDAC_misc_ctrl);
142706f2543Smrg	    /* 0x2A & 0x2B are reserved */
143706f2543Smrg    TIRESTORE(TIDAC_key_over_low);
144706f2543Smrg    TIRESTORE(TIDAC_key_over_high);
145706f2543Smrg    TIRESTORE(TIDAC_key_red_low);
146706f2543Smrg    TIRESTORE(TIDAC_key_red_high);
147706f2543Smrg    TIRESTORE(TIDAC_key_green_low);
148706f2543Smrg    TIRESTORE(TIDAC_key_green_high);
149706f2543Smrg    TIRESTORE(TIDAC_key_blue_low);
150706f2543Smrg    TIRESTORE(TIDAC_key_blue_high);
151706f2543Smrg    TIRESTORE(TIDAC_key_ctrl);
152706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x30);
153706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x38);
154706f2543Smrg    TIRESTORE(TIDAC_clock_ctrl);
155706f2543Smrg    TIRESTORE(TIDAC_sense_test);
156706f2543Smrg    TIRESTORE(TIDAC_ind_curs_ctrl);
157706f2543Smrg
158706f2543Smrg    /* only restore clocks if they were valid to begin with */
159706f2543Smrg
160706f2543Smrg    if (ramdacReg->DacRegs[TIDAC_PIXEL_VALID]) {
161706f2543Smrg    /* Reset pixel clock */
162706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
163706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0, 0x3c);
164706f2543Smrg
165706f2543Smrg    /* Restore N, M & P values for pixel clocks */
166706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
167706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
168706f2543Smrg					ramdacReg->DacRegs[TIDAC_PIXEL_N]);
169706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
170706f2543Smrg					ramdacReg->DacRegs[TIDAC_PIXEL_M]);
171706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
172706f2543Smrg					ramdacReg->DacRegs[TIDAC_PIXEL_P]);
173706f2543Smrg
174706f2543Smrg    /* wait for pixel clock to lock */
175706f2543Smrg    i = 1000000;
176706f2543Smrg    do {
177706f2543Smrg	status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
178706f2543Smrg    } while ((!(status & 0x40)) && (--i));
179706f2543Smrg    if (!(status & 0x40)) {
180706f2543Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
181706f2543Smrg			"Pixel clock setup timed out\n");
182706f2543Smrg	return;
183706f2543Smrg    }
184706f2543Smrg    }
185706f2543Smrg
186706f2543Smrg    if (ramdacReg->DacRegs[TIDAC_LOOP_VALID]) {
187706f2543Smrg    /* Reset loop clock */
188706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
189706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0, 0x70);
190706f2543Smrg
191706f2543Smrg    /* Restore N, M & P values for pixel clocks */
192706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
193706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
194706f2543Smrg					ramdacReg->DacRegs[TIDAC_LOOP_N]);
195706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
196706f2543Smrg					ramdacReg->DacRegs[TIDAC_LOOP_M]);
197706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
198706f2543Smrg					ramdacReg->DacRegs[TIDAC_LOOP_P]);
199706f2543Smrg
200706f2543Smrg    /* wait for loop clock to lock */
201706f2543Smrg    i = 1000000;
202706f2543Smrg    do {
203706f2543Smrg        status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
204706f2543Smrg    } while ((!(status & 0x40)) && (--i));
205706f2543Smrg    if (!(status & 0x40)) {
206706f2543Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
207706f2543Smrg			"Loop clock setup timed out\n");
208706f2543Smrg	    return;
209706f2543Smrg    }
210706f2543Smrg    }
211706f2543Smrg
212706f2543Smrg    /* restore palette */
213706f2543Smrg    (*ramdacPtr->WriteAddress)(pScrn, 0);
214706f2543Smrg#ifndef NOT_DONE
215706f2543Smrg    for (i=0;i<768;i++)
216706f2543Smrg	(*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]);
217706f2543Smrg#else
218706f2543Smrg	(*ramdacPtr->WriteData)(pScrn, 0);
219706f2543Smrg	(*ramdacPtr->WriteData)(pScrn, 0);
220706f2543Smrg	(*ramdacPtr->WriteData)(pScrn, 0);
221706f2543Smrg    for (i=0;i<765;i++)
222706f2543Smrg	(*ramdacPtr->WriteData)(pScrn, 0xff);
223706f2543Smrg#endif
224706f2543Smrg}
225706f2543Smrg
226706f2543Smrgvoid
227706f2543SmrgTIramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
228706f2543Smrg				RamDacRegRecPtr ramdacReg)
229706f2543Smrg{
230706f2543Smrg    int i;
231706f2543Smrg
232706f2543Smrg    (*ramdacPtr->ReadAddress)(pScrn, 0);
233706f2543Smrg    for (i=0;i<768;i++)
234706f2543Smrg	ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn);
235706f2543Smrg
236706f2543Smrg    /* Read back N,M and P values for pixel clock */
237706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
238706f2543Smrg    ramdacReg->DacRegs[TIDAC_PIXEL_N] =
239706f2543Smrg			(*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
240706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11);
241706f2543Smrg    ramdacReg->DacRegs[TIDAC_PIXEL_M] =
242706f2543Smrg		    	(*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
243706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
244706f2543Smrg    ramdacReg->DacRegs[TIDAC_PIXEL_P] =
245706f2543Smrg		    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
246706f2543Smrg
247706f2543Smrg    /* Read back N,M and P values for loop clock */
248706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
249706f2543Smrg    ramdacReg->DacRegs[TIDAC_LOOP_N] =
250706f2543Smrg		    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
251706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11);
252706f2543Smrg    ramdacReg->DacRegs[TIDAC_LOOP_M] =
253706f2543Smrg		    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
254706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
255706f2543Smrg    ramdacReg->DacRegs[TIDAC_LOOP_P] =
256706f2543Smrg		    (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
257706f2543Smrg
258706f2543Smrg    /* Order is important */
259706f2543Smrg    TISAVE(TIDAC_latch_ctrl);
260706f2543Smrg    TISAVE(TIDAC_true_color_ctrl);
261706f2543Smrg    TISAVE(TIDAC_multiplex_ctrl);
262706f2543Smrg    TISAVE(TIDAC_clock_select);
263706f2543Smrg    TISAVE(TIDAC_palette_page);
264706f2543Smrg    TISAVE(TIDAC_general_ctrl);
265706f2543Smrg    TISAVE(TIDAC_misc_ctrl);
266706f2543Smrg	    /* 0x2A & 0x2B are reserved */
267706f2543Smrg    TISAVE(TIDAC_key_over_low);
268706f2543Smrg    TISAVE(TIDAC_key_over_high);
269706f2543Smrg    TISAVE(TIDAC_key_red_low);
270706f2543Smrg    TISAVE(TIDAC_key_red_high);
271706f2543Smrg    TISAVE(TIDAC_key_green_low);
272706f2543Smrg    TISAVE(TIDAC_key_green_high);
273706f2543Smrg    TISAVE(TIDAC_key_blue_low);
274706f2543Smrg    TISAVE(TIDAC_key_blue_high);
275706f2543Smrg    TISAVE(TIDAC_key_ctrl);
276706f2543Smrg    TISAVE(TIDAC_clock_ctrl);
277706f2543Smrg    TISAVE(TIDAC_sense_test);
278706f2543Smrg    TISAVE(TIDAC_ind_curs_ctrl);
279706f2543Smrg}
280706f2543Smrg
281706f2543SmrgRamDacHelperRecPtr
282706f2543SmrgTIramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs)
283706f2543Smrg{
284706f2543Smrg    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
285706f2543Smrg    RamDacHelperRecPtr ramdacHelperPtr = NULL;
286706f2543Smrg    Bool RamDacIsSupported = FALSE;
287706f2543Smrg    int TIramdac_ID = -1;
288706f2543Smrg    int i;
289706f2543Smrg    unsigned char id, rev, rev2, id2;
290706f2543Smrg
291706f2543Smrg    /* read ID and revision */
292706f2543Smrg    rev = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev);
293706f2543Smrg    id = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id);
294706f2543Smrg
295706f2543Smrg    /* check if ID and revision are read only */
296706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, TIDAC_rev);
297706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, TIDAC_id);
298706f2543Smrg    rev2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev);
299706f2543Smrg    id2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id);
300706f2543Smrg
301706f2543Smrg    switch (id) {
302706f2543Smrg	case TIDAC_TVP_3030_ID:
303706f2543Smrg		if (id == id2 && rev == rev2)  /* check for READ ONLY */
304706f2543Smrg		    TIramdac_ID = TI3030_RAMDAC;
305706f2543Smrg		break;
306706f2543Smrg	case TIDAC_TVP_3026_ID:
307706f2543Smrg		if (id == id2 && rev == rev2)  /* check for READ ONLY */
308706f2543Smrg		    TIramdac_ID = TI3026_RAMDAC;
309706f2543Smrg		break;
310706f2543Smrg    }
311706f2543Smrg
312706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, rev, 0, TIDAC_rev);
313706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, id, 0, TIDAC_id);
314706f2543Smrg
315706f2543Smrg    if (TIramdac_ID == -1) {
316706f2543Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
317706f2543Smrg		"Cannot determine TI RAMDAC type, aborting\n");
318706f2543Smrg	return NULL;
319706f2543Smrg    } else {
320706f2543Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
321706f2543Smrg		"Attached RAMDAC is %s\n", TIramdacDeviceInfo[TIramdac_ID&0xFFFF].DeviceName);
322706f2543Smrg    }
323706f2543Smrg
324706f2543Smrg    for (i=0;ramdacs[i].token != -1;i++) {
325706f2543Smrg	if (ramdacs[i].token == TIramdac_ID)
326706f2543Smrg	    RamDacIsSupported = TRUE;
327706f2543Smrg    }
328706f2543Smrg
329706f2543Smrg    if (!RamDacIsSupported) {
330706f2543Smrg        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
331706f2543Smrg		"This TI RAMDAC is NOT supported by this driver, aborting\n");
332706f2543Smrg	return NULL;
333706f2543Smrg    }
334706f2543Smrg
335706f2543Smrg    ramdacHelperPtr = RamDacHelperCreateInfoRec();
336706f2543Smrg    switch (TIramdac_ID) {
337706f2543Smrg	case TI3030_RAMDAC:
338706f2543Smrg 	    ramdacHelperPtr->SetBpp = TIramdac3030SetBpp;
339706f2543Smrg    	    ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit;
340706f2543Smrg	    break;
341706f2543Smrg	case TI3026_RAMDAC:
342706f2543Smrg 	    ramdacHelperPtr->SetBpp = TIramdac3026SetBpp;
343706f2543Smrg    	    ramdacHelperPtr->HWCursorInit = TIramdacHWCursorInit;
344706f2543Smrg	    break;
345706f2543Smrg    }
346706f2543Smrg    ramdacPtr->RamDacType = TIramdac_ID;
347706f2543Smrg    ramdacHelperPtr->RamDacType = TIramdac_ID;
348706f2543Smrg    ramdacHelperPtr->Save = TIramdacSave;
349706f2543Smrg    ramdacHelperPtr->Restore = TIramdacRestore;
350706f2543Smrg
351706f2543Smrg    return ramdacHelperPtr;
352706f2543Smrg}
353706f2543Smrg
354706f2543Smrgvoid
355706f2543SmrgTIramdac3026SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
356706f2543Smrg{
357706f2543Smrg    switch (pScrn->bitsPerPixel) {
358706f2543Smrg    case 32:
359706f2543Smrg	/* order is important */
360706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
361706f2543Smrg	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
362706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5c;
363706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
364706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
365706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
366706f2543Smrg	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
367706f2543Smrg	/* 0x2A & 0x2B are reserved */
368706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
369706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
370706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
371706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
372706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
373706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
374706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
375706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
376706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
377706f2543Smrg	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
378706f2543Smrg	if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
379706f2543Smrg	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
380706f2543Smrg	    ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
381706f2543Smrg	    ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
382706f2543Smrg	}
383706f2543Smrg	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
384706f2543Smrg	break;
385706f2543Smrg    case 24:
386706f2543Smrg	/* order is important */
387706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
388706f2543Smrg	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
389706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
390706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
391706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
392706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
393706f2543Smrg	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
394706f2543Smrg	/* 0x2A & 0x2B are reserved */
395706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
396706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
397706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
398706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
399706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
400706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
401706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
402706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
403706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
404706f2543Smrg	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
405706f2543Smrg	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
406706f2543Smrg	break;
407706f2543Smrg    case 16:
408706f2543Smrg	/* order is important */
409706f2543Smrg#if 0
410706f2543Smrg	/* Matrox driver uses this */
411706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
412706f2543Smrg#else
413706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
414706f2543Smrg#endif
415706f2543Smrg	if (pScrn->depth == 16) {
416706f2543Smrg	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
417706f2543Smrg	} else {
418706f2543Smrg	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
419706f2543Smrg	}
420706f2543Smrg#if 0
421706f2543Smrg	/* Matrox driver uses this */
422706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
423706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
424706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
425706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
426706f2543Smrg#else
427706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x54;
428706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
429706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
430706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
431706f2543Smrg#endif
432706f2543Smrg	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
433706f2543Smrg	/* 0x2A & 0x2B are reserved */
434706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
435706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
436706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
437706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
438706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
439706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
440706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
441706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
442706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
443706f2543Smrg	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
444706f2543Smrg	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
445706f2543Smrg	break;
446706f2543Smrg    case 8:
447706f2543Smrg	/* order is important */
448706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
449706f2543Smrg	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
450706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4c;
451706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
452706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
453706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
454706f2543Smrg	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
455706f2543Smrg	/* 0x2A & 0x2B are reserved */
456706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
457706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
458706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
459706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
460706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
461706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
462706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00;
463706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
464706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
465706f2543Smrg	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
466706f2543Smrg	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
467706f2543Smrg	break;
468706f2543Smrg    }
469706f2543Smrg}
470706f2543Smrg
471706f2543Smrgvoid
472706f2543SmrgTIramdac3030SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
473706f2543Smrg{
474706f2543Smrg    switch (pScrn->bitsPerPixel) {
475706f2543Smrg    case 32:
476706f2543Smrg	/* order is important */
477706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
478706f2543Smrg	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
479706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5D;
480706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
481706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
482706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
483706f2543Smrg	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
484706f2543Smrg	/* 0x2A & 0x2B are reserved */
485706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
486706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
487706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
488706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
489706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
490706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
491706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
492706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
493706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
494706f2543Smrg	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
495706f2543Smrg	if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
496706f2543Smrg	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
497706f2543Smrg	    ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
498706f2543Smrg	    ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
499706f2543Smrg	}
500706f2543Smrg	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
501706f2543Smrg	break;
502706f2543Smrg    case 24:
503706f2543Smrg	/* order is important */
504706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
505706f2543Smrg	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
506706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
507706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
508706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
509706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
510706f2543Smrg	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
511706f2543Smrg	/* 0x2A & 0x2B are reserved */
512706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
513706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
514706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
515706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
516706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
517706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
518706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
519706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
520706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
521706f2543Smrg	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
522706f2543Smrg	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
523706f2543Smrg	break;
524706f2543Smrg    case 16:
525706f2543Smrg	/* order is important */
526706f2543Smrg#if 0
527706f2543Smrg	/* Matrox driver uses this */
528706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
529706f2543Smrg#else
530706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
531706f2543Smrg#endif
532706f2543Smrg	if (pScrn->depth == 16) {
533706f2543Smrg	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
534706f2543Smrg	} else {
535706f2543Smrg	    ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
536706f2543Smrg	}
537706f2543Smrg#if 0
538706f2543Smrg	/* Matrox driver uses this */
539706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
540706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
541706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
542706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
543706f2543Smrg#else
544706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x55;
545706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x85;
546706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
547706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
548706f2543Smrg#endif
549706f2543Smrg	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
550706f2543Smrg	/* 0x2A & 0x2B are reserved */
551706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
552706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
553706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
554706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
555706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
556706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
557706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
558706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
559706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
560706f2543Smrg	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
561706f2543Smrg	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
562706f2543Smrg	break;
563706f2543Smrg    case 8:
564706f2543Smrg	/* order is important */
565706f2543Smrg	ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
566706f2543Smrg	ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
567706f2543Smrg	ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4d;
568706f2543Smrg	ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
569706f2543Smrg	ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
570706f2543Smrg	ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
571706f2543Smrg	ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
572706f2543Smrg	/* 0x2A & 0x2B are reserved */
573706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
574706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
575706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
576706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
577706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
578706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
579706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_low] = 0x00;
580706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
581706f2543Smrg	ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
582706f2543Smrg	ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
583706f2543Smrg	ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
584706f2543Smrg	break;
585706f2543Smrg    }
586706f2543Smrg}
587706f2543Smrg
588706f2543Smrgstatic void
589706f2543SmrgTIramdacShowCursor(ScrnInfoPtr pScrn)
590706f2543Smrg{
591706f2543Smrg    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
592706f2543Smrg
593706f2543Smrg    /* Enable cursor - X11 mode */
594706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x03);
595706f2543Smrg}
596706f2543Smrg
597706f2543Smrgstatic void
598706f2543SmrgTIramdacHideCursor(ScrnInfoPtr pScrn)
599706f2543Smrg{
600706f2543Smrg    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
601706f2543Smrg
602706f2543Smrg    /* Disable cursor - X11 mode */
603706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x00);
604706f2543Smrg}
605706f2543Smrg
606706f2543Smrgstatic void
607706f2543SmrgTIramdacSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
608706f2543Smrg{
609706f2543Smrg    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
610706f2543Smrg
611706f2543Smrg    x += 64;
612706f2543Smrg    y += 64;
613706f2543Smrg
614706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XLOW,  0, x & 0xff);
615706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XHIGH, 0, (x >> 8) & 0x0f);
616706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YLOW,  0, y & 0xff);
617706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YHIGH, 0, (y >> 8) & 0x0f);
618706f2543Smrg}
619706f2543Smrg
620706f2543Smrgstatic void
621706f2543SmrgTIramdacSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
622706f2543Smrg{
623706f2543Smrg    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
624706f2543Smrg
625706f2543Smrg    /* Background color */
626706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 1);
627706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x00ff0000) >> 16));
628706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x0000ff00) >>  8));
629706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0,  (bg&0x000000ff)       );
630706f2543Smrg
631706f2543Smrg    /* Foreground color */
632706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 2);
633706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x00ff0000) >> 16));
634706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x0000ff00) >>  8));
635706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0,  (fg&0x000000ff)       );
636706f2543Smrg}
637706f2543Smrg
638706f2543Smrgstatic void
639706f2543SmrgTIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
640706f2543Smrg{
641706f2543Smrg    RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
642706f2543Smrg    int i = 1024;
643706f2543Smrg
644706f2543Smrg    /* reset A9,A8 */
645706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0, 0x00);
646706f2543Smrg    /* reset cursor RAM load address A7..A0 */
647706f2543Smrg    (*ramdacPtr->WriteDAC)(pScrn, TIDAC_INDEX, 0x00, 0x00);
648706f2543Smrg
649706f2543Smrg    while(i--) {
650706f2543Smrg	/* NOT_DONE: might need a delay here */
651706f2543Smrg	(*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_RAM_DATA, 0, *(src++));
652706f2543Smrg    }
653706f2543Smrg}
654706f2543Smrg
655706f2543Smrgstatic Bool
656706f2543SmrgTIramdacUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
657706f2543Smrg{
658706f2543Smrg    return TRUE;
659706f2543Smrg}
660706f2543Smrg
661706f2543Smrgvoid
662706f2543SmrgTIramdacHWCursorInit(xf86CursorInfoPtr infoPtr)
663706f2543Smrg{
664706f2543Smrg    infoPtr->MaxWidth = 64;
665706f2543Smrg    infoPtr->MaxHeight = 64;
666706f2543Smrg    infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
667706f2543Smrg		     HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
668706f2543Smrg		     HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
669706f2543Smrg    infoPtr->SetCursorColors = TIramdacSetCursorColors;
670706f2543Smrg    infoPtr->SetCursorPosition = TIramdacSetCursorPosition;
671706f2543Smrg    infoPtr->LoadCursorImage = TIramdacLoadCursorImage;
672706f2543Smrg    infoPtr->HideCursor = TIramdacHideCursor;
673706f2543Smrg    infoPtr->ShowCursor = TIramdacShowCursor;
674706f2543Smrg    infoPtr->UseHWCursor = TIramdacUseHWCursor;
675706f2543Smrg}
676706f2543Smrg
677706f2543Smrgvoid TIramdacLoadPalette(
678706f2543Smrg    ScrnInfoPtr pScrn,
679706f2543Smrg    int numColors,
680706f2543Smrg    int *indices,
681706f2543Smrg    LOCO *colors,
682706f2543Smrg    VisualPtr pVisual
683706f2543Smrg){
684706f2543Smrg    RamDacRecPtr hwp = RAMDACSCRPTR(pScrn);
685706f2543Smrg    int i, index, shift;
686706f2543Smrg
687706f2543Smrg    if (pScrn->depth == 16) {
688706f2543Smrg    for(i = 0; i < numColors; i++) {
689706f2543Smrg	index = indices[i];
690706f2543Smrg    	(*hwp->WriteAddress)(pScrn, index << 2);
691706f2543Smrg	(*hwp->WriteData)(pScrn, colors[index >> 1].red);
692706f2543Smrg	(*hwp->WriteData)(pScrn, colors[index].green);
693706f2543Smrg	(*hwp->WriteData)(pScrn, colors[index >> 1].blue);
694706f2543Smrg
695706f2543Smrg	if(index <= 31) {
696706f2543Smrg	    (*hwp->WriteAddress)(pScrn, index << 3);
697706f2543Smrg	    (*hwp->WriteData)(pScrn, colors[index].red);
698706f2543Smrg	    (*hwp->WriteData)(pScrn, colors[(index << 1) + 1].green);
699706f2543Smrg	    (*hwp->WriteData)(pScrn, colors[index].blue);
700706f2543Smrg	}
701706f2543Smrg    }
702706f2543Smrg} else {
703706f2543Smrg    shift = (pScrn->depth == 15) ? 3 : 0;
704706f2543Smrg
705706f2543Smrg    for(i = 0; i < numColors; i++) {
706706f2543Smrg	index = indices[i];
707706f2543Smrg    	(*hwp->WriteAddress)(pScrn, index << shift);
708706f2543Smrg	(*hwp->WriteData)(pScrn, colors[index].red);
709706f2543Smrg	(*hwp->WriteData)(pScrn, colors[index].green);
710706f2543Smrg	(*hwp->WriteData)(pScrn, colors[index].blue);
711706f2543Smrg    }
712706f2543Smrg}
713706f2543Smrg}
714706f2543Smrg
715706f2543SmrgTIramdacLoadPaletteProc *TIramdacLoadPaletteWeak(void) {
716706f2543Smrg    return TIramdacLoadPalette;
717706f2543Smrg}
718