1c35d236eSmrg/* 2c35d236eSmrg * Copyright 1997-2001 by Alan Hourihane <alanh@fairlite.demon.co.uk> 3c35d236eSmrg * 4c35d236eSmrg * Permission to use, copy, modify, distribute, and sell this software and its 5c35d236eSmrg * documentation for any purpose is hereby granted without fee, provided that 6c35d236eSmrg * the above copyright notice appear in all copies and that both that 7c35d236eSmrg * copyright notice and this permission notice appear in supporting 8c35d236eSmrg * documentation, and that the name of Alan Hourihane not be used in 9c35d236eSmrg * advertising or publicity pertaining to distribution of the software without 10c35d236eSmrg * specific, written prior permission. Alan Hourihane makes no representations 11c35d236eSmrg * about the suitability of this software for any purpose. It is provided 12c35d236eSmrg * "as is" without express or implied warranty. 13c35d236eSmrg * 14c35d236eSmrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15c35d236eSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16c35d236eSmrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17c35d236eSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18c35d236eSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19c35d236eSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20c35d236eSmrg * PERFORMANCE OF THIS SOFTWARE. 21c35d236eSmrg * 22c35d236eSmrg * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 23c35d236eSmrg * Dirk Hohndel, <hohndel@suse.de> 24c35d236eSmrg * Stefan Dirsch, <sndirsch@suse.de> 25c35d236eSmrg * Helmut Fahrion, <hf@suse.de> 26c35d236eSmrg * 27c35d236eSmrg * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and 28c35d236eSmrg * Siemens Nixdorf Informationssysteme 29c35d236eSmrg */ 30c35d236eSmrg 31c35d236eSmrg#ifdef HAVE_CONFIG_H 32c35d236eSmrg#include "config.h" 33c35d236eSmrg#endif 34c35d236eSmrg 35c35d236eSmrg#include "xf86.h" 36c35d236eSmrg#include "xf86_OSproc.h" 37c35d236eSmrg 38c35d236eSmrg#include "xf86Pci.h" 39c35d236eSmrg 40c35d236eSmrg#include "glint_regs.h" 41c35d236eSmrg#include "glint.h" 42c35d236eSmrg 43c35d236eSmrgstatic unsigned long 44c35d236eSmrgPM2VDAC_CalculateClock 45c35d236eSmrg( 46c35d236eSmrg unsigned long reqclock, /* In kHz units */ 47c35d236eSmrg unsigned long refclock, /* In kHz units */ 48c35d236eSmrg unsigned char *prescale, /* ClkPreScale */ 49c35d236eSmrg unsigned char *feedback, /* ClkFeedBackScale */ 50c35d236eSmrg unsigned char *postscale /* ClkPostScale */ 51c35d236eSmrg ) 52c35d236eSmrg{ 53c35d236eSmrg int f, pre, post; 54c35d236eSmrg unsigned long freq; 55c35d236eSmrg long freqerr = 1000; 56c35d236eSmrg unsigned long actualclock = 0; 57c35d236eSmrg unsigned char divide[5] = { 1, 2, 4, 8, 16 }; 58c35d236eSmrg 59c35d236eSmrg for (f=1;f<256;f++) { 60c35d236eSmrg for (pre=1;pre<256;pre++) { 61c35d236eSmrg for (post=0;post<2;post++) { 62c35d236eSmrg freq = ((refclock * f) / (pre * (1 << divide[post]))); 63c35d236eSmrg if ((reqclock > freq - freqerr)&&(reqclock < freq + freqerr)){ 64c35d236eSmrg freqerr = (reqclock > freq) ? 65c35d236eSmrg reqclock - freq : freq - reqclock; 66c35d236eSmrg *feedback = f; 67c35d236eSmrg *prescale = pre; 68c35d236eSmrg *postscale = post; 69c35d236eSmrg actualclock = freq; 70c35d236eSmrg } 71c35d236eSmrg } 72c35d236eSmrg } 73c35d236eSmrg } 74c35d236eSmrg 75c35d236eSmrg return(actualclock); 76c35d236eSmrg} 77c35d236eSmrg 78c35d236eSmrgstatic void 79c35d236eSmrgPermedia2VPreInitSecondary(ScrnInfoPtr pScrn) 80c35d236eSmrg{ 81c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 82c35d236eSmrg 83c35d236eSmrg /* disable MCLK */ 84c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDMClkControl, 0x00, 0); 85c35d236eSmrg 86c35d236eSmrg /* boot new mclk values */ 87c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDMClkPreScale, 0x00, 0x09); 88c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDMClkFeedbackScale, 0x00, 0x58); 89c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDMClkPostScale, 0x00, 0x01); 90c35d236eSmrg 91c35d236eSmrg /* re-enable MCLK */ 92c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDMClkControl, 0x00, 1); 93c35d236eSmrg 94c35d236eSmrg /* spin until locked MCLK */ 95c35d236eSmrg while ( (Permedia2vInIndReg(pScrn, PM2VDACRDMClkControl) & 0x2) == 0); 96c35d236eSmrg 97c35d236eSmrg /* Now re-boot the SGRAM's */ 98c35d236eSmrg GLINT_SLOW_WRITE_REG(0xe6002021,PMMemConfig); 99c35d236eSmrg GLINT_SLOW_WRITE_REG(0x00000020,PMBootAddress); 100c35d236eSmrg} 101c35d236eSmrg 102c35d236eSmrgvoid 103c35d236eSmrgPermedia2VPreInit(ScrnInfoPtr pScrn) 104c35d236eSmrg{ 105c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 106c35d236eSmrg 107c35d236eSmrg if (IS_JPRO) { 108c35d236eSmrg /* Appian Jeronimo Pro 4x8mb (pm2v version) */ 109c35d236eSmrg /* BIOS doesn't initialize the secondary heads, so we need to */ 110c35d236eSmrg 111c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 112c35d236eSmrg "Appian Jeronimo Pro 4x8mb board detected and initialized.\n"); 113c35d236eSmrg 114c35d236eSmrg Permedia2VPreInitSecondary(pScrn); 115c35d236eSmrg } 116c35d236eSmrg 117c35d236eSmrg#if defined(__alpha__) 118c35d236eSmrg /* 119c35d236eSmrg * On Alpha, we have to init secondary PM2V cards, since 120c35d236eSmrg * int10 cannot be run on the OEMed cards with VGA disable 121c35d236eSmrg * jumpers. 122c35d236eSmrg */ 123c35d236eSmrg if (!xf86IsPrimaryPci(pGlint->PciInfo)) { 124c35d236eSmrg if ( IS_QPM2V ) { 125c35d236eSmrg 126c35d236eSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 127c35d236eSmrg "PM2V secondary: initializing\n"); 128c35d236eSmrg Permedia2VPreInitSecondary(pScrn); 129c35d236eSmrg } 130c35d236eSmrg } 131c35d236eSmrg#endif /* __alpha__ */ 132c35d236eSmrg} 133c35d236eSmrg 134c35d236eSmrgBool 135c35d236eSmrgPermedia2VInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 136c35d236eSmrg{ 137c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 138c35d236eSmrg GLINTRegPtr pReg = &pGlint->ModeReg[0]; 139c35d236eSmrg CARD32 temp1, temp2, temp3, temp4; 140c35d236eSmrg 141c35d236eSmrg temp1 = 0; 142c35d236eSmrg temp2 = 0; 143c35d236eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 144c35d236eSmrg switch (pGlint->HwBpp) { 145c35d236eSmrg case 8: 146c35d236eSmrg case 24: 147c35d236eSmrg temp1 = 0x00; 148c35d236eSmrg temp2 = 0x00; 149c35d236eSmrg break; 150c35d236eSmrg 151c35d236eSmrg case 15: 152c35d236eSmrg case 16: 153c35d236eSmrg temp1 = 0x02; 154c35d236eSmrg temp2 = 0x02; 155c35d236eSmrg break; 156c35d236eSmrg 157c35d236eSmrg case 32: 158c35d236eSmrg temp1 = 0x01; 159c35d236eSmrg temp2 = 0x01; 160c35d236eSmrg break; 161c35d236eSmrg default: 162c35d236eSmrg break; 163c35d236eSmrg }; 164c35d236eSmrg#endif /* BIG_ENDIAN */ 165c35d236eSmrg 166c35d236eSmrg pReg->glintRegs[Aperture0 >> 3] = temp1; 167c35d236eSmrg pReg->glintRegs[Aperture1 >> 3] = temp2; 168c35d236eSmrg 169c35d236eSmrg pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF; 170c35d236eSmrg pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF; 171c35d236eSmrg 172c35d236eSmrg pReg->glintRegs[DFIFODis >> 3] = 0; 173c35d236eSmrg pReg->glintRegs[FIFODis >> 3] = 1; 174c35d236eSmrg 175c35d236eSmrg if (pGlint->UseBlockWrite) 176c35d236eSmrg pReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig) | 1<<21; 177c35d236eSmrg 178c35d236eSmrg temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; 179c35d236eSmrg temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; 180c35d236eSmrg temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; 181c35d236eSmrg temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; 182c35d236eSmrg 183c35d236eSmrg pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal); 184c35d236eSmrg pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3); 185c35d236eSmrg pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1); 186c35d236eSmrg pReg->glintRegs[PMHbEnd >> 3] = 187c35d236eSmrg Shiftbpp(pScrn,mode->CrtcHTotal-mode->CrtcHDisplay); 188c35d236eSmrg pReg->glintRegs[PMScreenStride >> 3] = 189c35d236eSmrg Shiftbpp(pScrn,pScrn->displayWidth>>1); 190c35d236eSmrg 191c35d236eSmrg pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal; 192c35d236eSmrg pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4; 193c35d236eSmrg pReg->glintRegs[PMVsStart >> 3] = temp2; 194c35d236eSmrg pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay; 195c35d236eSmrg 196c35d236eSmrg /* The hw cursor needs /VSYNC to recognize vert retrace. We'll stick 197c35d236eSmrg both sync lines to active low here and if needed invert them 198c35d236eSmrg using the RAMDAC's RDSyncControl below. */ 199c35d236eSmrg pReg->glintRegs[PMVideoControl >> 3] = 200c35d236eSmrg (1 << 5) | (1 << 3) | 1; 201c35d236eSmrg 202c35d236eSmrg /* We stick the RAMDAC into 64bit mode */ 203c35d236eSmrg /* And reduce the horizontal timings and clock by half */ 204c35d236eSmrg pReg->glintRegs[PMVideoControl >> 3] |= 1<<16; 205c35d236eSmrg pReg->glintRegs[PMHTotal >> 3] >>= 1; 206c35d236eSmrg pReg->glintRegs[PMHsEnd >> 3] >>= 1; 207c35d236eSmrg pReg->glintRegs[PMHsStart >> 3] >>= 1; 208c35d236eSmrg pReg->glintRegs[PMHbEnd >> 3] >>= 1; 209c35d236eSmrg 210c35d236eSmrg pReg->glintRegs[VClkCtl >> 3] = (GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC); 211c35d236eSmrg pReg->glintRegs[PMScreenBase >> 3] = 0; 212c35d236eSmrg pReg->glintRegs[PMHTotal >> 3] -= 1; 213c35d236eSmrg pReg->glintRegs[PMHsStart >> 3] -= 1; /* PMHsStart */ 214c35d236eSmrg pReg->glintRegs[PMVTotal >> 3] -= 1; /* PMVTotal */ 215c35d236eSmrg 216c35d236eSmrg pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFDD; 217c35d236eSmrg pReg->DacRegs[PM2VDACRDDACControl] = 0x00; 218c35d236eSmrg 219c35d236eSmrg { 220c35d236eSmrg /* Get the programmable clock values */ 221c35d236eSmrg unsigned char m,n,p; 222c35d236eSmrg 223c35d236eSmrg (void) PM2VDAC_CalculateClock(mode->Clock/2,pGlint->RefClock, 224c35d236eSmrg &m,&n,&p); 225c35d236eSmrg pReg->DacRegs[PM2VDACRDDClk0PreScale] = m; 226c35d236eSmrg pReg->DacRegs[PM2VDACRDDClk0FeedbackScale] = n; 227c35d236eSmrg pReg->DacRegs[PM2VDACRDDClk0PostScale] = p; 228c35d236eSmrg } 229c35d236eSmrg 230c35d236eSmrg pReg->glintRegs[PM2VDACRDIndexControl >> 3] = 0x00; 231c35d236eSmrg 232c35d236eSmrg if (pScrn->rgbBits == 8) 233c35d236eSmrg pReg->DacRegs[PM2VDACRDMiscControl] = 0x01; /* 8bit DAC */ 234c35d236eSmrg else 235c35d236eSmrg pReg->DacRegs[PM2VDACRDMiscControl] = 0x00; /* 6bit DAC */ 236c35d236eSmrg 237c35d236eSmrg pReg->DacRegs[PM2VDACRDSyncControl] = 0x00; 238c35d236eSmrg if (mode->Flags & V_PHSYNC) 239c35d236eSmrg pReg->DacRegs[PM2VDACRDSyncControl] |= 0x01; /* invert hsync */ 240c35d236eSmrg if (mode->Flags & V_PVSYNC) 241c35d236eSmrg pReg->DacRegs[PM2VDACRDSyncControl] |= 0x08; /* invert vsync */ 242c35d236eSmrg 243c35d236eSmrg switch (pScrn->bitsPerPixel) 244c35d236eSmrg { 245c35d236eSmrg case 8: 246c35d236eSmrg pReg->DacRegs[PM2VDACRDPixelSize] = 0x00; 247c35d236eSmrg pReg->DacRegs[PM2VDACRDColorFormat] = 0x2E; 248c35d236eSmrg break; 249c35d236eSmrg case 16: 250c35d236eSmrg pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; 251c35d236eSmrg pReg->DacRegs[PM2VDACRDPixelSize] = 0x01; 252c35d236eSmrg if (pScrn->depth == 15) 253c35d236eSmrg pReg->DacRegs[PM2VDACRDColorFormat] = 0x61; 254c35d236eSmrg else 255c35d236eSmrg pReg->DacRegs[PM2VDACRDColorFormat] = 0x70; 256c35d236eSmrg break; 257c35d236eSmrg case 24: 258c35d236eSmrg pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; 259c35d236eSmrg pReg->DacRegs[PM2VDACRDPixelSize] = 0x04; 260c35d236eSmrg pReg->DacRegs[PM2VDACRDColorFormat] = 0x60; 261c35d236eSmrg break; 262c35d236eSmrg case 32: 263c35d236eSmrg pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08; 264c35d236eSmrg pReg->DacRegs[PM2VDACRDPixelSize] = 0x02; 265c35d236eSmrg pReg->DacRegs[PM2VDACRDColorFormat] = 0x20; 266c35d236eSmrg if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { 267c35d236eSmrg pReg->DacRegs[PM2VDACRDMiscControl] |= 0x18; 268c35d236eSmrg pReg->DacRegs[PM2VDACRDOverlayKey] = pScrn->colorKey; 269c35d236eSmrg } 270c35d236eSmrg break; 271c35d236eSmrg } 272c35d236eSmrg 273c35d236eSmrg return(TRUE); 274c35d236eSmrg} 275c35d236eSmrg 276c35d236eSmrgvoid 277c35d236eSmrgPermedia2VSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) 278c35d236eSmrg{ 279c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 280c35d236eSmrg int i; 281c35d236eSmrg 282c35d236eSmrg /* We can't rely on the vgahw layer copying the font information 283c35d236eSmrg * back properly, due to problems with MMIO access to VGA space 284c35d236eSmrg * so we memcpy the information */ 285c35d236eSmrg memcpy((CARD8*)pGlint->VGAdata,(CARD8*)pGlint->FbBase, 65536); 286c35d236eSmrg 287c35d236eSmrg glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig); 288c35d236eSmrg glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0); 289c35d236eSmrg glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1); 290c35d236eSmrg glintReg->glintRegs[PMFramebufferWriteMask >> 3] = 291c35d236eSmrg GLINT_READ_REG(PMFramebufferWriteMask); 292c35d236eSmrg glintReg->glintRegs[PMBypassWriteMask >> 3] = 293c35d236eSmrg GLINT_READ_REG(PMBypassWriteMask); 294c35d236eSmrg glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis); 295c35d236eSmrg glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis); 296c35d236eSmrg /* We only muck about with PMMemConfig, if user wants to */ 297c35d236eSmrg if (pGlint->UseBlockWrite) 298c35d236eSmrg glintReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig); 299c35d236eSmrg glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal); 300c35d236eSmrg glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd); 301c35d236eSmrg glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHgEnd); 302c35d236eSmrg glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride); 303c35d236eSmrg glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart); 304c35d236eSmrg glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd); 305c35d236eSmrg glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal); 306c35d236eSmrg glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd); 307c35d236eSmrg glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart); 308c35d236eSmrg glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd); 309c35d236eSmrg glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase); 310c35d236eSmrg glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl); 311c35d236eSmrg glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl); 312c35d236eSmrg 313c35d236eSmrg for (i=0;i<768;i++) { 314c35d236eSmrg Permedia2ReadAddress(pScrn, i); 315c35d236eSmrg glintReg->cmap[i] = Permedia2ReadData(pScrn); 316c35d236eSmrg } 317c35d236eSmrg 318c35d236eSmrg glintReg->glintRegs[PM2VDACRDIndexControl >> 3] = 319c35d236eSmrg GLINT_READ_REG(PM2VDACRDIndexControl); 320c35d236eSmrg glintReg->DacRegs[PM2VDACRDOverlayKey] = 321c35d236eSmrg Permedia2vInIndReg(pScrn, PM2VDACRDOverlayKey); 322c35d236eSmrg glintReg->DacRegs[PM2VDACRDSyncControl] = 323c35d236eSmrg Permedia2vInIndReg(pScrn, PM2VDACRDSyncControl); 324c35d236eSmrg glintReg->DacRegs[PM2VDACRDMiscControl] = 325c35d236eSmrg Permedia2vInIndReg(pScrn, PM2VDACRDMiscControl); 326c35d236eSmrg glintReg->DacRegs[PM2VDACRDDACControl] = 327c35d236eSmrg Permedia2vInIndReg(pScrn, PM2VDACRDDACControl); 328c35d236eSmrg glintReg->DacRegs[PM2VDACRDPixelSize] = 329c35d236eSmrg Permedia2vInIndReg(pScrn, PM2VDACRDPixelSize); 330c35d236eSmrg glintReg->DacRegs[PM2VDACRDColorFormat] = 331c35d236eSmrg Permedia2vInIndReg(pScrn, PM2VDACRDColorFormat); 332c35d236eSmrg 333c35d236eSmrg glintReg->DacRegs[PM2VDACRDDClk0PreScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0PreScale); 334c35d236eSmrg glintReg->DacRegs[PM2VDACRDDClk0FeedbackScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0FeedbackScale); 335c35d236eSmrg glintReg->DacRegs[PM2VDACRDDClk0PostScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0PostScale); 336c35d236eSmrg} 337c35d236eSmrg 338c35d236eSmrgvoid 339c35d236eSmrgPermedia2VRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg) 340c35d236eSmrg{ 341c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 342c35d236eSmrg CARD32 temp; 343c35d236eSmrg int i; 344c35d236eSmrg 345c35d236eSmrg /* We can't rely on the vgahw layer copying the font information 346c35d236eSmrg * back properly, due to problems with MMIO access to VGA space 347c35d236eSmrg * so we memcpy the information */ 348c35d236eSmrg if (pGlint->STATE) 349c35d236eSmrg memcpy((CARD8*)pGlint->FbBase,(CARD8*)pGlint->VGAdata, 65536); 350c35d236eSmrg 351c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig); 352c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0); 353c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1); 354c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3], 355c35d236eSmrg PMFramebufferWriteMask); 356c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3], 357c35d236eSmrg PMBypassWriteMask); 358c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis); 359c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis); 360c35d236eSmrg /* We only muck about with PMMemConfig, if user wants to */ 361c35d236eSmrg if (pGlint->UseBlockWrite) 362c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMMemConfig >> 3],PMMemConfig); 363c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3], 364c35d236eSmrg PMVideoControl); 365c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHgEnd); 366c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase); 367c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl); 368c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3], 369c35d236eSmrg PMScreenStride); 370c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal); 371c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHbEnd); 372c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart); 373c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd); 374c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal); 375c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd); 376c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart); 377c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd); 378c35d236eSmrg 379c35d236eSmrg GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PM2VDACRDIndexControl >> 3], 380c35d236eSmrg PM2VDACRDIndexControl); 381c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDOverlayKey, 0x00, 382c35d236eSmrg glintReg->DacRegs[PM2VDACRDOverlayKey]); 383c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDSyncControl, 0x00, 384c35d236eSmrg glintReg->DacRegs[PM2VDACRDSyncControl]); 385c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDMiscControl, 0x00, 386c35d236eSmrg glintReg->DacRegs[PM2VDACRDMiscControl]); 387c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDDACControl, 0x00, 388c35d236eSmrg glintReg->DacRegs[PM2VDACRDDACControl]); 389c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDPixelSize, 0x00, 390c35d236eSmrg glintReg->DacRegs[PM2VDACRDPixelSize]); 391c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDColorFormat, 0x00, 392c35d236eSmrg glintReg->DacRegs[PM2VDACRDColorFormat]); 393c35d236eSmrg 394c35d236eSmrg for (i=0;i<768;i++) { 395c35d236eSmrg Permedia2WriteAddress(pScrn, i); 396c35d236eSmrg Permedia2WriteData(pScrn, glintReg->cmap[i]); 397c35d236eSmrg } 398c35d236eSmrg 399c35d236eSmrg temp = Permedia2vInIndReg(pScrn, PM2VDACIndexClockControl) & 0xFC; 400c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0PreScale, 0x00, 401c35d236eSmrg glintReg->DacRegs[PM2VDACRDDClk0PreScale]); 402c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0FeedbackScale, 0x00, 403c35d236eSmrg glintReg->DacRegs[PM2VDACRDDClk0FeedbackScale]); 404c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0PostScale, 0x00, 405c35d236eSmrg glintReg->DacRegs[PM2VDACRDDClk0PostScale]); 406c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACIndexClockControl, 0x00, temp|0x03); 407c35d236eSmrg} 408c35d236eSmrg 409c35d236eSmrgstatic void 410c35d236eSmrgPermedia2vShowCursor(ScrnInfoPtr pScrn) 411c35d236eSmrg{ 412c35d236eSmrg /* Enable cursor - X11 mode */ 413c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorMode, 0x00, 0x11); 414c35d236eSmrg} 415c35d236eSmrg 416c35d236eSmrgstatic void Permedia2vLoadCursorCallback(ScrnInfoPtr pScrn); 417c35d236eSmrg 418c35d236eSmrgstatic void 419c35d236eSmrgPermedia2vHideCursor(ScrnInfoPtr pScrn) 420c35d236eSmrg{ 421c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 422c35d236eSmrg 423c35d236eSmrg /* Disable cursor - X11 mode */ 424c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorMode, 0x00, 0x10); 425c35d236eSmrg 426c35d236eSmrg /* 427c35d236eSmrg * For some reason, we need to clear the image as well as disable 428c35d236eSmrg * the cursor on PM2V, but not on PM3. The problem is noticeable 429c35d236eSmrg * only when running multi-head, as you can see the cursor get 430c35d236eSmrg * "left behind" on the screen it is leaving... 431c35d236eSmrg */ 432c35d236eSmrg if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) { 433c35d236eSmrg memset(pGlint->HardwareCursorPattern, 0, 1024); 434c35d236eSmrg pGlint->LoadCursorCallback = Permedia2vLoadCursorCallback; 435c35d236eSmrg } 436c35d236eSmrg} 437c35d236eSmrg 438c35d236eSmrgstatic void 439c35d236eSmrgPermedia2vLoadCursorCallback( 440c35d236eSmrg ScrnInfoPtr pScrn 441c35d236eSmrg) 442c35d236eSmrg{ 443c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 444c35d236eSmrg int i; 445c35d236eSmrg 446c35d236eSmrg for (i=0; i<1024; i++) 447c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPattern+i, 0x00, 448c35d236eSmrg pGlint->HardwareCursorPattern[i]); 449c35d236eSmrg 450c35d236eSmrg pGlint->LoadCursorCallback = NULL; 451c35d236eSmrg} 452c35d236eSmrg 453c35d236eSmrgstatic void 454c35d236eSmrgPermedia2vLoadCursorImage( 455c35d236eSmrg ScrnInfoPtr pScrn, 456c35d236eSmrg unsigned char *src 457c35d236eSmrg) 458c35d236eSmrg{ 459c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 460c35d236eSmrg int i; 461c35d236eSmrg 462c35d236eSmrg for (i=0; i<1024; i++) 463c35d236eSmrg pGlint->HardwareCursorPattern[i] = *(src++); 464c35d236eSmrg 465c35d236eSmrg pGlint->LoadCursorCallback = Permedia2vLoadCursorCallback; 466c35d236eSmrg} 467c35d236eSmrg 468c35d236eSmrgstatic void 469c35d236eSmrgPermedia2vSetCursorPosition( 470c35d236eSmrg ScrnInfoPtr pScrn, 471c35d236eSmrg int x, int y 472c35d236eSmrg) 473c35d236eSmrg{ 474c35d236eSmrg x += 64; 475c35d236eSmrg y += 64; 476c35d236eSmrg /* Output position - "only" 11 bits of location documented */ 477c35d236eSmrg 478c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorHotSpotX, 0x00, 0x3f); 479c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorHotSpotY, 0x00, 0x3f); 480c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorXLow, 0x00, x & 0xFF); 481c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorXHigh, 0x00, (x>>8) & 0x0F); 482c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorYLow, 0x00, y & 0xFF); 483c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorYHigh, 0x00, (y>>8) & 0x0F); 484c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x00); 485c35d236eSmrg} 486c35d236eSmrg 487c35d236eSmrgstatic void 488c35d236eSmrgPermedia2vCursorColorCallback( 489c35d236eSmrg ScrnInfoPtr pScrn 490c35d236eSmrg) 491c35d236eSmrg{ 492c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 493c35d236eSmrg int fg = pGlint->FGCursor; 494c35d236eSmrg int bg = pGlint->BGCursor; 495c35d236eSmrg 496c35d236eSmrg if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA3) || 497c35d236eSmrg ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) && 4981fb744b4Smrg (pGlint->MultiChip == PCI_CHIP_3DLABS_PERMEDIA3)) ) { 499c35d236eSmrg /* PM3 uses last 2 indexes into hardware cursor palette fg first...*/ 500c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+39, 0x00, (fg>>16)&0xff); 501c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+40, 0x00, (fg>>8)&0xff); 502c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+41, 0x00, fg & 0xff); 503c35d236eSmrg 504c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+42, 0x00, (bg>>16)&0xff); 505c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+43, 0x00, (bg>>8)&0xff); 506c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+44, 0x00, bg & 0xff); 507c35d236eSmrg } else { 508c35d236eSmrg /* PM2v uses first 2 indexes into hardware cursor palette bg first...*/ 509c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+0, 0x00, (bg>>16)&0xff); 510c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+1, 0x00, (bg>>8)&0xff); 511c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+2, 0x00, bg & 0xff); 512c35d236eSmrg 513c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+3, 0x00, (fg>>16)&0xff); 514c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+4, 0x00, (fg>>8)&0xff); 515c35d236eSmrg Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+5, 0x00, fg & 0xff); 516c35d236eSmrg } 517c35d236eSmrg pGlint->CursorColorCallback = NULL; 518c35d236eSmrg} 519c35d236eSmrg 520c35d236eSmrgstatic void 521c35d236eSmrgPermedia2vSetCursorColors( 522c35d236eSmrg ScrnInfoPtr pScrn, 523c35d236eSmrg int bg, int fg 524c35d236eSmrg) 525c35d236eSmrg{ 526c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 527c35d236eSmrg 528c35d236eSmrg pGlint->FGCursor = fg; 529c35d236eSmrg pGlint->BGCursor = bg; 530c35d236eSmrg 531c35d236eSmrg pGlint->CursorColorCallback = Permedia2vCursorColorCallback; 532c35d236eSmrg} 533c35d236eSmrg 534c35d236eSmrgstatic Bool 535c35d236eSmrgPermedia2vUseHWCursor(ScreenPtr pScr, CursorPtr pCurs) 536c35d236eSmrg{ 537c35d236eSmrg return TRUE; 538c35d236eSmrg} 539c35d236eSmrg 540c35d236eSmrgBool 541c35d236eSmrgPermedia2vHWCursorInit(ScreenPtr pScreen) 542c35d236eSmrg{ 5431fb744b4Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 544c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 545c35d236eSmrg xf86CursorInfoPtr infoPtr; 546c35d236eSmrg 547c35d236eSmrg infoPtr = xf86CreateCursorInfoRec(); 548c35d236eSmrg if(!infoPtr) return FALSE; 549c35d236eSmrg 550c35d236eSmrg pGlint->CursorInfoRec = infoPtr; 551c35d236eSmrg 552c35d236eSmrg infoPtr->MaxWidth = 64; 553c35d236eSmrg infoPtr->MaxHeight = 64; 554c35d236eSmrg infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 555c35d236eSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 556c35d236eSmrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 557c35d236eSmrg#endif 558c35d236eSmrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; 559c35d236eSmrg infoPtr->SetCursorColors = Permedia2vSetCursorColors; 560c35d236eSmrg infoPtr->SetCursorPosition = Permedia2vSetCursorPosition; 561c35d236eSmrg infoPtr->LoadCursorImage = Permedia2vLoadCursorImage; 562c35d236eSmrg infoPtr->HideCursor = Permedia2vHideCursor; 563c35d236eSmrg infoPtr->ShowCursor = Permedia2vShowCursor; 564c35d236eSmrg infoPtr->UseHWCursor = Permedia2vUseHWCursor; 565c35d236eSmrg 566c35d236eSmrg return(xf86InitCursor(pScreen, infoPtr)); 567c35d236eSmrg} 568