/* Mandatory */ static Bool VoodooPreInit(ScrnInfoPtr pScrn, int flags) { VoodooPtr pVoo; int i; ClockRangePtr clockRanges; MessageType from; int maxwidth; if (flags & PROBE_DETECT) return FALSE; /* Check the number of entities, and fail if it isn't one. */ if (pScrn->numEntities != 1) return FALSE; /* Set pScrn->monitor */ pScrn->monitor = pScrn->confScreen->monitor; if (!xf86SetDepthBpp(pScrn, 16, 0, 0, Support32bppFb)) { return FALSE; } /* Check that the returned depth is one we support */ switch (pScrn->depth) { case 16: case 24: case 32: break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported by this driver\n", pScrn->depth); return FALSE; } xf86PrintDepthBpp(pScrn); if(pScrn->depth == 32) pScrn->depth = 24; /* * This must happen after pScrn->display has been set because * xf86SetWeight references it. */ if (pScrn->depth > 8) { /* The defaults are OK for us */ rgb zeros = {0, 0, 0}; if (!xf86SetWeight(pScrn, zeros, zeros)) { return FALSE; } else { /* XXX check that weight returned is supported */ ; } } /* Set the default visual. */ if (!xf86SetDefaultVisual(pScrn, -1)) { return FALSE; } /* We don't support DirectColor at > 8bpp */ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" " (%s) is not supported at depth %d\n", xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); return FALSE; } /* Set default gamma */ { Gamma zeros = {0.0, 0.0, 0.0}; if (!xf86SetGamma(pScrn, zeros)) { return FALSE; } } /* We use a programmable clock */ pScrn->progClock = TRUE; /* Allocate the VoodooRec driverPrivate */ if (!VoodooGetRec(pScrn)) { return FALSE; } pVoo = VoodooPTR(pScrn); /* Get the entity */ pVoo->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); pVoo->PciInfo = xf86GetPciInfoForEntity(pVoo->pEnt->index); #ifndef XSERVER_LIBPCIACCESS pVoo->PciTag = pciTag(pVoo->PciInfo->bus, pVoo->PciInfo->device, pVoo->PciInfo->func); #endif /* Collect all of the relevant option flags (fill in pScrn->options) */ xf86CollectOptions(pScrn, NULL); /* Process the options */ if (!(pVoo->Options = malloc(sizeof(VoodooOptions)))) return FALSE; memcpy(pVoo->Options, VoodooOptions, sizeof(VoodooOptions)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pVoo->Options); /* Need to do rotation some day */ if(pVoo->pEnt->chipset == PCI_CHIP_VOODOO2) { pVoo->Voodoo2 = 1; /* We have 2D accel, interlace, double */ pVoo->Accel = 1; } else { pVoo->Voodoo2 = 0; pVoo->ShadowFB = 1; xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Using shadowFB with Voodoo1 hardware.\n"); } from = X_DEFAULT; if (xf86ReturnOptValBool(pVoo->Options, OPTION_SHADOW_FB, FALSE)) { pVoo->ShadowFB = 1; pVoo->Accel = 0; } if (xf86ReturnOptValBool(pVoo->Options, OPTION_PASS_THROUGH, FALSE)) pVoo->PassThrough = 1; if (xf86ReturnOptValBool(pVoo->Options, OPTION_NOACCEL, FALSE)) { pVoo->ShadowFB = 1; pVoo->Accel = 0; } if(pScrn->depth == 24 && !pVoo->ShadowFB) { xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "ShadowFB is required for 24/32bit modes.\n"); pVoo->ShadowFB = 1; pVoo->Accel = 0; } /* MMIO at 0 , FB at 4Mb, Texture at 8Mb */ pVoo->PhysBase = PCI_REGION_BASE(pVoo->PciInfo, 0, REGION_MEM) + 0x400000; #ifndef XSERVER_LIBPCIACCESS pVoo->MMIO = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVoo->PciTag, pVoo->PciInfo->memBase[0], 0x400000); pVoo->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVoo->PciTag, pVoo->PciInfo->memBase[0] + 0x400000, 0x400000); #else { void** result = (void**)&pVoo->MMIO; int err = pci_device_map_range(pVoo->PciInfo, PCI_REGION_BASE(pVoo->PciInfo, 0, REGION_MEM), 0x400000, PCI_DEV_MAP_FLAG_WRITABLE, result); if (err) return FALSE; } { void** result = (void**)&pVoo->FBBase; int err = pci_device_map_range(pVoo->PciInfo, PCI_REGION_BASE(pVoo->PciInfo, 0, REGION_MEM) + 0x400000, 0x400000, PCI_DEV_MAP_FLAG_WRITABLE| PCI_DEV_MAP_FLAG_WRITE_COMBINE, result); if (err) return FALSE; } #endif VoodooHardwareInit(pVoo); /* * If the user has specified the amount of memory in the XF86Config * file, we respect that setting. */ if (pVoo->pEnt->device->videoRam != 0) { pScrn->videoRam = pVoo->pEnt->device->videoRam; from = X_CONFIG; } else { pScrn->videoRam = VoodooMemorySize(pVoo) * 1024 ; /* Sizer reports Mbytes */ from = X_PROBED; } xf86DrvMsg(pScrn->scrnIndex, from, "Video RAM: %d kB\n", pScrn->videoRam); /* Set up clock ranges so that the xf86ValidateModes() function will not fail a mode because of the clock requirement (because we don't use the clock value anyway) */ clockRanges = xnfcalloc(sizeof(ClockRange), 1); clockRanges->next = NULL; clockRanges->minClock = 10000; clockRanges->maxClock = 250000; /* 250MHz DAC */ clockRanges->clockIndex = -1; /* programmable */ if(pVoo->Voodoo2) { clockRanges->interlaceAllowed = TRUE; clockRanges->doubleScanAllowed = TRUE; maxwidth = min(1024, pScrn->display->virtualX); } else { clockRanges->interlaceAllowed = FALSE; clockRanges->doubleScanAllowed = FALSE; maxwidth = min(800, pScrn->display->virtualX); } /* Select valid modes from those available */ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, NULL, 256, 2048, pScrn->bitsPerPixel, 128, 768, pScrn->display->virtualX, pScrn->display->virtualY, pScrn->videoRam * 1024, LOOKUP_BEST_REFRESH); if (i == -1) { VoodooFreeRec(pScrn); return FALSE; } /* Prune the modes marked as invalid */ xf86PruneDriverModes(pScrn); /* If no valid modes, return */ if (i == 0 || pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); VoodooFreeRec(pScrn); return FALSE; } /* Set the current mode to the first in the list */ xf86SetCrtcForModes(pScrn, 0); pScrn->currentMode = pScrn->modes; /* Do some checking, we will not support a virtual framebuffer larger than the visible screen. */ if (pScrn->currentMode->HDisplay != pScrn->virtualX || pScrn->currentMode->VDisplay != pScrn->virtualY || pScrn->displayWidth != pScrn->virtualX) { /* FIXME: In this case we could use shadowfb and clip the drawing into the physical buffer */ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Virtual size doesn't equal display size. Forcing virtual size to equal display size.\n"); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "(Virtual size: %dx%d, Display size: %dx%d)\n", pScrn->virtualX, pScrn->virtualY, pScrn->currentMode->HDisplay, pScrn->currentMode->VDisplay); /* I'm not entirely sure this is "legal" but I hope so. */ pScrn->virtualX = pScrn->currentMode->HDisplay; pScrn->virtualY = pScrn->currentMode->VDisplay; pScrn->displayWidth = pScrn->virtualX; } /* Print the list of modes being used */ xf86PrintModes(pScrn); /* Set display resolution */ xf86SetDpi(pScrn, 0, 0); /* Load fb */ if (xf86LoadSubModule(pScrn, "fb") == NULL) { VoodooFreeRec(pScrn); return FALSE; } if (!xf86LoadSubModule(pScrn, "xaa")) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadowfb\n"); pVoo->Accel = 0; pVoo->ShadowFB = 1; } if(pVoo->ShadowFB) { /* Load the shadow framebuffer */ if (!xf86LoadSubModule(pScrn, "shadowfb")) { VoodooFreeRec(pScrn); return FALSE; } } return TRUE; }
Bool Permedia3Init(ScrnInfoPtr pScrn, DisplayModePtr mode, GLINTRegPtr pReg) { GLINTPtr pGlint = GLINTPTR(pScrn); CARD32 temp1, temp2, temp3, temp4; if ((pGlint->numMultiDevices == 2) || (IS_J2000)) { STOREREG(GCSRAperture, GCSRSecondaryGLINTMapEn); } if (pGlint->MultiAperture) { STOREREG(GMultGLINTAperture, pGlint->realWidth); STOREREG(GMultGLINT1, PCI_REGION_BASE(pGlint->MultiPciInfo[0], 2, REGION_MEM) & 0xFF800000); STOREREG(GMultGLINT2, PCI_REGION_BASE(pGlint->MultiPciInfo[1], 2, REGION_MEM) & 0xFF800000); } STOREREG(PM3MemBypassWriteMask, 0xffffffff); STOREREG(Aperture0, 0x00000000); STOREREG(Aperture1, 0x00000000); if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) STOREREG(DFIFODis, 0x00000001); STOREREG(FIFODis, 0x00000007); temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay; temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay; temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; STOREREG(PMHTotal, Shiftbpp(pScrn, mode->CrtcHTotal) - 1); STOREREG(PMHsEnd, Shiftbpp(pScrn, temp1 + temp3)); STOREREG(PMHsStart, Shiftbpp(pScrn, temp1)); STOREREG(PMHbEnd, Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay)); STOREREG(PMHgEnd, Shiftbpp(pScrn, mode->CrtcHTotal - mode->CrtcHDisplay)); STOREREG(PMScreenStride, Shiftbpp(pScrn, pScrn->displayWidth)); STOREREG(PMVTotal, mode->CrtcVTotal - 1); STOREREG(PMVsEnd, temp2 + temp4 - 1); STOREREG(PMVsStart, temp2 - 1); STOREREG(PMVbEnd, mode->CrtcVTotal - mode->CrtcVDisplay); switch (pScrn->bitsPerPixel) { case 8: STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_8BIT); STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_8BIT); STOREREG(PMVideoControl, 1 | (1 << 3) | (1 << 5) | (0 << 19)); break; case 16: #if X_BYTE_ORDER != X_BIG_ENDIAN STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT); STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT); #else STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_16BIT | PM3ByApertureMode_BYTESWAP_BADC); STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_16BIT | PM3ByApertureMode_BYTESWAP_BADC); #endif STOREREG(PMVideoControl, 1 | (1 << 3) | (1 << 5) | (1 << 19)); break; case 32: #if X_BYTE_ORDER != X_BIG_ENDIAN STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT); STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT); #else STOREREG(PM3ByAperture1Mode, PM3ByApertureMode_PIXELSIZE_32BIT | PM3ByApertureMode_BYTESWAP_DCBA); STOREREG(PM3ByAperture2Mode, PM3ByApertureMode_PIXELSIZE_32BIT | PM3ByApertureMode_BYTESWAP_DCBA); #endif STOREREG(PMVideoControl, 1 | (1 << 3) | (1 << 5) | (2 << 19)); break; } STOREREG(VClkCtl, GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC); STOREREG(PMScreenBase, 0x00000000); STOREREG(ChipConfig, GLINT_READ_REG(ChipConfig) & 0xFFFFFFFD); { /* Get the programmable clock values */ unsigned char m,n,p; /* Let's program the dot clock */ switch (pGlint->Chipset) { case PCI_VENDOR_3DLABS_CHIP_PERMEDIA4: case PCI_VENDOR_3DLABS_CHIP_R4: (void) PM4DAC_CalculateClock(mode->Clock, pGlint->RefClock, &m,&n,&p); break; case PCI_VENDOR_3DLABS_CHIP_PERMEDIA3: (void) PM3DAC_CalculateClock(mode->Clock, pGlint->RefClock, &m,&n,&p); break; case PCI_VENDOR_3DLABS_CHIP_GAMMA: switch (pGlint->MultiChip) { case PCI_CHIP_3DLABS_PERMEDIA3: (void) PM3DAC_CalculateClock(mode->Clock, pGlint->RefClock, &m,&n,&p); break; case PCI_CHIP_3DLABS_R4: (void) PM4DAC_CalculateClock(mode->Clock, pGlint->RefClock, &m,&n,&p); break; } break; } STOREDAC(PM3RD_DClk0PreScale, m); STOREDAC(PM3RD_DClk0FeedbackScale, n); STOREDAC(PM3RD_DClk0PostScale, p); } temp1 = 0; temp2 = 0; temp3 = 0; if (pGlint->UseFlatPanel) { temp2 |= PM3RD_DACControl_BLANK_PEDESTAL_ENABLE; temp3 |= PM3RD_MiscControl_VSB_OUTPUT_ENABLE; STOREREG(VSConfiguration, 0x06); STOREREG(VSBBase, 1<<14); } if (mode->Flags & V_PHSYNC) temp1 |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH; if (mode->Flags & V_PVSYNC) temp1 |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH; STOREREG(PM2VDACRDIndexControl, 0x00); STOREDAC(PM2VDACRDSyncControl, temp1); STOREDAC(PM2VDACRDDACControl, temp2); if (pScrn->rgbBits == 8) temp3 |= 0x01; /* 8bit DAC */ switch (pScrn->bitsPerPixel) { case 8: STOREDAC(PM2VDACRDPixelSize, 0x00); STOREDAC(PM2VDACRDColorFormat, 0x2E); break; case 16: temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE; STOREDAC(PM2VDACRDPixelSize, 0x01); if (pScrn->depth == 15) { STOREDAC(PM2VDACRDColorFormat, 0x61); } else { STOREDAC(PM2VDACRDColorFormat, 0x70); } break; case 24: temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE; STOREDAC(PM2VDACRDPixelSize, 0x04); STOREDAC(PM2VDACRDColorFormat, 0x20); break; case 32: temp3 |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE; if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) { temp3 |= 0x18; STOREDAC(PM2VDACRDOverlayKey, pScrn->colorKey); } STOREDAC(PM2VDACRDPixelSize, 0x02); STOREDAC(PM2VDACRDColorFormat, 0x20); break; } STOREDAC(PM2VDACRDMiscControl, temp3); STOREREG(PM3FifoControl, 0x905); /* Lower the default fifo threshold */ return(TRUE); }