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