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 * IBM RAMDAC routines. 25706f2543Smrg */ 26706f2543Smrg 27706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 28706f2543Smrg#include <xorg-config.h> 29706f2543Smrg#endif 30706f2543Smrg 31706f2543Smrg#include "xf86.h" 32706f2543Smrg#include "xf86_OSproc.h" 33706f2543Smrg 34706f2543Smrg#include "xf86Cursor.h" 35706f2543Smrg 36706f2543Smrg#define INIT_IBM_RAMDAC_INFO 37706f2543Smrg#include "IBMPriv.h" 38706f2543Smrg#include "xf86RamDacPriv.h" 39706f2543Smrg 40706f2543Smrg#define INITIALFREQERR 100000 41706f2543Smrg 42706f2543Smrgunsigned long 43706f2543SmrgIBMramdac640CalculateMNPCForClock( 44706f2543Smrg unsigned long RefClock, /* In 100Hz units */ 45706f2543Smrg unsigned long ReqClock, /* In 100Hz units */ 46706f2543Smrg char IsPixClock, /* boolean, is this the pixel or the sys clock */ 47706f2543Smrg unsigned long MinClock, /* Min VCO rating */ 48706f2543Smrg unsigned long MaxClock, /* Max VCO rating */ 49706f2543Smrg unsigned long *rM, /* M Out */ 50706f2543Smrg unsigned long *rN, /* N Out */ 51706f2543Smrg unsigned long *rP, /* Min P In, P Out */ 52706f2543Smrg unsigned long *rC /* C Out */ 53706f2543Smrg) 54706f2543Smrg{ 55706f2543Smrg unsigned long M, N, P, iP = *rP; 56706f2543Smrg unsigned long IntRef, VCO, Clock; 57706f2543Smrg long freqErr, lowestFreqErr = INITIALFREQERR; 58706f2543Smrg unsigned long ActualClock = 0; 59706f2543Smrg 60706f2543Smrg for (N = 0; N <= 63; N++) 61706f2543Smrg { 62706f2543Smrg IntRef = RefClock / (N + 1); 63706f2543Smrg if (IntRef < 10000) 64706f2543Smrg break; /* IntRef needs to be >= 1MHz */ 65706f2543Smrg for (M = 2; M <= 127; M++) 66706f2543Smrg { 67706f2543Smrg VCO = IntRef * (M + 1); 68706f2543Smrg if ((VCO < MinClock) || (VCO > MaxClock)) 69706f2543Smrg continue; 70706f2543Smrg for (P = iP; P <= 4; P++) 71706f2543Smrg { 72706f2543Smrg if (P != 0) 73706f2543Smrg Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P); 74706f2543Smrg else 75706f2543Smrg Clock = (RefClock * (M + 1)) / (N + 1); 76706f2543Smrg 77706f2543Smrg freqErr = (Clock - ReqClock); 78706f2543Smrg 79706f2543Smrg if (freqErr < 0) 80706f2543Smrg { 81706f2543Smrg /* PixelClock gets rounded up always so monitor reports 82706f2543Smrg correct frequency. */ 83706f2543Smrg if (IsPixClock) 84706f2543Smrg continue; 85706f2543Smrg freqErr = -freqErr; 86706f2543Smrg } 87706f2543Smrg 88706f2543Smrg if (freqErr < lowestFreqErr) 89706f2543Smrg { 90706f2543Smrg *rM = M; 91706f2543Smrg *rN = N; 92706f2543Smrg *rP = P; 93706f2543Smrg *rC = (VCO <= 1280000 ? 1 : 2); 94706f2543Smrg ActualClock = Clock; 95706f2543Smrg 96706f2543Smrg lowestFreqErr = freqErr; 97706f2543Smrg /* Return if we found an exact match */ 98706f2543Smrg if (freqErr == 0) 99706f2543Smrg return ActualClock; 100706f2543Smrg } 101706f2543Smrg } 102706f2543Smrg } 103706f2543Smrg } 104706f2543Smrg 105706f2543Smrg return ActualClock; 106706f2543Smrg} 107706f2543Smrg 108706f2543Smrgunsigned long 109706f2543SmrgIBMramdac526CalculateMNPCForClock( 110706f2543Smrg unsigned long RefClock, /* In 100Hz units */ 111706f2543Smrg unsigned long ReqClock, /* In 100Hz units */ 112706f2543Smrg char IsPixClock, /* boolean, is this the pixel or the sys clock */ 113706f2543Smrg unsigned long MinClock, /* Min VCO rating */ 114706f2543Smrg unsigned long MaxClock, /* Max VCO rating */ 115706f2543Smrg unsigned long *rM, /* M Out */ 116706f2543Smrg unsigned long *rN, /* N Out */ 117706f2543Smrg unsigned long *rP, /* Min P In, P Out */ 118706f2543Smrg unsigned long *rC /* C Out */ 119706f2543Smrg) 120706f2543Smrg{ 121706f2543Smrg unsigned long M, N, P, iP = *rP; 122706f2543Smrg unsigned long IntRef, VCO, Clock; 123706f2543Smrg long freqErr, lowestFreqErr = INITIALFREQERR; 124706f2543Smrg unsigned long ActualClock = 0; 125706f2543Smrg 126706f2543Smrg for (N = 0; N <= 63; N++) 127706f2543Smrg { 128706f2543Smrg IntRef = RefClock / (N + 1); 129706f2543Smrg if (IntRef < 10000) 130706f2543Smrg break; /* IntRef needs to be >= 1MHz */ 131706f2543Smrg for (M = 0; M <= 63; M++) 132706f2543Smrg { 133706f2543Smrg VCO = IntRef * (M + 1); 134706f2543Smrg if ((VCO < MinClock) || (VCO > MaxClock)) 135706f2543Smrg continue; 136706f2543Smrg for (P = iP; P <= 4; P++) 137706f2543Smrg { 138706f2543Smrg if (P) 139706f2543Smrg Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P); 140706f2543Smrg else 141706f2543Smrg Clock = VCO; 142706f2543Smrg 143706f2543Smrg freqErr = (Clock - ReqClock); 144706f2543Smrg 145706f2543Smrg if (freqErr < 0) 146706f2543Smrg { 147706f2543Smrg /* PixelClock gets rounded up always so monitor reports 148706f2543Smrg correct frequency. */ 149706f2543Smrg if (IsPixClock) 150706f2543Smrg continue; 151706f2543Smrg freqErr = -freqErr; 152706f2543Smrg } 153706f2543Smrg 154706f2543Smrg if (freqErr < lowestFreqErr) 155706f2543Smrg { 156706f2543Smrg *rM = M; 157706f2543Smrg *rN = N; 158706f2543Smrg *rP = P; 159706f2543Smrg *rC = (VCO <= 1280000 ? 1 : 2); 160706f2543Smrg ActualClock = Clock; 161706f2543Smrg 162706f2543Smrg lowestFreqErr = freqErr; 163706f2543Smrg /* Return if we found an exact match */ 164706f2543Smrg if (freqErr == 0) 165706f2543Smrg return ActualClock; 166706f2543Smrg } 167706f2543Smrg } 168706f2543Smrg } 169706f2543Smrg } 170706f2543Smrg 171706f2543Smrg return ActualClock; 172706f2543Smrg} 173706f2543Smrg 174706f2543Smrgvoid 175706f2543SmrgIBMramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 176706f2543Smrg RamDacRegRecPtr ramdacReg) 177706f2543Smrg{ 178706f2543Smrg int i, maxreg, dacreg; 179706f2543Smrg 180706f2543Smrg switch (ramdacPtr->RamDacType) { 181706f2543Smrg case IBM640_RAMDAC: 182706f2543Smrg maxreg = 0x300; 183706f2543Smrg dacreg = 1024; 184706f2543Smrg break; 185706f2543Smrg default: 186706f2543Smrg maxreg = 0x100; 187706f2543Smrg dacreg = 768; 188706f2543Smrg break; 189706f2543Smrg } 190706f2543Smrg 191706f2543Smrg /* Here we pass a short, so that we can evaluate a mask too */ 192706f2543Smrg /* So that the mask is the high byte and the data the low byte */ 193706f2543Smrg for (i=0;i<maxreg;i++) 194706f2543Smrg (*ramdacPtr->WriteDAC) 195706f2543Smrg (pScrn, i, (ramdacReg->DacRegs[i] & 0xFF00) >> 8, 196706f2543Smrg ramdacReg->DacRegs[i]); 197706f2543Smrg 198706f2543Smrg (*ramdacPtr->WriteAddress)(pScrn, 0); 199706f2543Smrg for (i=0;i<dacreg;i++) 200706f2543Smrg (*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]); 201706f2543Smrg} 202706f2543Smrg 203706f2543Smrgvoid 204706f2543SmrgIBMramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr, 205706f2543Smrg RamDacRegRecPtr ramdacReg) 206706f2543Smrg{ 207706f2543Smrg int i, maxreg, dacreg; 208706f2543Smrg 209706f2543Smrg switch (ramdacPtr->RamDacType) { 210706f2543Smrg case IBM640_RAMDAC: 211706f2543Smrg maxreg = 0x300; 212706f2543Smrg dacreg = 1024; 213706f2543Smrg break; 214706f2543Smrg default: 215706f2543Smrg maxreg = 0x100; 216706f2543Smrg dacreg = 768; 217706f2543Smrg break; 218706f2543Smrg } 219706f2543Smrg 220706f2543Smrg (*ramdacPtr->ReadAddress)(pScrn, 0); 221706f2543Smrg for (i=0;i<dacreg;i++) 222706f2543Smrg ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn); 223706f2543Smrg 224706f2543Smrg for (i=0;i<maxreg;i++) 225706f2543Smrg ramdacReg->DacRegs[i] = (*ramdacPtr->ReadDAC)(pScrn, i); 226706f2543Smrg} 227706f2543Smrg 228706f2543SmrgRamDacHelperRecPtr 229706f2543SmrgIBMramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs/* , RamDacRecPtr ramdacPtr*/) 230706f2543Smrg{ 231706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 232706f2543Smrg RamDacHelperRecPtr ramdacHelperPtr = NULL; 233706f2543Smrg Bool RamDacIsSupported = FALSE; 234706f2543Smrg int IBMramdac_ID = -1; 235706f2543Smrg int i; 236706f2543Smrg unsigned char id, rev, id2, rev2; 237706f2543Smrg 238706f2543Smrg /* read ID and revision */ 239706f2543Smrg rev = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_rev); 240706f2543Smrg id = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_id); 241706f2543Smrg 242706f2543Smrg /* check if ID and revision are read only */ 243706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, IBMRGB_rev); 244706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, IBMRGB_id); 245706f2543Smrg rev2 = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_rev); 246706f2543Smrg id2 = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_id); 247706f2543Smrg 248706f2543Smrg switch (id) { 249706f2543Smrg case 0x30: 250706f2543Smrg if (rev == 0xc0) IBMramdac_ID = IBM624_RAMDAC; 251706f2543Smrg if (rev == 0x80) IBMramdac_ID = IBM624DB_RAMDAC; 252706f2543Smrg break; 253706f2543Smrg case 0x12: 254706f2543Smrg if (rev == 0x1c) IBMramdac_ID = IBM640_RAMDAC; 255706f2543Smrg break; 256706f2543Smrg case 0x01: 257706f2543Smrg IBMramdac_ID = IBM525_RAMDAC; 258706f2543Smrg break; 259706f2543Smrg case 0x02: 260706f2543Smrg if (rev == 0xf0) IBMramdac_ID = IBM524_RAMDAC; 261706f2543Smrg if (rev == 0xe0) IBMramdac_ID = IBM524A_RAMDAC; 262706f2543Smrg if (rev == 0xc0) IBMramdac_ID = IBM526_RAMDAC; 263706f2543Smrg if (rev == 0x80) IBMramdac_ID = IBM526DB_RAMDAC; 264706f2543Smrg break; 265706f2543Smrg } 266706f2543Smrg 267706f2543Smrg if (id == 1 || id == 2) { 268706f2543Smrg if (id == id2 && rev == rev2) { /* IBM RGB52x found */ 269706f2543Smrg /* check for 128bit VRAM -> RGB528 */ 270706f2543Smrg if (((*ramdacPtr->ReadDAC)(pScrn, IBMRGB_misc1) & 0x03) == 0x03) { 271706f2543Smrg IBMramdac_ID = IBM528_RAMDAC; /* 128bit DAC found */ 272706f2543Smrg if (rev == 0xe0) 273706f2543Smrg IBMramdac_ID = IBM528A_RAMDAC; 274706f2543Smrg } 275706f2543Smrg } 276706f2543Smrg } 277706f2543Smrg 278706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, rev, 0, IBMRGB_rev); 279706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, id, 0, IBMRGB_id); 280706f2543Smrg 281706f2543Smrg if (IBMramdac_ID == -1) { 282706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 283706f2543Smrg "Cannot determine IBM RAMDAC type, aborting\n"); 284706f2543Smrg return NULL; 285706f2543Smrg } else { 286706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 287706f2543Smrg "Attached RAMDAC is %s\n", IBMramdacDeviceInfo[IBMramdac_ID&0xFFFF].DeviceName); 288706f2543Smrg } 289706f2543Smrg 290706f2543Smrg for (i=0;ramdacs[i].token != -1;i++) { 291706f2543Smrg if (ramdacs[i].token == IBMramdac_ID) 292706f2543Smrg RamDacIsSupported = TRUE; 293706f2543Smrg } 294706f2543Smrg 295706f2543Smrg if (!RamDacIsSupported) { 296706f2543Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 297706f2543Smrg "This IBM RAMDAC is NOT supported by this driver, aborting\n"); 298706f2543Smrg return NULL; 299706f2543Smrg } 300706f2543Smrg 301706f2543Smrg ramdacHelperPtr = RamDacHelperCreateInfoRec(); 302706f2543Smrg switch (IBMramdac_ID) { 303706f2543Smrg case IBM526_RAMDAC: 304706f2543Smrg case IBM526DB_RAMDAC: 305706f2543Smrg ramdacHelperPtr->SetBpp = IBMramdac526SetBpp; 306706f2543Smrg ramdacHelperPtr->HWCursorInit = IBMramdac526HWCursorInit; 307706f2543Smrg break; 308706f2543Smrg case IBM640_RAMDAC: 309706f2543Smrg ramdacHelperPtr->SetBpp = IBMramdac640SetBpp; 310706f2543Smrg ramdacHelperPtr->HWCursorInit = IBMramdac640HWCursorInit; 311706f2543Smrg break; 312706f2543Smrg } 313706f2543Smrg ramdacPtr->RamDacType = IBMramdac_ID; 314706f2543Smrg ramdacHelperPtr->RamDacType = IBMramdac_ID; 315706f2543Smrg ramdacHelperPtr->Save = IBMramdacSave; 316706f2543Smrg ramdacHelperPtr->Restore = IBMramdacRestore; 317706f2543Smrg 318706f2543Smrg return ramdacHelperPtr; 319706f2543Smrg} 320706f2543Smrg 321706f2543Smrgvoid 322706f2543SmrgIBMramdac526SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg) 323706f2543Smrg{ 324706f2543Smrg ramdacReg->DacRegs[IBMRGB_key_control] = 0x00; /* Disable Chroma Key */ 325706f2543Smrg 326706f2543Smrg switch (pScrn->bitsPerPixel) { 327706f2543Smrg case 32: 328706f2543Smrg ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_32BPP; 329706f2543Smrg ramdacReg->DacRegs[IBMRGB_32bpp] = B32_DCOL_DIRECT; 330706f2543Smrg ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 331706f2543Smrg ramdacReg->DacRegs[IBMRGB_16bpp] = 0; 332706f2543Smrg ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 333706f2543Smrg if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { 334706f2543Smrg ramdacReg->DacRegs[IBMRGB_key_control] = 0x01; /* Enable Key */ 335706f2543Smrg ramdacReg->DacRegs[IBMRGB_key] = 0xFF; 336706f2543Smrg ramdacReg->DacRegs[IBMRGB_key_mask] = 0xFF; 337706f2543Smrg } 338706f2543Smrg break; 339706f2543Smrg case 24: 340706f2543Smrg ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_24BPP; 341706f2543Smrg ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 342706f2543Smrg ramdacReg->DacRegs[IBMRGB_24bpp] = B24_DCOL_DIRECT; 343706f2543Smrg ramdacReg->DacRegs[IBMRGB_16bpp] = 0; 344706f2543Smrg ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 345706f2543Smrg break; 346706f2543Smrg case 16: 347706f2543Smrg if (pScrn->depth == 16) { 348706f2543Smrg ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP; 349706f2543Smrg ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 350706f2543Smrg ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 351706f2543Smrg ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT|B16_LINEAR | 352706f2543Smrg B16_CONTIGUOUS | B16_565; 353706f2543Smrg ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 354706f2543Smrg } else { 355706f2543Smrg ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP; 356706f2543Smrg ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 357706f2543Smrg ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 358706f2543Smrg ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT|B16_LINEAR | 359706f2543Smrg B16_CONTIGUOUS | B16_555; 360706f2543Smrg ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 361706f2543Smrg } 362706f2543Smrg break; 363706f2543Smrg case 8: 364706f2543Smrg ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_8BPP; 365706f2543Smrg ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 366706f2543Smrg ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 367706f2543Smrg ramdacReg->DacRegs[IBMRGB_16bpp] = 0; 368706f2543Smrg ramdacReg->DacRegs[IBMRGB_8bpp] = B8_DCOL_INDIRECT; 369706f2543Smrg break; 370706f2543Smrg case 4: 371706f2543Smrg ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_4BPP; 372706f2543Smrg ramdacReg->DacRegs[IBMRGB_32bpp] = 0; 373706f2543Smrg ramdacReg->DacRegs[IBMRGB_24bpp] = 0; 374706f2543Smrg ramdacReg->DacRegs[IBMRGB_16bpp] = 0; 375706f2543Smrg ramdacReg->DacRegs[IBMRGB_8bpp] = 0; 376706f2543Smrg } 377706f2543Smrg} 378706f2543Smrg 379706f2543SmrgIBMramdac526SetBppProc *IBMramdac526SetBppWeak(void) { 380706f2543Smrg return IBMramdac526SetBpp; 381706f2543Smrg} 382706f2543Smrg 383706f2543Smrgvoid 384706f2543SmrgIBMramdac640SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg) 385706f2543Smrg{ 386706f2543Smrg unsigned char bpp = 0x00; 387706f2543Smrg unsigned char overlaybpp = 0x00; 388706f2543Smrg unsigned char offset = 0x00; 389706f2543Smrg unsigned char dispcont = 0x44; 390706f2543Smrg 391706f2543Smrg ramdacReg->DacRegs[RGB640_SER_WID_03_00] = 0x00; 392706f2543Smrg ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x00; 393706f2543Smrg ramdacReg->DacRegs[RGB640_DIAGS] = 0x07; 394706f2543Smrg 395706f2543Smrg switch (pScrn->depth) { 396706f2543Smrg case 8: 397706f2543Smrg ramdacReg->DacRegs[RGB640_SER_07_00] = 0x00; 398706f2543Smrg ramdacReg->DacRegs[RGB640_SER_15_08] = 0x00; 399706f2543Smrg ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00; 400706f2543Smrg ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00; 401706f2543Smrg ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_16_1; /*16:1 Mux*/ 402706f2543Smrg ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */ 403706f2543Smrg bpp = 0x03; 404706f2543Smrg break; 405706f2543Smrg case 15: 406706f2543Smrg ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10; 407706f2543Smrg ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11; 408706f2543Smrg ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00; 409706f2543Smrg ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00; 410706f2543Smrg ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux*/ 411706f2543Smrg ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */ 412706f2543Smrg bpp = 0x0E; 413706f2543Smrg break; 414706f2543Smrg case 16: 415706f2543Smrg ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10; 416706f2543Smrg ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11; 417706f2543Smrg ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00; 418706f2543Smrg ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00; 419706f2543Smrg ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux*/ 420706f2543Smrg ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */ 421706f2543Smrg bpp = 0x05; 422706f2543Smrg break; 423706f2543Smrg case 24: 424706f2543Smrg ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30; 425706f2543Smrg ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31; 426706f2543Smrg ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32; 427706f2543Smrg ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33; 428706f2543Smrg ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux*/ 429706f2543Smrg ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */ 430706f2543Smrg bpp = 0x09; 431706f2543Smrg if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { 432706f2543Smrg ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x04; 433706f2543Smrg ramdacReg->DacRegs[RGB640_CHROMA_KEY0] = 0xFF; 434706f2543Smrg ramdacReg->DacRegs[RGB640_CHROMA_MASK0] = 0xFF; 435706f2543Smrg offset = 0x04; 436706f2543Smrg overlaybpp = 0x04; 437706f2543Smrg dispcont = 0x48; 438706f2543Smrg } 439706f2543Smrg break; 440706f2543Smrg case 30: /* 10 bit dac */ 441706f2543Smrg ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30; 442706f2543Smrg ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31; 443706f2543Smrg ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32; 444706f2543Smrg ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33; 445706f2543Smrg ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux*/ 446706f2543Smrg ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PSIZE10 | 447706f2543Smrg IBM640_PCLK_8; /* pll / 8 */ 448706f2543Smrg bpp = 0x0D; 449706f2543Smrg break; 450706f2543Smrg } 451706f2543Smrg 452706f2543Smrg { 453706f2543Smrg int i; 454706f2543Smrg for (i=0x100;i<0x140;i+=4) { 455706f2543Smrg /* Initialize FrameBuffer Window Attribute Table */ 456706f2543Smrg ramdacReg->DacRegs[i+0] = bpp; 457706f2543Smrg ramdacReg->DacRegs[i+1] = offset; 458706f2543Smrg ramdacReg->DacRegs[i+2] = 0x00; 459706f2543Smrg ramdacReg->DacRegs[i+3] = 0x00; 460706f2543Smrg /* Initialize Overlay Window Attribute Table */ 461706f2543Smrg ramdacReg->DacRegs[i+0x100] = overlaybpp; 462706f2543Smrg ramdacReg->DacRegs[i+0x101] = 0x00; 463706f2543Smrg ramdacReg->DacRegs[i+0x102] = 0x00; 464706f2543Smrg ramdacReg->DacRegs[i+0x103] = dispcont; 465706f2543Smrg } 466706f2543Smrg } 467706f2543Smrg} 468706f2543Smrg 469706f2543Smrgstatic void 470706f2543SmrgIBMramdac526ShowCursor(ScrnInfoPtr pScrn) 471706f2543Smrg{ 472706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 473706f2543Smrg 474706f2543Smrg /* Enable cursor - X11 mode */ 475706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs, 0x00, 0x07); 476706f2543Smrg} 477706f2543Smrg 478706f2543Smrgstatic void 479706f2543SmrgIBMramdac640ShowCursor(ScrnInfoPtr pScrn) 480706f2543Smrg{ 481706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 482706f2543Smrg 483706f2543Smrg /* Enable cursor - mode2 (x11 mode) */ 484706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x0B); 485706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CROSSHAIR_CONTROL, 0x00, 0x00); 486706f2543Smrg} 487706f2543Smrg 488706f2543Smrgstatic void 489706f2543SmrgIBMramdac526HideCursor(ScrnInfoPtr pScrn) 490706f2543Smrg{ 491706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 492706f2543Smrg 493706f2543Smrg /* Disable cursor - X11 mode */ 494706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs, 0x00, 0x24); 495706f2543Smrg} 496706f2543Smrg 497706f2543Smrgstatic void 498706f2543SmrgIBMramdac640HideCursor(ScrnInfoPtr pScrn) 499706f2543Smrg{ 500706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 501706f2543Smrg 502706f2543Smrg /* Disable cursor - mode2 (x11 mode) */ 503706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x08); 504706f2543Smrg} 505706f2543Smrg 506706f2543Smrgstatic void 507706f2543SmrgIBMramdac526SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 508706f2543Smrg{ 509706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 510706f2543Smrg 511706f2543Smrg x += 64; 512706f2543Smrg y += 64; 513706f2543Smrg 514706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_hot_x, 0x00, 0x3f); 515706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_hot_y, 0x00, 0x3f); 516706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_xl, 0x00, x & 0xff); 517706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_xh, 0x00, (x>>8) & 0xf); 518706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_yl, 0x00, y & 0xff); 519706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_yh, 0x00, (y>>8) & 0xf); 520706f2543Smrg} 521706f2543Smrg 522706f2543Smrgstatic void 523706f2543SmrgIBMramdac640SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 524706f2543Smrg{ 525706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 526706f2543Smrg 527706f2543Smrg x += 64; 528706f2543Smrg y += 64; 529706f2543Smrg 530706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_OFFSETX, 0x00, 0x3f); 531706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_OFFSETY, 0x00, 0x3f); 532706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_X_LOW, 0x00, x & 0xff); 533706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_X_HIGH, 0x00, (x>>8) & 0xf); 534706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_Y_LOW, 0x00, y & 0xff); 535706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_Y_HIGH, 0x00, (y>>8) & 0xf); 536706f2543Smrg} 537706f2543Smrg 538706f2543Smrgstatic void 539706f2543SmrgIBMramdac526SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 540706f2543Smrg{ 541706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 542706f2543Smrg 543706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_r, 0x00, bg >> 16); 544706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_g, 0x00, bg >> 8); 545706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_b, 0x00, bg); 546706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_r, 0x00, fg >> 16); 547706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_g, 0x00, fg >> 8); 548706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_b, 0x00, fg); 549706f2543Smrg} 550706f2543Smrg 551706f2543Smrgstatic void 552706f2543SmrgIBMramdac640SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 553706f2543Smrg{ 554706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 555706f2543Smrg 556706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_COL0, 0x00, 0); 557706f2543Smrg (*ramdacPtr->WriteData)(pScrn, fg>>16); 558706f2543Smrg (*ramdacPtr->WriteData)(pScrn, fg>>8); 559706f2543Smrg (*ramdacPtr->WriteData)(pScrn, fg); 560706f2543Smrg (*ramdacPtr->WriteData)(pScrn, bg>>16); 561706f2543Smrg (*ramdacPtr->WriteData)(pScrn, bg>>8); 562706f2543Smrg (*ramdacPtr->WriteData)(pScrn, bg); 563706f2543Smrg (*ramdacPtr->WriteData)(pScrn, fg>>16); 564706f2543Smrg (*ramdacPtr->WriteData)(pScrn, fg>>8); 565706f2543Smrg (*ramdacPtr->WriteData)(pScrn, fg); 566706f2543Smrg (*ramdacPtr->WriteData)(pScrn, bg>>16); 567706f2543Smrg (*ramdacPtr->WriteData)(pScrn, bg>>8); 568706f2543Smrg (*ramdacPtr->WriteData)(pScrn, bg); 569706f2543Smrg} 570706f2543Smrg 571706f2543Smrgstatic void 572706f2543SmrgIBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 573706f2543Smrg{ 574706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 575706f2543Smrg int i; 576706f2543Smrg /* 577706f2543Smrg * Output the cursor data. The realize function has put the planes into 578706f2543Smrg * their correct order, so we can just blast this out. 579706f2543Smrg */ 580706f2543Smrg for (i = 0; i < 1024; i++) 581706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_array + i, 0x00, (*src++)); 582706f2543Smrg} 583706f2543Smrg 584706f2543Smrgstatic void 585706f2543SmrgIBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 586706f2543Smrg{ 587706f2543Smrg RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); 588706f2543Smrg int i; 589706f2543Smrg /* 590706f2543Smrg * Output the cursor data. The realize function has put the planes into 591706f2543Smrg * their correct order, so we can just blast this out. 592706f2543Smrg */ 593706f2543Smrg for (i = 0; i < 1024; i++) 594706f2543Smrg (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_WRITE + i, 0x00, (*src++)); 595706f2543Smrg} 596706f2543Smrg 597706f2543Smrgstatic Bool 598706f2543SmrgIBMramdac526UseHWCursor(ScreenPtr pScr, CursorPtr pCurs) 599706f2543Smrg{ 600706f2543Smrg return TRUE; 601706f2543Smrg} 602706f2543Smrg 603706f2543Smrgstatic Bool 604706f2543SmrgIBMramdac640UseHWCursor(ScreenPtr pScr, CursorPtr pCurs) 605706f2543Smrg{ 606706f2543Smrg return TRUE; 607706f2543Smrg} 608706f2543Smrg 609706f2543Smrgvoid 610706f2543SmrgIBMramdac526HWCursorInit(xf86CursorInfoPtr infoPtr) 611706f2543Smrg{ 612706f2543Smrg infoPtr->MaxWidth = 64; 613706f2543Smrg infoPtr->MaxHeight = 64; 614706f2543Smrg infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 615706f2543Smrg HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 616706f2543Smrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; 617706f2543Smrg infoPtr->SetCursorColors = IBMramdac526SetCursorColors; 618706f2543Smrg infoPtr->SetCursorPosition = IBMramdac526SetCursorPosition; 619706f2543Smrg infoPtr->LoadCursorImage = IBMramdac526LoadCursorImage; 620706f2543Smrg infoPtr->HideCursor = IBMramdac526HideCursor; 621706f2543Smrg infoPtr->ShowCursor = IBMramdac526ShowCursor; 622706f2543Smrg infoPtr->UseHWCursor = IBMramdac526UseHWCursor; 623706f2543Smrg} 624706f2543Smrg 625706f2543Smrgvoid 626706f2543SmrgIBMramdac640HWCursorInit(xf86CursorInfoPtr infoPtr) 627706f2543Smrg{ 628706f2543Smrg infoPtr->MaxWidth = 64; 629706f2543Smrg infoPtr->MaxHeight = 64; 630706f2543Smrg infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 631706f2543Smrg HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 632706f2543Smrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; 633706f2543Smrg infoPtr->SetCursorColors = IBMramdac640SetCursorColors; 634706f2543Smrg infoPtr->SetCursorPosition = IBMramdac640SetCursorPosition; 635706f2543Smrg infoPtr->LoadCursorImage = IBMramdac640LoadCursorImage; 636706f2543Smrg infoPtr->HideCursor = IBMramdac640HideCursor; 637706f2543Smrg infoPtr->ShowCursor = IBMramdac640ShowCursor; 638706f2543Smrg infoPtr->UseHWCursor = IBMramdac640UseHWCursor; 639706f2543Smrg} 640