2 * Copyright 1998 by Alan Hourihane, Wigan, England.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
22 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
24 * Modified from IBM.c to support TI RAMDAC routines
25 * by Jens Owen, <jens@tungstengraphics.com>.
28 #ifdef HAVE_XORG_CONFIG_H
29 #include <xorg-config.h>
33 #include "xf86_OSproc.h"
35 #include "xf86Cursor.h"
37 #define INIT_TI_RAMDAC_INFO
39 #include "xf86RamDacPriv.h"
41 /* The following values are in kHz */
42 #define TI_MIN_VCO_FREQ 110000
43 #define TI_MAX_VCO_FREQ 220000
46 TIramdacCalculateMNPForClock(unsigned long RefClock
, /* In 100Hz units */
47 unsigned long ReqClock
, /* In 100Hz units */
48 char IsPixClock
, /* boolean, is this the pixel or the sys clock */
49 unsigned long MinClock
, /* Min VCO rating */
50 unsigned long MaxClock
, /* Max VCO rating */
51 unsigned long *rM
, /* M Out */
52 unsigned long *rN
, /* N Out */
53 unsigned long *rP
/* Min P In, P Out */
57 unsigned long best_m
= 0, best_n
= 0;
58 double VCO
, IntRef
= (double) RefClock
;
59 double m_err
, inc_m
, calc_m
;
60 unsigned long ActualClock
;
62 /* Make sure that MinClock <= ReqClock <= MaxClock */
63 if (ReqClock
< MinClock
)
65 if (ReqClock
> MaxClock
)
69 * ActualClock = VCO / 2 ^ p
70 * Choose p so that TI_MIN_VCO_FREQ <= VCO <= TI_MAX_VCO_FREQ
71 * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ
72 * we don't have to bother checking for this maximum limit.
74 VCO
= (double) ReqClock
;
75 for (p
= 0; p
< 3 && VCO
< TI_MIN_VCO_FREQ
; (p
)++)
79 * We avoid doing multiplications by ( 65 - n ),
80 * and add an increment instead - this keeps any error small.
82 inc_m
= VCO
/ (IntRef
* 8.0);
84 /* Initial value of calc_m for the loop */
85 calc_m
= inc_m
+ inc_m
+ inc_m
;
87 /* Initial amount of error for an integer - impossibly large */
90 /* Search for the closest INTEGER value of ( 65 - m ) */
91 for (n
= 3; n
<= 25; (n
)++, calc_m
+= inc_m
) {
93 /* Ignore values of ( 65 - m ) which we can't use */
94 if (calc_m
< 3.0 || calc_m
> 64.0)
98 * Pick the closest INTEGER (has smallest fractional part).
99 * The optimizer should clean this up for us.
101 if ((calc_m
- (int) calc_m
) < m_err
) {
102 m_err
= calc_m
- (int) calc_m
;
103 best_m
= (int) calc_m
;
108 /* 65 - ( 65 - x ) = x */
113 /* Now all the calculations can be completed */
114 VCO
= 8.0 * IntRef
* best_m
/ best_n
;
115 ActualClock
= VCO
/ (1 << p
);
117 DebugF("f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n",
118 ActualClock
, VCO
, *rN
, *rM
, *rP
);
124 TIramdacRestore(ScrnInfoPtr pScrn
, RamDacRecPtr ramdacPtr
,
125 RamDacRegRecPtr ramdacReg
)
128 unsigned long status
;
130 /* Here we pass a short, so that we can evaluate a mask too
131 * So that the mask is the high byte and the data the low byte
134 TIRESTORE(TIDAC_latch_ctrl
);
135 TIRESTORE(TIDAC_true_color_ctrl
);
136 TIRESTORE(TIDAC_multiplex_ctrl
);
137 TIRESTORE(TIDAC_clock_select
);
138 TIRESTORE(TIDAC_palette_page
);
139 TIRESTORE(TIDAC_general_ctrl
);
140 TIRESTORE(TIDAC_misc_ctrl
);
141 /* 0x2A & 0x2B are reserved */
142 TIRESTORE(TIDAC_key_over_low
);
143 TIRESTORE(TIDAC_key_over_high
);
144 TIRESTORE(TIDAC_key_red_low
);
145 TIRESTORE(TIDAC_key_red_high
);
146 TIRESTORE(TIDAC_key_green_low
);
147 TIRESTORE(TIDAC_key_green_high
);
148 TIRESTORE(TIDAC_key_blue_low
);
149 TIRESTORE(TIDAC_key_blue_high
);
150 TIRESTORE(TIDAC_key_ctrl
);
151 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_clock_ctrl
, 0, 0x30);
152 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_clock_ctrl
, 0, 0x38);
153 TIRESTORE(TIDAC_clock_ctrl
);
154 TIRESTORE(TIDAC_sense_test
);
155 TIRESTORE(TIDAC_ind_curs_ctrl
);
157 /* only restore clocks if they were valid to begin with */
159 if (ramdacReg
->DacRegs
[TIDAC_PIXEL_VALID
]) {
160 /* Reset pixel clock */
161 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0x22);
162 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_pixel_data
, 0, 0x3c);
164 /* Restore N, M & P values for pixel clocks */
165 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0);
166 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_pixel_data
, 0,
167 ramdacReg
->DacRegs
[TIDAC_PIXEL_N
]);
168 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_pixel_data
, 0,
169 ramdacReg
->DacRegs
[TIDAC_PIXEL_M
]);
170 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_pixel_data
, 0,
171 ramdacReg
->DacRegs
[TIDAC_PIXEL_P
]);
173 /* wait for pixel clock to lock */
176 status
= (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_pll_pixel_data
);
177 } while ((!(status
& 0x40)) && (--i
));
178 if (!(status
& 0x40)) {
179 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
180 "Pixel clock setup timed out\n");
185 if (ramdacReg
->DacRegs
[TIDAC_LOOP_VALID
]) {
186 /* Reset loop clock */
187 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0x22);
188 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_loop_data
, 0, 0x70);
190 /* Restore N, M & P values for pixel clocks */
191 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0);
192 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_loop_data
, 0,
193 ramdacReg
->DacRegs
[TIDAC_LOOP_N
]);
194 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_loop_data
, 0,
195 ramdacReg
->DacRegs
[TIDAC_LOOP_M
]);
196 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_loop_data
, 0,
197 ramdacReg
->DacRegs
[TIDAC_LOOP_P
]);
199 /* wait for loop clock to lock */
202 status
= (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_pll_loop_data
);
203 } while ((!(status
& 0x40)) && (--i
));
204 if (!(status
& 0x40)) {
205 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
206 "Loop clock setup timed out\n");
211 /* restore palette */
212 (*ramdacPtr
->WriteAddress
) (pScrn
, 0);
214 for (i
= 0; i
< 768; i
++)
215 (*ramdacPtr
->WriteData
) (pScrn
, ramdacReg
->DAC
[i
]);
217 (*ramdacPtr
->WriteData
) (pScrn
, 0);
218 (*ramdacPtr
->WriteData
) (pScrn
, 0);
219 (*ramdacPtr
->WriteData
) (pScrn
, 0);
220 for (i
= 0; i
< 765; i
++)
221 (*ramdacPtr
->WriteData
) (pScrn
, 0xff);
226 TIramdacSave(ScrnInfoPtr pScrn
, RamDacRecPtr ramdacPtr
,
227 RamDacRegRecPtr ramdacReg
)
231 (*ramdacPtr
->ReadAddress
) (pScrn
, 0);
232 for (i
= 0; i
< 768; i
++)
233 ramdacReg
->DAC
[i
] = (*ramdacPtr
->ReadData
) (pScrn
);
235 /* Read back N,M and P values for pixel clock */
236 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0);
237 ramdacReg
->DacRegs
[TIDAC_PIXEL_N
] =
238 (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_pll_pixel_data
);
239 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0x11);
240 ramdacReg
->DacRegs
[TIDAC_PIXEL_M
] =
241 (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_pll_pixel_data
);
242 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0x22);
243 ramdacReg
->DacRegs
[TIDAC_PIXEL_P
] =
244 (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_pll_pixel_data
);
246 /* Read back N,M and P values for loop clock */
247 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0);
248 ramdacReg
->DacRegs
[TIDAC_LOOP_N
] =
249 (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_pll_loop_data
);
250 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0x11);
251 ramdacReg
->DacRegs
[TIDAC_LOOP_M
] =
252 (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_pll_loop_data
);
253 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_pll_addr
, 0, 0x22);
254 ramdacReg
->DacRegs
[TIDAC_LOOP_P
] =
255 (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_pll_loop_data
);
257 /* Order is important */
258 TISAVE(TIDAC_latch_ctrl
);
259 TISAVE(TIDAC_true_color_ctrl
);
260 TISAVE(TIDAC_multiplex_ctrl
);
261 TISAVE(TIDAC_clock_select
);
262 TISAVE(TIDAC_palette_page
);
263 TISAVE(TIDAC_general_ctrl
);
264 TISAVE(TIDAC_misc_ctrl
);
265 /* 0x2A & 0x2B are reserved */
266 TISAVE(TIDAC_key_over_low
);
267 TISAVE(TIDAC_key_over_high
);
268 TISAVE(TIDAC_key_red_low
);
269 TISAVE(TIDAC_key_red_high
);
270 TISAVE(TIDAC_key_green_low
);
271 TISAVE(TIDAC_key_green_high
);
272 TISAVE(TIDAC_key_blue_low
);
273 TISAVE(TIDAC_key_blue_high
);
274 TISAVE(TIDAC_key_ctrl
);
275 TISAVE(TIDAC_clock_ctrl
);
276 TISAVE(TIDAC_sense_test
);
277 TISAVE(TIDAC_ind_curs_ctrl
);
281 TIramdacProbe(ScrnInfoPtr pScrn
, RamDacSupportedInfoRecPtr ramdacs
)
283 RamDacRecPtr ramdacPtr
= RAMDACSCRPTR(pScrn
);
284 RamDacHelperRecPtr ramdacHelperPtr
= NULL
;
285 Bool RamDacIsSupported
= FALSE
;
286 int TIramdac_ID
= -1;
288 unsigned char id
, rev
, rev2
, id2
;
290 /* read ID and revision */
291 rev
= (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_rev
);
292 id
= (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_id
);
294 /* check if ID and revision are read only */
295 (*ramdacPtr
->WriteDAC
) (pScrn
, ~rev
, 0, TIDAC_rev
);
296 (*ramdacPtr
->WriteDAC
) (pScrn
, ~id
, 0, TIDAC_id
);
297 rev2
= (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_rev
);
298 id2
= (*ramdacPtr
->ReadDAC
) (pScrn
, TIDAC_id
);
301 case TIDAC_TVP_3030_ID
:
302 if (id
== id2
&& rev
== rev2
) /* check for READ ONLY */
303 TIramdac_ID
= TI3030_RAMDAC
;
305 case TIDAC_TVP_3026_ID
:
306 if (id
== id2
&& rev
== rev2
) /* check for READ ONLY */
307 TIramdac_ID
= TI3026_RAMDAC
;
311 (*ramdacPtr
->WriteDAC
) (pScrn
, rev
, 0, TIDAC_rev
);
312 (*ramdacPtr
->WriteDAC
) (pScrn
, id
, 0, TIDAC_id
);
314 if (TIramdac_ID
== -1) {
315 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
316 "Cannot determine TI RAMDAC type, aborting\n");
320 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
321 "Attached RAMDAC is %s\n",
322 TIramdacDeviceInfo
[TIramdac_ID
& 0xFFFF].DeviceName
);
325 for (i
= 0; ramdacs
[i
].token
!= -1; i
++) {
326 if (ramdacs
[i
].token
== TIramdac_ID
)
327 RamDacIsSupported
= TRUE
;
330 if (!RamDacIsSupported
) {
331 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
,
332 "This TI RAMDAC is NOT supported by this driver, aborting\n");
336 ramdacHelperPtr
= RamDacHelperCreateInfoRec();
337 switch (TIramdac_ID
) {
339 ramdacHelperPtr
->SetBpp
= TIramdac3030SetBpp
;
340 ramdacHelperPtr
->HWCursorInit
= TIramdacHWCursorInit
;
343 ramdacHelperPtr
->SetBpp
= TIramdac3026SetBpp
;
344 ramdacHelperPtr
->HWCursorInit
= TIramdacHWCursorInit
;
347 ramdacPtr
->RamDacType
= TIramdac_ID
;
348 ramdacHelperPtr
->RamDacType
= TIramdac_ID
;
349 ramdacHelperPtr
->Save
= TIramdacSave
;
350 ramdacHelperPtr
->Restore
= TIramdacRestore
;
352 return ramdacHelperPtr
;
356 TIramdac3026SetBpp(ScrnInfoPtr pScrn
, RamDacRegRecPtr ramdacReg
)
358 switch (pScrn
->bitsPerPixel
) {
360 /* order is important */
361 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x06;
362 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x46;
363 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x5c;
364 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x05;
365 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
366 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x10;
367 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x3C;
368 /* 0x2A & 0x2B are reserved */
369 ramdacReg
->DacRegs
[TIDAC_key_over_low
] = 0xFF;
370 ramdacReg
->DacRegs
[TIDAC_key_over_high
] = 0xFF;
371 ramdacReg
->DacRegs
[TIDAC_key_red_low
] = 0xFF;
372 ramdacReg
->DacRegs
[TIDAC_key_red_high
] = 0xFF;
373 ramdacReg
->DacRegs
[TIDAC_key_green_low
] = 0xFF;
374 ramdacReg
->DacRegs
[TIDAC_key_green_high
] = 0xFF;
375 ramdacReg
->DacRegs
[TIDAC_key_blue_low
] = 0xFF;
376 ramdacReg
->DacRegs
[TIDAC_key_blue_high
] = 0x00;
377 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x10;
378 ramdacReg
->DacRegs
[TIDAC_sense_test
] = 0x00;
379 if (pScrn
->overlayFlags
& OVERLAY_8_32_PLANAR
) {
380 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x06;
381 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x3C;
382 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x01;
384 ramdacReg
->DacRegs
[TIDAC_ind_curs_ctrl
] = 0x00;
387 /* order is important */
388 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x06;
389 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x56;
390 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x58;
391 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x25;
392 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
393 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x00;
394 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x2C;
395 /* 0x2A & 0x2B are reserved */
396 ramdacReg
->DacRegs
[TIDAC_key_over_low
] = 0xFF;
397 ramdacReg
->DacRegs
[TIDAC_key_over_high
] = 0xFF;
398 ramdacReg
->DacRegs
[TIDAC_key_red_low
] = 0xFF;
399 ramdacReg
->DacRegs
[TIDAC_key_red_high
] = 0xFF;
400 ramdacReg
->DacRegs
[TIDAC_key_green_low
] = 0xFF;
401 ramdacReg
->DacRegs
[TIDAC_key_green_high
] = 0xFF;
402 ramdacReg
->DacRegs
[TIDAC_key_blue_low
] = 0xFF;
403 ramdacReg
->DacRegs
[TIDAC_key_blue_high
] = 0x00;
404 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x10;
405 ramdacReg
->DacRegs
[TIDAC_sense_test
] = 0x00;
406 ramdacReg
->DacRegs
[TIDAC_ind_curs_ctrl
] = 0x00;
409 /* order is important */
411 /* Matrox driver uses this */
412 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x07;
414 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x06;
416 if (pScrn
->depth
== 16) {
417 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x45;
420 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x44;
423 /* Matrox driver uses this */
424 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x50;
425 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x15;
426 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
427 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x00;
429 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x54;
430 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x05;
431 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
432 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x10;
434 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x2C;
435 /* 0x2A & 0x2B are reserved */
436 ramdacReg
->DacRegs
[TIDAC_key_over_low
] = 0xFF;
437 ramdacReg
->DacRegs
[TIDAC_key_over_high
] = 0xFF;
438 ramdacReg
->DacRegs
[TIDAC_key_red_low
] = 0xFF;
439 ramdacReg
->DacRegs
[TIDAC_key_red_high
] = 0xFF;
440 ramdacReg
->DacRegs
[TIDAC_key_green_low
] = 0xFF;
441 ramdacReg
->DacRegs
[TIDAC_key_green_high
] = 0xFF;
442 ramdacReg
->DacRegs
[TIDAC_key_blue_low
] = 0xFF;
443 ramdacReg
->DacRegs
[TIDAC_key_blue_high
] = 0x00;
444 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x10;
445 ramdacReg
->DacRegs
[TIDAC_sense_test
] = 0x00;
446 ramdacReg
->DacRegs
[TIDAC_ind_curs_ctrl
] = 0x00;
449 /* order is important */
450 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x06;
451 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x80;
452 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x4c;
453 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x05;
454 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
455 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x10;
456 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x1C;
457 /* 0x2A & 0x2B are reserved */
458 ramdacReg
->DacRegs
[TIDAC_key_over_low
] = 0xFF;
459 ramdacReg
->DacRegs
[TIDAC_key_over_high
] = 0xFF;
460 ramdacReg
->DacRegs
[TIDAC_key_red_low
] = 0xFF;
461 ramdacReg
->DacRegs
[TIDAC_key_red_high
] = 0xFF;
462 ramdacReg
->DacRegs
[TIDAC_key_green_low
] = 0xFF;
463 ramdacReg
->DacRegs
[TIDAC_key_green_high
] = 0xFF;
464 ramdacReg
->DacRegs
[TIDAC_key_blue_low
] = 0x00;
465 ramdacReg
->DacRegs
[TIDAC_key_blue_high
] = 0x00;
466 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x00;
467 ramdacReg
->DacRegs
[TIDAC_sense_test
] = 0x00;
468 ramdacReg
->DacRegs
[TIDAC_ind_curs_ctrl
] = 0x00;
474 TIramdac3030SetBpp(ScrnInfoPtr pScrn
, RamDacRegRecPtr ramdacReg
)
476 switch (pScrn
->bitsPerPixel
) {
478 /* order is important */
479 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x06;
480 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x46;
481 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x5D;
482 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x05;
483 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
484 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x10;
485 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x3C;
486 /* 0x2A & 0x2B are reserved */
487 ramdacReg
->DacRegs
[TIDAC_key_over_low
] = 0xFF;
488 ramdacReg
->DacRegs
[TIDAC_key_over_high
] = 0xFF;
489 ramdacReg
->DacRegs
[TIDAC_key_red_low
] = 0xFF;
490 ramdacReg
->DacRegs
[TIDAC_key_red_high
] = 0xFF;
491 ramdacReg
->DacRegs
[TIDAC_key_green_low
] = 0xFF;
492 ramdacReg
->DacRegs
[TIDAC_key_green_high
] = 0xFF;
493 ramdacReg
->DacRegs
[TIDAC_key_blue_low
] = 0xFF;
494 ramdacReg
->DacRegs
[TIDAC_key_blue_high
] = 0x00;
495 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x10;
496 ramdacReg
->DacRegs
[TIDAC_sense_test
] = 0x00;
497 if (pScrn
->overlayFlags
& OVERLAY_8_32_PLANAR
) {
498 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x06;
499 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x3C;
500 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x01;
502 ramdacReg
->DacRegs
[TIDAC_ind_curs_ctrl
] = 0x00;
505 /* order is important */
506 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x06;
507 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x56;
508 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x58;
509 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x25;
510 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
511 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x00;
512 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x2C;
513 /* 0x2A & 0x2B are reserved */
514 ramdacReg
->DacRegs
[TIDAC_key_over_low
] = 0xFF;
515 ramdacReg
->DacRegs
[TIDAC_key_over_high
] = 0xFF;
516 ramdacReg
->DacRegs
[TIDAC_key_red_low
] = 0xFF;
517 ramdacReg
->DacRegs
[TIDAC_key_red_high
] = 0xFF;
518 ramdacReg
->DacRegs
[TIDAC_key_green_low
] = 0xFF;
519 ramdacReg
->DacRegs
[TIDAC_key_green_high
] = 0xFF;
520 ramdacReg
->DacRegs
[TIDAC_key_blue_low
] = 0xFF;
521 ramdacReg
->DacRegs
[TIDAC_key_blue_high
] = 0x00;
522 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x10;
523 ramdacReg
->DacRegs
[TIDAC_sense_test
] = 0x00;
524 ramdacReg
->DacRegs
[TIDAC_ind_curs_ctrl
] = 0x00;
527 /* order is important */
529 /* Matrox driver uses this */
530 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x07;
532 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x06;
534 if (pScrn
->depth
== 16) {
535 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x45;
538 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x44;
541 /* Matrox driver uses this */
542 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x50;
543 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x15;
544 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
545 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x00;
547 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x55;
548 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x85;
549 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
550 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x10;
552 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x2C;
553 /* 0x2A & 0x2B are reserved */
554 ramdacReg
->DacRegs
[TIDAC_key_over_low
] = 0xFF;
555 ramdacReg
->DacRegs
[TIDAC_key_over_high
] = 0xFF;
556 ramdacReg
->DacRegs
[TIDAC_key_red_low
] = 0xFF;
557 ramdacReg
->DacRegs
[TIDAC_key_red_high
] = 0xFF;
558 ramdacReg
->DacRegs
[TIDAC_key_green_low
] = 0xFF;
559 ramdacReg
->DacRegs
[TIDAC_key_green_high
] = 0xFF;
560 ramdacReg
->DacRegs
[TIDAC_key_blue_low
] = 0xFF;
561 ramdacReg
->DacRegs
[TIDAC_key_blue_high
] = 0x00;
562 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x10;
563 ramdacReg
->DacRegs
[TIDAC_sense_test
] = 0x00;
564 ramdacReg
->DacRegs
[TIDAC_ind_curs_ctrl
] = 0x00;
567 /* order is important */
568 ramdacReg
->DacRegs
[TIDAC_latch_ctrl
] = 0x06;
569 ramdacReg
->DacRegs
[TIDAC_true_color_ctrl
] = 0x80;
570 ramdacReg
->DacRegs
[TIDAC_multiplex_ctrl
] = 0x4d;
571 ramdacReg
->DacRegs
[TIDAC_clock_select
] = 0x05;
572 ramdacReg
->DacRegs
[TIDAC_palette_page
] = 0x00;
573 ramdacReg
->DacRegs
[TIDAC_general_ctrl
] = 0x10;
574 ramdacReg
->DacRegs
[TIDAC_misc_ctrl
] = 0x1C;
575 /* 0x2A & 0x2B are reserved */
576 ramdacReg
->DacRegs
[TIDAC_key_over_low
] = 0xFF;
577 ramdacReg
->DacRegs
[TIDAC_key_over_high
] = 0xFF;
578 ramdacReg
->DacRegs
[TIDAC_key_red_low
] = 0xFF;
579 ramdacReg
->DacRegs
[TIDAC_key_red_high
] = 0xFF;
580 ramdacReg
->DacRegs
[TIDAC_key_green_low
] = 0xFF;
581 ramdacReg
->DacRegs
[TIDAC_key_green_high
] = 0xFF;
582 ramdacReg
->DacRegs
[TIDAC_key_blue_low
] = 0x00;
583 ramdacReg
->DacRegs
[TIDAC_key_blue_high
] = 0x00;
584 ramdacReg
->DacRegs
[TIDAC_key_ctrl
] = 0x00;
585 ramdacReg
->DacRegs
[TIDAC_sense_test
] = 0x00;
586 ramdacReg
->DacRegs
[TIDAC_ind_curs_ctrl
] = 0x00;
592 TIramdacShowCursor(ScrnInfoPtr pScrn
)
594 RamDacRecPtr ramdacPtr
= RAMDACSCRPTR(pScrn
);
596 /* Enable cursor - X11 mode */
597 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_ind_curs_ctrl
, 0, 0x03);
601 TIramdacHideCursor(ScrnInfoPtr pScrn
)
603 RamDacRecPtr ramdacPtr
= RAMDACSCRPTR(pScrn
);
605 /* Disable cursor - X11 mode */
606 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_ind_curs_ctrl
, 0, 0x00);
610 TIramdacSetCursorPosition(ScrnInfoPtr pScrn
, int x
, int y
)
612 RamDacRecPtr ramdacPtr
= RAMDACSCRPTR(pScrn
);
617 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_XLOW
, 0, x
& 0xff);
618 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_XHIGH
, 0, (x
>> 8) & 0x0f);
619 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_YLOW
, 0, y
& 0xff);
620 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_YHIGH
, 0, (y
>> 8) & 0x0f);
624 TIramdacSetCursorColors(ScrnInfoPtr pScrn
, int bg
, int fg
)
626 RamDacRecPtr ramdacPtr
= RAMDACSCRPTR(pScrn
);
628 /* Background color */
629 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_WRITE_ADDR
, 0, 1);
630 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_COLOR
, 0,
631 ((bg
& 0x00ff0000) >> 16));
632 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_COLOR
, 0,
633 ((bg
& 0x0000ff00) >> 8));
634 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_COLOR
, 0, (bg
& 0x000000ff));
636 /* Foreground color */
637 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_WRITE_ADDR
, 0, 2);
638 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_COLOR
, 0,
639 ((fg
& 0x00ff0000) >> 16));
640 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_COLOR
, 0,
641 ((fg
& 0x0000ff00) >> 8));
642 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_COLOR
, 0, (fg
& 0x000000ff));
646 TIramdacLoadCursorImage(ScrnInfoPtr pScrn
, unsigned char *src
)
648 RamDacRecPtr ramdacPtr
= RAMDACSCRPTR(pScrn
);
652 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_ind_curs_ctrl
, 0, 0x00);
653 /* reset cursor RAM load address A7..A0 */
654 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_INDEX
, 0x00, 0x00);
657 /* NOT_DONE: might need a delay here */
658 (*ramdacPtr
->WriteDAC
) (pScrn
, TIDAC_CURS_RAM_DATA
, 0, *(src
++));
663 TIramdacUseHWCursor(ScreenPtr pScr
, CursorPtr pCurs
)
669 TIramdacHWCursorInit(xf86CursorInfoPtr infoPtr
)
671 infoPtr
->MaxWidth
= 64;
672 infoPtr
->MaxHeight
= 64;
673 infoPtr
->Flags
= HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
|
674 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
|
675 HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED
;
676 infoPtr
->SetCursorColors
= TIramdacSetCursorColors
;
677 infoPtr
->SetCursorPosition
= TIramdacSetCursorPosition
;
678 infoPtr
->LoadCursorImage
= TIramdacLoadCursorImage
;
679 infoPtr
->HideCursor
= TIramdacHideCursor
;
680 infoPtr
->ShowCursor
= TIramdacShowCursor
;
681 infoPtr
->UseHWCursor
= TIramdacUseHWCursor
;
685 TIramdacLoadPalette(ScrnInfoPtr pScrn
,
687 int *indices
, LOCO
* colors
, VisualPtr pVisual
)
689 RamDacRecPtr hwp
= RAMDACSCRPTR(pScrn
);
692 if (pScrn
->depth
== 16) {
693 for (i
= 0; i
< numColors
; i
++) {
695 (*hwp
->WriteAddress
) (pScrn
, index
<< 2);
696 (*hwp
->WriteData
) (pScrn
, colors
[index
>> 1].red
);
697 (*hwp
->WriteData
) (pScrn
, colors
[index
].green
);
698 (*hwp
->WriteData
) (pScrn
, colors
[index
>> 1].blue
);
701 (*hwp
->WriteAddress
) (pScrn
, index
<< 3);
702 (*hwp
->WriteData
) (pScrn
, colors
[index
].red
);
703 (*hwp
->WriteData
) (pScrn
, colors
[(index
<< 1) + 1].green
);
704 (*hwp
->WriteData
) (pScrn
, colors
[index
].blue
);
709 shift
= (pScrn
->depth
== 15) ? 3 : 0;
711 for (i
= 0; i
< numColors
; i
++) {
713 (*hwp
->WriteAddress
) (pScrn
, index
<< shift
);
714 (*hwp
->WriteData
) (pScrn
, colors
[index
].red
);
715 (*hwp
->WriteData
) (pScrn
, colors
[index
].green
);
716 (*hwp
->WriteData
) (pScrn
, colors
[index
].blue
);
721 TIramdacLoadPaletteProc
*
722 TIramdacLoadPaletteWeak(void)
724 return TIramdacLoadPalette
;