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