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 * IBM RAMDAC routines. 25 */ 26 27#ifdef HAVE_XORG_CONFIG_H 28#include <xorg-config.h> 29#endif 30 31#include "xf86.h" 32#include "xf86_OSproc.h" 33 34#include "xf86Cursor.h" 35 36#define INIT_IBM_RAMDAC_INFO 37#include "IBMPriv.h" 38#include "xf86RamDacPriv.h" 39 40#define INITIALFREQERR 100000 41 42unsigned long 43IBMramdac640CalculateMNPCForClock( 44 unsigned long RefClock, /* In 100Hz units */ 45 unsigned long ReqClock, /* In 100Hz units */ 46 char IsPixClock, /* boolean, is this the pixel or the sys clock */ 47 unsigned long MinClock, /* Min VCO rating */ 48 unsigned long MaxClock, /* Max VCO rating */ 49 unsigned long *rM, /* M Out */ 50 unsigned long *rN, /* N Out */ 51 unsigned long *rP, /* Min P In, P Out */ 52 unsigned long *rC /* C Out */ 53) 54{ 55 unsigned long M, N, P, iP = *rP; 56 unsigned long IntRef, VCO, Clock; 57 long freqErr, lowestFreqErr = INITIALFREQERR; 58 unsigned long ActualClock = 0; 59 60 for (N = 0; N <= 63; N++) 61 { 62 IntRef = RefClock / (N + 1); 63 if (IntRef < 10000) 64 break; /* IntRef needs to be >= 1MHz */ 65 for (M = 2; M <= 127; M++) 66 { 67 VCO = IntRef * (M + 1); 68 if ((VCO < MinClock) || (VCO > MaxClock)) 69 continue; 70 for (P = iP; P <= 4; P++) 71 { 72 if (P != 0) 73 Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P); 74 else 75 Clock = (RefClock * (M + 1)) / (N + 1); 76 77 freqErr = (Clock - ReqClock); 78 79 if (freqErr < 0) 80 { 81 /* PixelClock gets rounded up always so monitor reports 82 correct frequency. */ 83 if (IsPixClock) 84 continue; 85 freqErr = -freqErr; 86 } 87 88 if (freqErr < lowestFreqErr) 89 { 90 *rM = M; 91 *rN = N; 92 *rP = P; 93 *rC = (VCO <= 1280000 ? 1 : 2); 94 ActualClock = Clock; 95 96 lowestFreqErr = freqErr; 97 /* Return if we found an exact match */ 98 if (freqErr == 0) 99 return ActualClock; 100 } 101 } 102 } 103 } 104 105 return ActualClock; 106} 107 108unsigned long 109IBMramdac526CalculateMNPCForClock( 110 unsigned long RefClock, /* In 100Hz units */ 111 unsigned long ReqClock, /* In 100Hz units */ 112 char IsPixClock, /* boolean, is this the pixel or the sys clock */ 113 unsigned long MinClock, /* Min VCO rating */ 114 unsigned long MaxClock, /* Max VCO rating */ 115 unsigned long *rM, /* M Out */ 116 unsigned long *rN, /* N Out */ 117 unsigned long *rP, /* Min P In, P Out */ 118 unsigned long *rC /* C Out */ 119) 120{ 121 unsigned long M, N, P, iP = *rP; 122 unsigned long IntRef, VCO, Clock; 123 long freqErr, lowestFreqErr = INITIALFREQERR; 124 unsigned long ActualClock = 0; 125 126 for (N = 0; N <= 63; N++) 127 { 128 IntRef = RefClock / (N + 1); 129 if (IntRef < 10000) 130 break; /* IntRef needs to be >= 1MHz */ 131 for (M = 0; M <= 63; M++) 132 { 133 VCO = IntRef * (M + 1); 134 if ((VCO < MinClock) || (VCO > MaxClock)) 135 continue; 136 for (P = iP; P <= 4; P++) 137 { 138 if (P) 139 Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P); 140 else 141 Clock = VCO; 142 143 freqErr = (Clock - ReqClock); 144 145 if (freqErr < 0) 146 { 147 /* PixelClock gets rounded up always so monitor reports 148 correct frequency. */ 149 if (IsPixClock) 150 continue; 151 freqErr = -freqErr; 152 } 153 154 if (freqErr < lowestFreqErr) 155 { 156 *rM = M; 157 *rN = N; 158 *rP = P; 159 *rC = (VCO <= 1280000 ? 1 : 2); 160 ActualClock = Clock; 161 162 lowestFreqErr = freqErr; 163 /* Return if we found an exact match */ 164 if (freqErr == 0) 165 return ActualClock; 166 } 167 } 168 } 169 } 170 171 return ActualClock; 172} 173 174void 175IBMramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 176 RamDacRegRecPtr ramdacReg) 177{ 178 int i, maxreg, dacreg; 179 180 switch (ramdacPtr->RamDacType) { 181 case IBM640_RAMDAC: 182 maxreg = 0x300; 183 dacreg = 1024; 184 break; 185 default: 186 maxreg = 0x100; 187 dacreg = 768; 188 break; 189 } 190 191 /* Here we pass a short, so that we can evaluate a mask too */ 192 /* So that the mask is the high byte and the data the low byte */ 193 for (i=0;i<maxreg;i++) 194 (*ramdacPtr->WriteDAC) 195 (pScrn, i, (ramdacReg->DacRegs[i] & 0xFF00) >> 8, 196 ramdacReg->DacRegs[i]); 197 198 (*ramdacPtr->WriteAddress)(pScrn, 0); 199 for (i=0;i<dacreg;i++) 200 (*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]); 201} 202 203void 204IBMramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 205 RamDacRegRecPtr ramdacReg) 206{ 207 int i, maxreg, dacreg; 208 209 switch (ramdacPtr->RamDacType) { 210 case IBM640_RAMDAC: 211 maxreg = 0x300; 212 dacreg = 1024; 213 break; 214 default: 215 maxreg = 0x100; 216 dacreg = 768; 217 break; 218 } 219 220 (*ramdacPtr->ReadAddress)(pScrn, 0); 221 for (i=0;i<dacreg;i++) 222 ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn); 223 224 for (i=0;i<maxreg;i++) 225 ramdacReg->DacRegs[i] = (*ramdacPtr->ReadDAC)(pScrn, i); 226} 227 228RamDacHelperRecPtr 229IBMramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs/* , RamDacRecPtr ramdacPtr*/) 230{ 231 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 232 RamDacHelperRecPtr ramdacHelperPtr = NULL; 233 Bool RamDacIsSupported = FALSE; 234 int IBMramdac_ID = -1; 235 int i; 236 unsigned char id, rev, id2, rev2; 237 238 /* read ID and revision */ 239 rev = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_rev); 240 id = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_id); 241 242 /* check if ID and revision are read only */ 243 (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, IBMRGB_rev); 244 (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, IBMRGB_id); 245 rev2 = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_rev); 246 id2 = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_id); 247 248 switch (id) { 249 case 0x30: 250 if (rev == 0xc0) IBMramdac_ID = IBM624_RAMDAC; 251 if (rev == 0x80) IBMramdac_ID = IBM624DB_RAMDAC; 252 break; 253 case 0x12: 254 if (rev == 0x1c) IBMramdac_ID = IBM640_RAMDAC; 255 break; 256 case 0x01: 257 IBMramdac_ID = IBM525_RAMDAC; 258 break; 259 case 0x02: 260 if (rev == 0xf0) IBMramdac_ID = IBM524_RAMDAC; 261 if (rev == 0xe0) IBMramdac_ID = IBM524A_RAMDAC; 262 if (rev == 0xc0) IBMramdac_ID = IBM526_RAMDAC; 263 if (rev == 0x80) IBMramdac_ID = IBM526DB_RAMDAC; 264 break; 265 } 266 267 if (id == 1 || id == 2) { 268 if (id == id2 && rev == rev2) { /* IBM RGB52x found */ 269 /* check for 128bit VRAM -> RGB528 */ 270 if (((*ramdacPtr->ReadDAC)(pScrn, IBMRGB_misc1) & 0x03) == 0x03) { 271 IBMramdac_ID = IBM528_RAMDAC; /* 128bit DAC found */ 272 if (rev == 0xe0) 273 IBMramdac_ID = IBM528A_RAMDAC; 274 } 275 } 276 } 277 278 (*ramdacPtr->WriteDAC)(pScrn, rev, 0, IBMRGB_rev); 279 (*ramdacPtr->WriteDAC)(pScrn, id, 0, IBMRGB_id); 280 281 if (IBMramdac_ID == -1) { 282 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 283 "Cannot determine IBM RAMDAC type, aborting\n"); 284 return NULL; 285 } else { 286 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 287 "Attached RAMDAC is %s\n", IBMramdacDeviceInfo[IBMramdac_ID&0xFFFF].DeviceName); 288 } 289 290 for (i=0;ramdacs[i].token != -1;i++) { 291 if (ramdacs[i].token == IBMramdac_ID) 292 RamDacIsSupported = TRUE; 293 } 294 295 if (!RamDacIsSupported) { 296 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 297 "This IBM RAMDAC is NOT supported by this driver, aborting\n"); 298 return NULL; 299 } 300 301 ramdacHelperPtr = RamDacHelperCreateInfoRec(); 302 switch (IBMramdac_ID) { 303 case IBM526_RAMDAC: 304 case IBM526DB_RAMDAC: 305 ramdacHelperPtr->SetBpp = IBMramdac526SetBpp; 306 ramdacHelperPtr->HWCursorInit = IBMramdac526HWCursorInit; 307 break; 308 case IBM640_RAMDAC: 309 ramdacHelperPtr->SetBpp = IBMramdac640SetBpp; 310 ramdacHelperPtr->HWCursorInit = IBMramdac640HWCursorInit; 311 break; 312 } 313 ramdacPtr->RamDacType = IBMramdac_ID; 314 ramdacHelperPtr->RamDacType = IBMramdac_ID; 315 ramdacHelperPtr->Save = IBMramdacSave; 316 ramdacHelperPtr->Restore = IBMramdacRestore; 317 318 return ramdacHelperPtr; 319} 320 321void 322IBMramdac526SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg) 323{ 324 ramdacReg->DacRegs[IBMRGB_key_control] = 0x00; /* Disable Chroma Key */ 325 326 switch (pScrn->bitsPerPixel) { 327 case 32: 328 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_32BPP; 329 ramdacReg->DacRegs[IBMRGB_32bpp] = B32_DCOL_DIRECT; 330 ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 331 ramdacReg->DacRegs[IBMRGB_16bpp] = 0; 332 ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 333 if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { 334 ramdacReg->DacRegs[IBMRGB_key_control] = 0x01; /* Enable Key */ 335 ramdacReg->DacRegs[IBMRGB_key] = 0xFF; 336 ramdacReg->DacRegs[IBMRGB_key_mask] = 0xFF; 337 } 338 break; 339 case 24: 340 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_24BPP; 341 ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 342 ramdacReg->DacRegs[IBMRGB_24bpp] = B24_DCOL_DIRECT; 343 ramdacReg->DacRegs[IBMRGB_16bpp] = 0; 344 ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 345 break; 346 case 16: 347 if (pScrn->depth == 16) { 348 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP; 349 ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 350 ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 351 ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT|B16_LINEAR | 352 B16_CONTIGUOUS | B16_565; 353 ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 354 } else { 355 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP; 356 ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 357 ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 358 ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT|B16_LINEAR | 359 B16_CONTIGUOUS | B16_555; 360 ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 361 } 362 break; 363 case 8: 364 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_8BPP; 365 ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 366 ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 367 ramdacReg->DacRegs[IBMRGB_16bpp] = 0; 368 ramdacReg->DacRegs[IBMRGB_8bpp] = B8_DCOL_INDIRECT; 369 break; 370 case 4: 371 ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_4BPP; 372 ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 373 ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 374 ramdacReg->DacRegs[IBMRGB_16bpp] = 0; 375 ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 376 } 377} 378 379IBMramdac526SetBppProc *IBMramdac526SetBppWeak(void) { 380 return IBMramdac526SetBpp; 381} 382 383void 384IBMramdac640SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg) 385{ 386 unsigned char bpp = 0x00; 387 unsigned char overlaybpp = 0x00; 388 unsigned char offset = 0x00; 389 unsigned char dispcont = 0x44; 390 391 ramdacReg->DacRegs[RGB640_SER_WID_03_00] = 0x00; 392 ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x00; 393 ramdacReg->DacRegs[RGB640_DIAGS] = 0x07; 394 395 switch (pScrn->depth) { 396 case 8: 397 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x00; 398 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x00; 399 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00; 400 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00; 401 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_16_1; /*16:1 Mux*/ 402 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */ 403 bpp = 0x03; 404 break; 405 case 15: 406 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10; 407 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11; 408 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00; 409 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00; 410 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux*/ 411 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */ 412 bpp = 0x0E; 413 break; 414 case 16: 415 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10; 416 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11; 417 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00; 418 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00; 419 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux*/ 420 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */ 421 bpp = 0x05; 422 break; 423 case 24: 424 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30; 425 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31; 426 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32; 427 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33; 428 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux*/ 429 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */ 430 bpp = 0x09; 431 if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { 432 ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x04; 433 ramdacReg->DacRegs[RGB640_CHROMA_KEY0] = 0xFF; 434 ramdacReg->DacRegs[RGB640_CHROMA_MASK0] = 0xFF; 435 offset = 0x04; 436 overlaybpp = 0x04; 437 dispcont = 0x48; 438 } 439 break; 440 case 30: /* 10 bit dac */ 441 ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30; 442 ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31; 443 ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32; 444 ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33; 445 ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux*/ 446 ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PSIZE10 | 447 IBM640_PCLK_8; /* pll / 8 */ 448 bpp = 0x0D; 449 break; 450 } 451 452 { 453 int i; 454 for (i=0x100;i<0x140;i+=4) { 455 /* Initialize FrameBuffer Window Attribute Table */ 456 ramdacReg->DacRegs[i+0] = bpp; 457 ramdacReg->DacRegs[i+1] = offset; 458 ramdacReg->DacRegs[i+2] = 0x00; 459 ramdacReg->DacRegs[i+3] = 0x00; 460 /* Initialize Overlay Window Attribute Table */ 461 ramdacReg->DacRegs[i+0x100] = overlaybpp; 462 ramdacReg->DacRegs[i+0x101] = 0x00; 463 ramdacReg->DacRegs[i+0x102] = 0x00; 464 ramdacReg->DacRegs[i+0x103] = dispcont; 465 } 466 } 467} 468 469static void 470IBMramdac526ShowCursor(ScrnInfoPtr pScrn) 471{ 472 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 473 474 /* Enable cursor - X11 mode */ 475 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs, 0x00, 0x07); 476} 477 478static void 479IBMramdac640ShowCursor(ScrnInfoPtr pScrn) 480{ 481 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 482 483 /* Enable cursor - mode2 (x11 mode) */ 484 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x0B); 485 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CROSSHAIR_CONTROL, 0x00, 0x00); 486} 487 488static void 489IBMramdac526HideCursor(ScrnInfoPtr pScrn) 490{ 491 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 492 493 /* Disable cursor - X11 mode */ 494 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs, 0x00, 0x24); 495} 496 497static void 498IBMramdac640HideCursor(ScrnInfoPtr pScrn) 499{ 500 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 501 502 /* Disable cursor - mode2 (x11 mode) */ 503 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x08); 504} 505 506static void 507IBMramdac526SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 508{ 509 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 510 511 x += 64; 512 y += 64; 513 514 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_hot_x, 0x00, 0x3f); 515 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_hot_y, 0x00, 0x3f); 516 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_xl, 0x00, x & 0xff); 517 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_xh, 0x00, (x>>8) & 0xf); 518 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_yl, 0x00, y & 0xff); 519 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_yh, 0x00, (y>>8) & 0xf); 520} 521 522static void 523IBMramdac640SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 524{ 525 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 526 527 x += 64; 528 y += 64; 529 530 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_OFFSETX, 0x00, 0x3f); 531 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_OFFSETY, 0x00, 0x3f); 532 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_X_LOW, 0x00, x & 0xff); 533 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_X_HIGH, 0x00, (x>>8) & 0xf); 534 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_Y_LOW, 0x00, y & 0xff); 535 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_Y_HIGH, 0x00, (y>>8) & 0xf); 536} 537 538static void 539IBMramdac526SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 540{ 541 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 542 543 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_r, 0x00, bg >> 16); 544 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_g, 0x00, bg >> 8); 545 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_b, 0x00, bg); 546 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_r, 0x00, fg >> 16); 547 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_g, 0x00, fg >> 8); 548 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_b, 0x00, fg); 549} 550 551static void 552IBMramdac640SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 553{ 554 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 555 556 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_COL0, 0x00, 0); 557 (*ramdacPtr->WriteData)(pScrn, fg>>16); 558 (*ramdacPtr->WriteData)(pScrn, fg>>8); 559 (*ramdacPtr->WriteData)(pScrn, fg); 560 (*ramdacPtr->WriteData)(pScrn, bg>>16); 561 (*ramdacPtr->WriteData)(pScrn, bg>>8); 562 (*ramdacPtr->WriteData)(pScrn, bg); 563 (*ramdacPtr->WriteData)(pScrn, fg>>16); 564 (*ramdacPtr->WriteData)(pScrn, fg>>8); 565 (*ramdacPtr->WriteData)(pScrn, fg); 566 (*ramdacPtr->WriteData)(pScrn, bg>>16); 567 (*ramdacPtr->WriteData)(pScrn, bg>>8); 568 (*ramdacPtr->WriteData)(pScrn, bg); 569} 570 571static void 572IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 573{ 574 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 575 int i; 576 /* 577 * Output the cursor data. The realize function has put the planes into 578 * their correct order, so we can just blast this out. 579 */ 580 for (i = 0; i < 1024; i++) 581 (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_array + i, 0x00, (*src++)); 582} 583 584static void 585IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 586{ 587 RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 588 int i; 589 /* 590 * Output the cursor data. The realize function has put the planes into 591 * their correct order, so we can just blast this out. 592 */ 593 for (i = 0; i < 1024; i++) 594 (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_WRITE + i, 0x00, (*src++)); 595} 596 597static Bool 598IBMramdac526UseHWCursor(ScreenPtr pScr, CursorPtr pCurs) 599{ 600 return TRUE; 601} 602 603static Bool 604IBMramdac640UseHWCursor(ScreenPtr pScr, CursorPtr pCurs) 605{ 606 return TRUE; 607} 608 609void 610IBMramdac526HWCursorInit(xf86CursorInfoPtr infoPtr) 611{ 612 infoPtr->MaxWidth = 64; 613 infoPtr->MaxHeight = 64; 614 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 615 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 616 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; 617 infoPtr->SetCursorColors = IBMramdac526SetCursorColors; 618 infoPtr->SetCursorPosition = IBMramdac526SetCursorPosition; 619 infoPtr->LoadCursorImage = IBMramdac526LoadCursorImage; 620 infoPtr->HideCursor = IBMramdac526HideCursor; 621 infoPtr->ShowCursor = IBMramdac526ShowCursor; 622 infoPtr->UseHWCursor = IBMramdac526UseHWCursor; 623} 624 625void 626IBMramdac640HWCursorInit(xf86CursorInfoPtr infoPtr) 627{ 628 infoPtr->MaxWidth = 64; 629 infoPtr->MaxHeight = 64; 630 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 631 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 632 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; 633 infoPtr->SetCursorColors = IBMramdac640SetCursorColors; 634 infoPtr->SetCursorPosition = IBMramdac640SetCursorPosition; 635 infoPtr->LoadCursorImage = IBMramdac640LoadCursorImage; 636 infoPtr->HideCursor = IBMramdac640HideCursor; 637 infoPtr->ShowCursor = IBMramdac640ShowCursor; 638 infoPtr->UseHWCursor = IBMramdac640UseHWCursor; 639} 640