/************************************************************************** * * I810InitMC * * Initialize the hardware motion compensation extension for this * hardware. The initialization routines want the address of the pointers * to the structures, not the address of the structures. This means we * allocate (or create static?) the pointer memory and pass that * address. This seems a little convoluted. * * We need to allocate memory for the device depended adaptor record. * This is what holds the pointers to all our device functions. * * We need to map the overlay registers into the drm. * * We need to map the surfaces into the drm. * * Inputs: * Screen pointer * * Outputs: * None, this calls the device independent screen initialization * function. * * Revisions: * **************************************************************************/ void I810InitMC(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); int i; /* Clear the Surface Allocation */ for(i=0; i<I810_MAX_SURFACES; i++) { pI810->surfaceAllocation[i] = 0; } /* Cursor is at a page boundary, Overlay regs are not, don't forget */ if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->CursorStart, 4096, DRM_AGP, 0, (drmAddress) &pI810->overlay_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(overlay) failed\n"); return; } if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->MC.Start, pI810->MC.Size, DRM_AGP, 0, (drmAddress) &pI810->mc_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(MC) failed\n"); return; } xf86XvMCScreenInit(pScreen, 1, ppAdapt); }
/* Add a map for the MMIO registers that will be accessed by any DRI-based clients. */ static GLboolean R128DRIMapInit(const DRIDriverContext *ctx) { R128InfoPtr info = ctx->driverPrivate; int flags; if (info->CCESecure) flags = DRM_READ_ONLY; else flags = 0; /* Map registers */ if (drmAddMap(ctx->drmFD, ctx->MMIOStart, ctx->MMIOSize, DRM_REGISTERS, flags, &info->registerHandle) < 0) { return GL_FALSE; } fprintf(stderr, "[drm] register handle = 0x%08x\n", info->registerHandle); return GL_TRUE; }
Bool I810DRIScreenInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); DRIInfoPtr pDRIInfo; I810DRIPtr pI810DRI; unsigned long tom; drm_handle_t agpHandle; drm_handle_t dcacheHandle; int sysmem_size = 0; int back_size = 0; unsigned int pitch_idx = 0; int bufs; int width = pScrn->displayWidth * pI810->cpp; int i; /* Hardware 3D rendering only implemented for 16bpp */ /* And it only works for 5:6:5 (Mark) */ if (pScrn->depth != 16) return FALSE; /* Check that the DRI, and DRM modules have been loaded by testing * for known symbols in each module. */ if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed (libdri.a too old)\n"); return FALSE; } /* adjust width first */ #define Elements(x) sizeof(x)/sizeof(*x) for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++) if (width <= i810_pitches[pitch_idx]) break; if (pitch_idx == Elements(i810_pitches)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Couldn't find depth/back buffer pitch"); DRICloseScreen(pScreen); return FALSE; } else { /* for tiled memory to work, the buffer needs to have the * number of lines as a multiple of 16 (the tile size), * - airlied */ int lines = (pScrn->virtualY + 15) / 16 * 16; back_size = i810_pitches[pitch_idx] * lines; back_size = ((back_size + 4096 - 1) / 4096) * 4096; } pScrn->displayWidth = i810_pitches[pitch_idx] / pI810->cpp; /* Check the DRI version */ { int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed because of a version mismatch.\n" "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n" "[dri] Disabling DRI.\n", major, minor, patch, DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); return FALSE; } } pDRIInfo = DRICreateInfoRec(); if (!pDRIInfo) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] DRICreateInfoRec failed. Disabling DRI.\n"); return FALSE; } /* pDRIInfo->wrap.ValidateTree = 0; */ /* pDRIInfo->wrap.PostValidateTree = 0; */ pI810->pDRIInfo = pDRIInfo; pI810->LockHeld = 0; pDRIInfo->drmDriverName = I810KernelDriverName; pDRIInfo->clientDriverName = I810ClientDriverName; if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { pDRIInfo->busIdString = DRICreatePCIBusID(pI810->PciInfo); } else { pDRIInfo->busIdString = malloc(64); if (pDRIInfo->busIdString) sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus), pI810->PciInfo->dev, pI810->PciInfo->func ); } if (!pDRIInfo->busIdString) { DRIDestroyInfoRec(pI810->pDRIInfo); pI810->pDRIInfo = NULL; return FALSE; } pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION; pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION; pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL; pDRIInfo->frameBufferPhysicalAddress = (pointer) pI810->LinearAddr; pDRIInfo->frameBufferSize = (((pScrn->displayWidth * pScrn->virtualY * pI810->cpp) + 4096 - 1) / 4096) * 4096; pDRIInfo->frameBufferStride = pScrn->displayWidth * pI810->cpp; pDRIInfo->ddxDrawableTableEntry = I810_MAX_DRAWABLES; if (SAREA_MAX_DRAWABLES < I810_MAX_DRAWABLES) pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; else pDRIInfo->maxDrawableTableEntry = I810_MAX_DRAWABLES; /* For now the mapping works by using a fixed size defined * in the SAREA header */ if (sizeof(XF86DRISAREARec) + sizeof(I810SAREARec) > SAREA_MAX) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] Data does not fit in SAREA\n"); return FALSE; } pDRIInfo->SAREASize = SAREA_MAX; if (!(pI810DRI = (I810DRIPtr) calloc(sizeof(I810DRIRec), 1))) { DRIDestroyInfoRec(pI810->pDRIInfo); pI810->pDRIInfo = NULL; return FALSE; } pDRIInfo->devPrivate = pI810DRI; pDRIInfo->devPrivateSize = sizeof(I810DRIRec); pDRIInfo->contextSize = sizeof(I810DRIContextRec); pDRIInfo->CreateContext = I810CreateContext; pDRIInfo->DestroyContext = I810DestroyContext; pDRIInfo->SwapContext = I810DRISwapContext; pDRIInfo->InitBuffers = I810DRIInitBuffers; pDRIInfo->MoveBuffers = I810DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; pDRIInfo->TransitionTo2d = I810DRITransitionTo2d; pDRIInfo->TransitionTo3d = I810DRITransitionTo3d; pDRIInfo->TransitionSingleToMulti3D = I810DRITransitionSingleToMulti3d; pDRIInfo->TransitionMultiToSingle3D = I810DRITransitionMultiToSingle3d; pDRIInfo->createDummyCtx = TRUE; pDRIInfo->createDummyCtxPriv = FALSE; /* This adds the framebuffer as a drm map *before* we have asked agp * to allocate it. Scary stuff, hold on... */ if (!DRIScreenInit(pScreen, pDRIInfo, &pI810->drmSubFD)) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] DRIScreenInit failed. Disabling DRI.\n"); free(pDRIInfo->devPrivate); pDRIInfo->devPrivate = NULL; DRIDestroyInfoRec(pI810->pDRIInfo); pI810->pDRIInfo = NULL; return FALSE; } /* Check the i810 DRM versioning */ { drmVersionPtr version; /* Check the DRM lib version. * drmGetLibVersion was not supported in version 1.0, so check for * symbol first to avoid possible crash or hang. */ if (xf86LoaderCheckSymbol("drmGetLibVersion")) { version = drmGetLibVersion(pI810->drmSubFD); } else { /* drmlib version 1.0.0 didn't have the drmGetLibVersion * entry point. Fake it by allocating a version record * via drmGetVersion and changing it to version 1.0.0 */ version = drmGetVersion(pI810->drmSubFD); version->version_major = 1; version->version_minor = 0; version->version_patchlevel = 0; } #define REQ_MAJ 1 #define REQ_MIN 1 if (version) { if (version->version_major != REQ_MAJ || version->version_minor < REQ_MIN) { /* incompatible drm library version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed because of a version mismatch.\n" "[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n" "[dri] Disabling DRI.\n", version->version_major, version->version_minor, version->version_patchlevel, REQ_MAJ, REQ_MIN); drmFreeVersion(version); I810DRICloseScreen(pScreen); return FALSE; } drmFreeVersion(version); } /* Check the i810 DRM version */ version = drmGetVersion(pI810->drmSubFD); if (version) { i810_drm_version = (version->version_major<<16) | version->version_minor; if (version->version_major != 1 || version->version_minor < 2) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed because of a version mismatch.\n" "[dri] i810.o kernel module version is %d.%d.%d but version 1.2.0 or greater is needed.\n" "[dri] Disabling DRI.\n", version->version_major, version->version_minor, version->version_patchlevel); I810DRICloseScreen(pScreen); drmFreeVersion(version); return FALSE; } pI810->drmMinor = version->version_minor; drmFreeVersion(version); } } pI810DRI->regsSize = I810_REG_SIZE; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->MMIOAddr, pI810DRI->regsSize, DRM_REGISTERS, 0, (drmAddress) &pI810DRI->regs) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); DRICloseScreen(pScreen); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", (int)pI810DRI->regs); pI810->backHandle = DRM_AGP_NO_HANDLE; pI810->zHandle = DRM_AGP_NO_HANDLE; pI810->cursorHandle = DRM_AGP_NO_HANDLE; pI810->xvmcHandle = DRM_AGP_NO_HANDLE; pI810->sysmemHandle = DRM_AGP_NO_HANDLE; pI810->agpAcquired = FALSE; pI810->dcacheHandle = DRM_AGP_NO_HANDLE; /* Agp Support - Need this just to get the framebuffer. */ if (drmAgpAcquire(pI810->drmSubFD) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpAquire failed\n"); DRICloseScreen(pScreen); return FALSE; } pI810->agpAcquired = TRUE; if (drmAgpEnable(pI810->drmSubFD, 0) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpEnable failed\n"); DRICloseScreen(pScreen); return FALSE; } memset(&pI810->DcacheMem, 0, sizeof(I810MemRange)); memset(&pI810->BackBuffer, 0, sizeof(I810MemRange)); memset(&pI810->DepthBuffer, 0, sizeof(I810MemRange)); pI810->CursorPhysical = 0; pI810->CursorARGBPhysical = 0; /* Dcache - half the speed of normal ram, but has use as a Z buffer * under the DRI. */ drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, (drmAddress) &dcacheHandle); pI810->dcacheHandle = dcacheHandle; xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] dcacheHandle : 0x%x\n", (int)dcacheHandle); sysmem_size = pScrn->videoRam * 1024; if (dcacheHandle != DRM_AGP_NO_HANDLE) { if (back_size > 4 * 1024 * 1024) { xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Backsize is larger then 4 meg\n"); sysmem_size = sysmem_size - 2 * back_size; drmAgpFree(pI810->drmSubFD, dcacheHandle); pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; } else { sysmem_size = sysmem_size - back_size; } } else { sysmem_size = sysmem_size - 2 * back_size; } /* Max size is 48 without XvMC, 41 with 6 surfaces, 40 with 7 surfaces */ if (pI810->numSurfaces && (pI810->numSurfaces == 6)) { if (sysmem_size > (pI810->FbMapSize - 7 * 1024 * 1024)) { sysmem_size = (pI810->FbMapSize - 7 * 1024 * 1024); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "User requested more memory then fits in the agp aperture\n" "Truncating to %d bytes of memory\n", sysmem_size); } } if (pI810->numSurfaces && (pI810->numSurfaces == 7)) { if (sysmem_size > (pI810->FbMapSize - 8 * 1024 * 1024)) { sysmem_size = (pI810->FbMapSize - 8 * 1024 * 1024); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "User requested more memory then fits in the agp aperture\n" "Truncating to %d bytes of memory\n", sysmem_size); } } if (sysmem_size > pI810->FbMapSize) { sysmem_size = pI810->FbMapSize; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] User requested more memory then fits in the agp" " aperture\n\tTruncating to %d bytes of memory\n", sysmem_size); } sysmem_size -= 4096; /* remove 4k for the hw cursor */ sysmem_size -= 16384; /* remove 16k for the ARGB hw cursor */ pI810->SysMem.Start = 0; pI810->SysMem.Size = sysmem_size; pI810->SysMem.End = sysmem_size; tom = sysmem_size; pI810->SavedSysMem = pI810->SysMem; if (dcacheHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, dcacheHandle, pI810->DepthOffset) == 0) { memset(&pI810->DcacheMem, 0, sizeof(I810MemRange)); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: Found 4096K Z buffer memory\n"); pI810->DcacheMem.Start = pI810->DepthOffset; pI810->DcacheMem.Size = 1024 * 4096; pI810->DcacheMem.End = pI810->DcacheMem.Start + pI810->DcacheMem.Size; if (!I810AllocLow (&(pI810->DepthBuffer), &(pI810->DcacheMem), back_size)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Depth buffer allocation failed\n"); DRICloseScreen(pScreen); return FALSE; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: dcache bind failed\n"); drmAgpFree(pI810->drmSubFD, dcacheHandle); pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: no dcache memory found\n"); } drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, (drmAddress) &agpHandle); pI810->backHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->BackOffset) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Bound backbuffer memory\n"); pI810->BackBuffer.Start = pI810->BackOffset; pI810->BackBuffer.Size = back_size; pI810->BackBuffer.End = (pI810->BackBuffer.Start + pI810->BackBuffer.Size); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Unable to bind backbuffer. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Unable to allocate backbuffer memory. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } if (dcacheHandle == DRM_AGP_NO_HANDLE) { drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, (drmAddress) &agpHandle); pI810->zHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->DepthOffset) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Bound depthbuffer memory\n"); pI810->DepthBuffer.Start = pI810->DepthOffset; pI810->DepthBuffer.Size = back_size; pI810->DepthBuffer.End = (pI810->DepthBuffer.Start + pI810->DepthBuffer.Size); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Unable to bind depthbuffer. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } /* Now allocate and bind the agp space. This memory will include the * regular framebuffer as well as texture memory. */ drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, (drmAddress)&agpHandle); pI810->sysmemHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, 0) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Bound System Texture Memory\n"); } else { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to bind system texture memory. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } else { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to allocate system texture memory. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } /* Allocate 7 or 8MB for XvMC this is setup as follows to best use tiled regions and required surface pitches. (Numbers are adjusted if the AGP region is only 32MB For numSurfaces == 6 44 - 48MB = 4MB Fence, 8 Tiles wide 43 - 44MB = 1MB Fence, 8 Tiles wide 42 - 43MB = 1MB Fence, 4 Tiles wide 41 - 42MB = 1MB Fence, 4 Tiles wide For numSurfaces == 7 44 - 48MB = 4MB Fence, 8 Tiles wide 43 - 44MB = 1MB Fence, 8 Tiles wide 42.5 - 43MB = 0.5MB Fence, 8 Tiles wide 42 - 42.5MB = 0.5MB Fence, 4 Tiles wide 40 - 42MB = 2MB Fence, 4 Tiles wide */ if (pI810->numSurfaces) { if (pI810->numSurfaces == 6) { pI810->MC.Size = 7 * 1024 * 1024; pI810->MC.Start = pI810->FbMapSize - 7 * 1024 * 1024; } if (pI810->numSurfaces == 7) { pI810->MC.Size = 8 * 1024 * 1024; pI810->MC.Start = pI810->FbMapSize - 8 * 1024 * 1024; } drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL, (drmAddress) &agpHandle); pI810->xvmcHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->MC.Start) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: Allocated 7MB for HWMC\n"); pI810->MC.End = pI810->MC.Start + pI810->MC.Size; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC bind failed\n"); pI810->MC.Start = 0; pI810->MC.Size = 0; pI810->MC.End = 0; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC alloc failed\n"); pI810->MC.Start = 0; pI810->MC.Size = 0; pI810->MC.End = 0; } pI810->xvmcContext = 0; } drmAgpAlloc(pI810->drmSubFD, 4096, 2, (unsigned long *)&pI810->CursorPhysical, (drmAddress) &agpHandle); pI810->cursorHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { tom = sysmem_size; if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: Allocated 4K for mouse cursor image\n"); pI810->CursorStart = tom; tom += 4096; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: cursor bind failed\n"); pI810->CursorPhysical = 0; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: cursor alloc failed\n"); pI810->CursorPhysical = 0; } drmAgpAlloc(pI810->drmSubFD, 16384, 2, (unsigned long *)&pI810->CursorARGBPhysical, (drmAddress) &agpHandle); pI810->cursorARGBHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: Allocated 16K for ARGB mouse cursor image\n"); pI810->CursorARGBStart = tom; tom += 16384; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: ARGB cursor bind failed\n"); pI810->CursorARGBPhysical = 0; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: ARGB cursor alloc failed\n"); pI810->CursorARGBPhysical = 0; } /* Steal some of the excess cursor space for the overlay regs. */ pI810->OverlayPhysical = pI810->CursorPhysical + 1024; pI810->OverlayStart = pI810->CursorStart + 1024; I810SetTiledMemory(pScrn, 1, pI810->DepthBuffer.Start, i810_pitches[pitch_idx], 8 * 1024 * 1024); I810SetTiledMemory(pScrn, 2, pI810->BackBuffer.Start, i810_pitches[pitch_idx], 8 * 1024 * 1024); /* These are for HWMC surfaces */ if (pI810->numSurfaces == 6) { I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 1024 * 1024); I810SetTiledMemory(pScrn, 4, pI810->MC.Start + 1024 * 1024, 512, 1024 * 1024); I810SetTiledMemory(pScrn, 5, pI810->MC.Start + 1024 * 1024 * 2, 1024, 1024 * 1024); I810SetTiledMemory(pScrn, 6, pI810->MC.Start + 1024 * 1024 * 3, 1024, 4 * 1024 * 1024); } if (pI810->numSurfaces == 7) { I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 2 * 1024 * 1024); I810SetTiledMemory(pScrn, 4, pI810->MC.Start + 2 * 1024 * 1024, 512, 512 * 1024); I810SetTiledMemory(pScrn, 5, pI810->MC.Start + 2 * 1024 * 1024 + 512 * 1024, 1024, 512 * 1024); I810SetTiledMemory(pScrn, 6, pI810->MC.Start + 3 * 1024 * 1024, 1024, 1 * 1024 * 1024); I810SetTiledMemory(pScrn, 7, pI810->MC.Start + 4 * 1024 * 1024, 1024, 4 * 1024 * 1024); } pI810->auxPitch = i810_pitches[pitch_idx]; pI810->auxPitchBits = i810_pitch_flags[pitch_idx]; pI810->SavedDcacheMem = pI810->DcacheMem; pI810DRI->backbufferSize = pI810->BackBuffer.Size; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BackBuffer.Start, pI810->BackBuffer.Size, DRM_AGP, 0, (drmAddress) &pI810DRI->backbuffer) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n"); DRICloseScreen(pScreen); return FALSE; } pI810DRI->depthbufferSize = pI810->DepthBuffer.Size; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->DepthBuffer.Start, pI810->DepthBuffer.Size, DRM_AGP, 0, (drmAddress) &pI810DRI->depthbuffer) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } /* Allocate FrontBuffer etc. */ if (!I810AllocateFront(pScrn)) { DRICloseScreen(pScreen); return FALSE; } /* Allocate buffer memory */ I810AllocHigh(&(pI810->BufferMem), &(pI810->SysMem), I810_DMA_BUF_NR * I810_DMA_BUF_SZ); xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Buffer map : %lx\n", pI810->BufferMem.Start); if (pI810->BufferMem.Start == 0 || pI810->BufferMem.End - pI810->BufferMem.Start > I810_DMA_BUF_NR * I810_DMA_BUF_SZ) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] Not enough memory for dma buffers. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BufferMem.Start, pI810->BufferMem.Size, DRM_AGP, 0, (drmAddress) &pI810->buffer_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } pI810DRI->agp_buffers = pI810->buffer_map; pI810DRI->agp_buf_size = pI810->BufferMem.Size; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start, pI810->LpRing->mem.Size, DRM_AGP, 0, (drmAddress) &pI810->ring_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(ring_map) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } /* Use the rest of memory for textures. */ pI810DRI->textureSize = pI810->SysMem.Size; i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS); if (i < I810_LOG_MIN_TEX_REGION_SIZE) i = I810_LOG_MIN_TEX_REGION_SIZE; pI810DRI->logTextureGranularity = i; pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i; /* truncate */ if (pI810DRI->textureSize < 512 * 1024) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Less then 512k memory left for textures. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } if (!I810AllocLow(&(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Texure memory allocation failed\n"); DRICloseScreen(pScreen); return FALSE; } if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->TexMem.Start, pI810->TexMem.Size, DRM_AGP, 0, (drmAddress) &pI810DRI->textures) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(textures) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } if ((bufs = drmAddBufs(pI810->drmSubFD, I810_DMA_BUF_NR, I810_DMA_BUF_SZ, DRM_AGP_BUFFER, pI810->BufferMem.Start)) <= 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] failure adding %d %d byte DMA buffers. Disabling DRI.\n", I810_DMA_BUF_NR, I810_DMA_BUF_SZ); DRICloseScreen(pScreen); return FALSE; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] added %d %d byte DMA buffers\n", bufs, I810_DMA_BUF_SZ); I810InitDma(pScrn); /* Okay now initialize the dma engine */ if (!pI810DRI->irq) { pI810DRI->irq = drmGetInterruptFromBusID(pI810->drmSubFD, ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus), pI810->PciInfo->dev, pI810->PciInfo->func ); if ((drmCtlInstHandler(pI810->drmSubFD, pI810DRI->irq)) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] failure adding irq handler, there is a device " "already using that irq\n Consider rearranging your " "PCI cards. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] dma control initialized, using IRQ %d\n", pI810DRI->irq); pI810DRI->deviceID = pI810->PciInfo->device_id; pI810DRI->width = pScrn->virtualX; pI810DRI->height = pScrn->virtualY; pI810DRI->mem = pScrn->videoRam * 1024; pI810DRI->cpp = pI810->cpp; pI810DRI->fbOffset = pI810->FrontBuffer.Start; pI810DRI->fbStride = pI810->auxPitch; pI810DRI->bitsPerPixel = pScrn->bitsPerPixel; pI810DRI->textureOffset = pI810->TexMem.Start; pI810DRI->backOffset = pI810->BackBuffer.Start; pI810DRI->depthOffset = pI810->DepthBuffer.Start; pI810DRI->ringOffset = pI810->LpRing->mem.Start; pI810DRI->ringSize = pI810->LpRing->mem.Size; pI810DRI->auxPitch = pI810->auxPitch; pI810DRI->auxPitchBits = pI810->auxPitchBits; pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized.\n"); pI810->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; return TRUE; }
void ViaInitXVMC(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); VIAPtr pVia = VIAPTR(pScrn); ViaXvMCPtr vXvMC = &(pVia->xvmc); volatile ViaXvMCSAreaPriv *saPriv; pVia->XvMCEnabled = 0; if ((pVia->Chipset == VIA_KM400) || (pVia->Chipset == VIA_CX700) || (pVia->Chipset == VIA_K8M890) || (pVia->Chipset == VIA_P4M900) || (pVia->Chipset == VIA_VX800) || (pVia->Chipset == VIA_VX855) || (pVia->Chipset == VIA_VX900)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] XvMC is not supported on this chipset.\n"); return; } if (!pVia->directRenderingType) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Cannot use XvMC without DRI!\n"); return; } if (((pVia->drmVerMajor <= 2) && (pVia->drmVerMinor < 4))) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Kernel drm is not compatible with XvMC.\n"); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Kernel drm version is %d.%d.%d; " "at least version 2.4.0 is needed.\n", pVia->drmVerMajor, pVia->drmVerMinor, pVia->drmVerPL); xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "[XvMC] Please update. Disabling XvMC.\n"); return; } vXvMC->mmioBase = pVia->registerHandle; if (drmAddMap(pVia->drmmode.fd, (drm_handle_t) pVia->FrameBufferBase, pVia->videoRambytes, DRM_FRAME_BUFFER, 0, &(vXvMC->fbBase)) < 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] drmAddMap(FB) failed. Disabling XvMC.\n"); return; } initViaXvMC(vXvMC); if (!xf86XvMCScreenInit(pScreen, 1, ((pVia->Chipset == VIA_PM800) ? ppAdapt_pga : ppAdapt))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[XvMC] XvMCScreenInit failed. Disabling XvMC.\n"); drmRmMap(pVia->drmmode.fd, vXvMC->fbBase); return; } #if (XvMCVersion > 1) || (XvMCRevision > 0) { DRIInfoPtr pDRIInfo = pVia->pDRIInfo; if (pVia->ChipId != PCI_CHIP_VT3259 && pVia->ChipId != PCI_CHIP_VT3364) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Registering chromeXvMC.\n"); xf86XvMCRegisterDRInfo(pScreen, "chromeXvMC", pDRIInfo->busIdString, VIAXVMC_MAJOR, VIAXVMC_MINOR, VIAXVMC_PL); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Registering chromeXvMCPro.\n"); xf86XvMCRegisterDRInfo(pScreen, "chromeXvMCPro", pDRIInfo->busIdString, VIAXVMC_MAJOR, VIAXVMC_MINOR, VIAXVMC_PL); } } #endif vXvMC->activePorts = 0; saPriv = (ViaXvMCSAreaPriv *) DRIGetSAREAPrivate(pScreen); saPriv->XvMCCtxNoGrabbed = ~0; XVMCLOCKPTR(saPriv, UNICHROME_LOCK_DECODER1)->lock = 0; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[XvMC] Initialized XvMC extension.\n"); pVia->XvMCEnabled = 1; }
/* Initialize the AGP state. Request memory for use in AGP space, and initialize the Rage 128 registers to point to that memory. */ static GLboolean R128DRIAgpInit(const DRIDriverContext *ctx) { unsigned char *R128MMIO = ctx->MMIOAddress; R128InfoPtr info = ctx->driverPrivate; unsigned long mode; unsigned int vendor, device; int ret; unsigned long cntl, chunk; int s, l; int flags; unsigned long agpBase; if (drmAgpAcquire(ctx->drmFD) < 0) { fprintf(stderr, "[agp] AGP not available\n"); return GL_FALSE; } /* Modify the mode if the default mode is not appropriate for this particular combination of graphics card and AGP chipset. */ mode = drmAgpGetMode(ctx->drmFD); /* Default mode */ vendor = drmAgpVendorId(ctx->drmFD); device = drmAgpDeviceId(ctx->drmFD); mode &= ~R128_AGP_MODE_MASK; switch (info->agpMode) { case 4: mode |= R128_AGP_4X_MODE; case 2: mode |= R128_AGP_2X_MODE; case 1: default: mode |= R128_AGP_1X_MODE; } fprintf(stderr, "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", mode, vendor, device, 0x1002, info->Chipset); if (drmAgpEnable(ctx->drmFD, mode) < 0) { fprintf(stderr, "[agp] AGP not enabled\n"); drmAgpRelease(ctx->drmFD); return GL_FALSE; } info->agpOffset = 0; if ((ret = drmAgpAlloc(ctx->drmFD, info->agpSize*1024*1024, 0, NULL, &info->agpMemHandle)) < 0) { fprintf(stderr, "[agp] Out of memory (%d)\n", ret); drmAgpRelease(ctx->drmFD); return GL_FALSE; } fprintf(stderr, "[agp] %d kB allocated with handle 0x%08x\n", info->agpSize*1024, info->agpMemHandle); if (drmAgpBind(ctx->drmFD, info->agpMemHandle, info->agpOffset) < 0) { fprintf(stderr, "[agp] Could not bind\n"); drmAgpFree(ctx->drmFD, info->agpMemHandle); drmAgpRelease(ctx->drmFD); return GL_FALSE; } /* Initialize the CCE ring buffer data */ info->ringStart = info->agpOffset; info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size; info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; info->ringReadOffset = info->ringStart + info->ringMapSize; info->ringReadMapSize = r128_drm_page_size; /* Reserve space for vertex/indirect buffers */ info->bufStart = info->ringReadOffset + info->ringReadMapSize; info->bufMapSize = info->bufSize*1024*1024; /* Reserve the rest for AGP textures */ info->agpTexStart = info->bufStart + info->bufMapSize; s = (info->agpSize*1024*1024 - info->agpTexStart); l = R128MinBits((s-1) / R128_NR_TEX_REGIONS); if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; info->agpTexMapSize = (s >> l) << l; info->log2AGPTexGran = l; if (info->CCESecure) flags = DRM_READ_ONLY; else flags = 0; if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, DRM_AGP, flags, &info->ringHandle) < 0) { fprintf(stderr, "[agp] Could not add ring mapping\n"); return GL_FALSE; } fprintf(stderr, "[agp] ring handle = 0x%08x\n", info->ringHandle); if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize, (drmAddressPtr)&info->ring) < 0) { fprintf(stderr, "[agp] Could not map ring\n"); return GL_FALSE; } fprintf(stderr, "[agp] Ring mapped at 0x%08lx\n", (unsigned long)info->ring); if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, DRM_AGP, flags, &info->ringReadPtrHandle) < 0) { fprintf(stderr, "[agp] Could not add ring read ptr mapping\n"); return GL_FALSE; } fprintf(stderr, "[agp] ring read ptr handle = 0x%08x\n", info->ringReadPtrHandle); if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, (drmAddressPtr)&info->ringReadPtr) < 0) { fprintf(stderr, "[agp] Could not map ring read ptr\n"); return GL_FALSE; } fprintf(stderr, "[agp] Ring read ptr mapped at 0x%08lx\n", (unsigned long)info->ringReadPtr); if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, DRM_AGP, 0, &info->bufHandle) < 0) { fprintf(stderr, "[agp] Could not add vertex/indirect buffers mapping\n"); return GL_FALSE; } fprintf(stderr, "[agp] vertex/indirect buffers handle = 0x%08lx\n", info->bufHandle); if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize, (drmAddressPtr)&info->buf) < 0) { fprintf(stderr, "[agp] Could not map vertex/indirect buffers\n"); return GL_FALSE; } fprintf(stderr, "[agp] Vertex/indirect buffers mapped at 0x%08lx\n", (unsigned long)info->buf); if (drmAddMap(ctx->drmFD, info->agpTexStart, info->agpTexMapSize, DRM_AGP, 0, &info->agpTexHandle) < 0) { fprintf(stderr, "[agp] Could not add AGP texture map mapping\n"); return GL_FALSE; } fprintf(stderr, "[agp] AGP texture map handle = 0x%08lx\n", info->agpTexHandle); if (drmMap(ctx->drmFD, info->agpTexHandle, info->agpTexMapSize, (drmAddressPtr)&info->agpTex) < 0) { fprintf(stderr, "[agp] Could not map AGP texture map\n"); return GL_FALSE; } fprintf(stderr, "[agp] AGP Texture map mapped at 0x%08lx\n", (unsigned long)info->agpTex); /* Initialize Rage 128's AGP registers */ cntl = INREG(R128_AGP_CNTL); cntl &= ~R128_AGP_APER_SIZE_MASK; switch (info->agpSize) { case 256: cntl |= R128_AGP_APER_SIZE_256MB; break; case 128: cntl |= R128_AGP_APER_SIZE_128MB; break; case 64: cntl |= R128_AGP_APER_SIZE_64MB; break; case 32: cntl |= R128_AGP_APER_SIZE_32MB; break; case 16: cntl |= R128_AGP_APER_SIZE_16MB; break; case 8: cntl |= R128_AGP_APER_SIZE_8MB; break; case 4: cntl |= R128_AGP_APER_SIZE_4MB; break; default: fprintf(stderr, "[agp] Illegal aperture size %d kB\n", info->agpSize*1024); return GL_FALSE; } agpBase = drmAgpBase(ctx->drmFD); OUTREG(R128_AGP_BASE, agpBase); OUTREG(R128_AGP_CNTL, cntl); /* Disable Rage 128's PCIGART registers */ chunk = INREG(R128_BM_CHUNK_0_VAL); chunk &= ~(R128_BM_PTR_FORCE_TO_PCI | R128_BM_PM4_RD_FORCE_TO_PCI | R128_BM_GLOBAL_FORCE_TO_PCI); OUTREG(R128_BM_CHUNK_0_VAL, chunk); OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */ return GL_TRUE; }
/* Initialize the screen-specific data structures for the DRI and the Rage 128. This is the main entry point to the device-specific initialization code. It calls device-independent DRI functions to create the DRI data structures and initialize the DRI state. */ static GLboolean R128DRIScreenInit(DRIDriverContext *ctx) { R128InfoPtr info = ctx->driverPrivate; R128DRIPtr pR128DRI; int err, major, minor, patch; drmVersionPtr version; drm_r128_sarea_t *pSAREAPriv; switch (ctx->bpp) { case 8: /* These modes are not supported (yet). */ case 15: case 24: fprintf(stderr, "[dri] R128DRIScreenInit failed (depth %d not supported). " "[dri] Disabling DRI.\n", ctx->bpp); return GL_FALSE; /* Only 16 and 32 color depths are supports currently. */ case 16: case 32: break; } r128_drm_page_size = getpagesize(); info->registerSize = ctx->MMIOSize; ctx->shared.SAREASize = SAREA_MAX; /* Note that drmOpen will try to load the kernel module, if needed. */ ctx->drmFD = drmOpen("r128", NULL ); if (ctx->drmFD < 0) { fprintf(stderr, "[drm] drmOpen failed\n"); return 0; } /* Check the r128 DRM version */ version = drmGetVersion(ctx->drmFD); if (version) { if (version->version_major != 2 || version->version_minor < 2) { /* incompatible drm version */ fprintf(stderr, "[dri] R128DRIScreenInit failed because of a version mismatch.\n" "[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n" "[dri] Disabling the DRI.\n", version->version_major, version->version_minor, version->version_patchlevel); drmFreeVersion(version); return GL_FALSE; } info->drmMinor = version->version_minor; drmFreeVersion(version); } if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", ctx->drmFD, ctx->pciBusID, strerror(-err)); return 0; } if (drmAddMap( ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM, DRM_CONTAINS_LOCK, &ctx->shared.hSAREA) < 0) { fprintf(stderr, "[drm] drmAddMap failed\n"); return 0; } fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", ctx->shared.SAREASize, ctx->shared.hSAREA); if (drmMap( ctx->drmFD, ctx->shared.hSAREA, ctx->shared.SAREASize, (drmAddressPtr)(&ctx->pSAREA)) < 0) { fprintf(stderr, "[drm] drmMap failed\n"); return 0; } memset(ctx->pSAREA, 0, ctx->shared.SAREASize); fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); /* Need to AddMap the framebuffer and mmio regions here: */ if (drmAddMap( ctx->drmFD, (drm_handle_t)ctx->FBStart, ctx->FBSize, DRM_FRAME_BUFFER, 0, &ctx->shared.hFrameBuffer) < 0) { fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); return 0; } fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", ctx->shared.hFrameBuffer); if (!R128MemoryInit(ctx)) return GL_FALSE; /* Initialize AGP */ if (!info->IsPCI && !R128DRIAgpInit(ctx)) { info->IsPCI = GL_TRUE; fprintf(stderr, "[agp] AGP failed to initialize -- falling back to PCI mode.\n"); fprintf(stderr, "[agp] Make sure you have the agpgart kernel module loaded.\n"); } /* Initialize PCIGART */ if (info->IsPCI && !R128DRIPciInit(ctx)) { return GL_FALSE; } /* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */ if (!R128DRIMapInit(ctx)) { return GL_FALSE; } /* Create a 'server' context so we can grab the lock for * initialization ioctls. */ if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); return 0; } DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); /* Initialize the kernel data structures */ if (!R128DRIKernelInit(ctx)) { return GL_FALSE; } /* Initialize the vertex buffers list */ if (!R128DRIBufInit(ctx)) { return GL_FALSE; } /* Initialize IRQ */ R128DRIIrqInit(ctx); /* Initialize and start the CCE if required */ R128DRICCEInit(ctx); /* Quick hack to clear the front & back buffers. Could also use * the clear ioctl to do this, but would need to setup hw state * first. */ drimemsetio((char *)ctx->FBAddress + info->frontOffset, 0, info->frontPitch * ctx->cpp * ctx->shared.virtualHeight ); drimemsetio((char *)ctx->FBAddress + info->backOffset, 0, info->backPitch * ctx->cpp * ctx->shared.virtualHeight ); pSAREAPriv = (drm_r128_sarea_t *)(((char*)ctx->pSAREA) + sizeof(drm_sarea_t)); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); /* This is the struct passed to radeon_dri.so for its initialization */ ctx->driverClientMsg = malloc(sizeof(R128DRIRec)); ctx->driverClientMsgSize = sizeof(R128DRIRec); pR128DRI = (R128DRIPtr)ctx->driverClientMsg; pR128DRI->deviceID = info->Chipset; pR128DRI->width = ctx->shared.virtualWidth; pR128DRI->height = ctx->shared.virtualHeight; pR128DRI->depth = ctx->bpp; pR128DRI->bpp = ctx->bpp; pR128DRI->IsPCI = info->IsPCI; pR128DRI->AGPMode = info->agpMode; pR128DRI->frontOffset = info->frontOffset; pR128DRI->frontPitch = info->frontPitch; pR128DRI->backOffset = info->backOffset; pR128DRI->backPitch = info->backPitch; pR128DRI->depthOffset = info->depthOffset; pR128DRI->depthPitch = info->depthPitch; pR128DRI->spanOffset = info->spanOffset; pR128DRI->textureOffset = info->textureOffset; pR128DRI->textureSize = info->textureSize; pR128DRI->log2TexGran = info->log2TexGran; pR128DRI->registerHandle = info->registerHandle; pR128DRI->registerSize = info->registerSize; pR128DRI->agpTexHandle = info->agpTexHandle; pR128DRI->agpTexMapSize = info->agpTexMapSize; pR128DRI->log2AGPTexGran = info->log2AGPTexGran; pR128DRI->agpTexOffset = info->agpTexStart; pR128DRI->sarea_priv_offset = sizeof(drm_sarea_t); return GL_TRUE; }
static GLboolean R128DRIPciInit(const DRIDriverContext *ctx) { R128InfoPtr info = ctx->driverPrivate; unsigned char *R128MMIO = ctx->MMIOAddress; u_int32_t chunk; int ret; int flags; info->agpOffset = 0; ret = drmScatterGatherAlloc(ctx->drmFD, info->agpSize*1024*1024, &info->pciMemHandle); if (ret < 0) { fprintf(stderr, "[pci] Out of memory (%d)\n", ret); return GL_FALSE; } fprintf(stderr, "[pci] %d kB allocated with handle 0x%08x\n", info->agpSize*1024, info->pciMemHandle); /* Initialize the CCE ring buffer data */ info->ringStart = info->agpOffset; info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size; info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; info->ringReadOffset = info->ringStart + info->ringMapSize; info->ringReadMapSize = r128_drm_page_size; /* Reserve space for vertex/indirect buffers */ info->bufStart = info->ringReadOffset + info->ringReadMapSize; info->bufMapSize = info->bufSize*1024*1024; flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { fprintf(stderr, "[pci] Could not add ring mapping\n"); return GL_FALSE; } fprintf(stderr, "[pci] ring handle = 0x%08lx\n", info->ringHandle); if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize, (drmAddressPtr)&info->ring) < 0) { fprintf(stderr, "[pci] Could not map ring\n"); return GL_FALSE; } fprintf(stderr, "[pci] Ring mapped at 0x%08lx\n", (unsigned long)info->ring); fprintf(stderr, "[pci] Ring contents 0x%08lx\n", *(unsigned long *)info->ring); if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { fprintf(stderr, "[pci] Could not add ring read ptr mapping\n"); return GL_FALSE; } fprintf(stderr, "[pci] ring read ptr handle = 0x%08lx\n", info->ringReadPtrHandle); if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, (drmAddressPtr)&info->ringReadPtr) < 0) { fprintf(stderr, "[pci] Could not map ring read ptr\n"); return GL_FALSE; } fprintf(stderr, "[pci] Ring read ptr mapped at 0x%08lx\n", (unsigned long)info->ringReadPtr); fprintf(stderr, "[pci] Ring read ptr contents 0x%08lx\n", *(unsigned long *)info->ringReadPtr); if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { fprintf(stderr, "[pci] Could not add vertex/indirect buffers mapping\n"); return GL_FALSE; } fprintf(stderr, "[pci] vertex/indirect buffers handle = 0x%08lx\n", info->bufHandle); if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize, (drmAddressPtr)&info->buf) < 0) { fprintf(stderr, "[pci] Could not map vertex/indirect buffers\n"); return GL_FALSE; } fprintf(stderr, "[pci] Vertex/indirect buffers mapped at 0x%08lx\n", (unsigned long)info->buf); fprintf(stderr, "[pci] Vertex/indirect buffers contents 0x%08lx\n", *(unsigned long *)info->buf); if (!info->IsPCI) { /* This is really an AGP card, force PCI GART mode */ chunk = INREG(R128_BM_CHUNK_0_VAL); chunk |= (R128_BM_PTR_FORCE_TO_PCI | R128_BM_PM4_RD_FORCE_TO_PCI | R128_BM_GLOBAL_FORCE_TO_PCI); OUTREG(R128_BM_CHUNK_0_VAL, chunk); OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */ } return GL_TRUE; }
int main(int argc, char **argv) { int c; int r = 0; int fd = -1; drm_handle_t handle; void *address; char *pt; unsigned long count; unsigned long offset; unsigned long size; drm_context_t context; int loops; char buf[1024]; int i; drmBufInfoPtr info; drmBufMapPtr bufs; drmLockPtr lock; int secs; while ((c = getopt(argc, argv, "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF) switch (c) { case 'F': count = strtoul(optarg, NULL, 0); if (!fork()) { dup(fd); sleep(count); } close(fd); break; case 'v': getversion(fd); break; case 'X': if ((r = drmCreateContext(fd, &context))) { drmError(r, argv[0]); return 1; } printf( "Got %d\n", context); break; case 'S': process_sigio(optarg); break; case 'C': if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) { drmError(r, argv[0]); return 1; } break; case 'c': if ((r = drmSetBusid(fd,optarg))) { drmError(r, argv[0]); return 1; } break; case 'o': if ((fd = drmOpen(optarg, NULL)) < 0) { drmError(fd, argv[0]); return 1; } break; case 'O': if ((fd = drmOpen(NULL, optarg)) < 0) { drmError(fd, argv[0]); return 1; } break; case 'B': /* Test buffer allocation */ count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, &pt, 0); secs = strtoul(pt+1, NULL, 0); { drmDMAReq dma; int *indices, *sizes; indices = alloca(sizeof(*indices) * count); sizes = alloca(sizeof(*sizes) * count); dma.context = context; dma.send_count = 0; dma.request_count = count; dma.request_size = size; dma.request_list = indices; dma.request_sizes = sizes; dma.flags = DRM_DMA_WAIT; if ((r = drmDMA(fd, &dma))) { drmError(r, argv[0]); return 1; } for (i = 0; i < dma.granted_count; i++) { printf("%5d: index = %d, size = %d\n", i, dma.request_list[i], dma.request_sizes[i]); } sleep(secs); drmFreeBufs(fd, dma.granted_count, indices); } break; case 'b': count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) { drmError(r, argv[0]); return 1; } if (!(info = drmGetBufInfo(fd))) { drmError(0, argv[0]); return 1; } for (i = 0; i < info->count; i++) { printf("%5d buffers of size %6d (low = %d, high = %d)\n", info->list[i].count, info->list[i].size, info->list[i].low_mark, info->list[i].high_mark); } if ((r = drmMarkBufs(fd, 0.50, 0.80))) { drmError(r, argv[0]); return 1; } if (!(info = drmGetBufInfo(fd))) { drmError(0, argv[0]); return 1; } for (i = 0; i < info->count; i++) { printf("%5d buffers of size %6d (low = %d, high = %d)\n", info->list[i].count, info->list[i].size, info->list[i].low_mark, info->list[i].high_mark); } printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); #if 1 if (!(bufs = drmMapBufs(fd))) { drmError(0, argv[0]); return 1; } printf("===============================\n"); printf( "%d bufs\n", bufs->count); for (i = 0; i < bufs->count; i++) { printf( " %4d: %8d bytes at %p\n", i, bufs->list[i].total, bufs->list[i].address); } printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); #endif break; case 'f': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); handle = 0; if ((r = drmAddMap(fd, offset, size, DRM_FRAME_BUFFER, 0, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); break; case 'r': case 'R': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); handle = 0; if ((r = drmAddMap(fd, offset, size, DRM_REGISTERS, c == 'R' ? DRM_READ_ONLY : 0, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); break; case 's': size = strtoul(optarg, &pt, 0); handle = 0; if ((r = drmAddMap(fd, 0, size, DRM_SHM, DRM_CONTAINS_LOCK, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%04lx byte shm added at 0x%08lx\n", size, handle); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vm"); system(buf); break; case 'P': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx mapped at %p for pid %d\n", offset, size, address, getpid()); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); mprotect((void *)offset, size, PROT_READ); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); break; case 'w': case 'W': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx mapped at %p for pid %d\n", offset, size, address, getpid()); printf("===== /proc/%d/maps =====\n", getpid()); snprintf(buf, sizeof(buf), "cat /proc/%d/maps", getpid()); system(buf); printf("===== /proc/dri/0/mem =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem"); system(buf); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); printf("===== READING =====\n"); for (i = 0; i < 0x10; i++) printf("%02x ", (unsigned int)((unsigned char *)address)[i]); printf("\n"); if (c == 'w') { printf("===== WRITING =====\n"); for (i = 0; i < size; i+=2) { ((char *)address)[i] = i & 0xff; ((char *)address)[i+1] = i & 0xff; } } printf("===== READING =====\n"); for (i = 0; i < 0x10; i++) printf("%02x ", (unsigned int)((unsigned char *)address)[i]); printf("\n"); printf("===== /proc/dri/0/vma =====\n"); snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma"); system(buf); break; case 'L': context = strtoul(optarg, &pt, 0); offset = strtoul(pt+1, &pt, 0); size = strtoul(pt+1, &pt, 0); loops = strtoul(pt+1, NULL, 0); address = NULL; if ((r = drmMap(fd, offset, size, &address))) { drmError(r, argv[0]); return 1; } lock = address; #if 1 { int counter = 0; struct timeval loop_start, loop_end; struct timeval lock_start, lock_end; double wt; #define HISTOSIZE 9 int histo[HISTOSIZE]; int output = 0; int fast = 0; if (loops < 0) { loops = -loops; ++output; } for (i = 0; i < HISTOSIZE; i++) histo[i] = 0; gettimeofday(&loop_start, NULL); for (i = 0; i < loops; i++) { gettimeofday(&lock_start, NULL); DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast); gettimeofday(&lock_end, NULL); DRM_UNLOCK(fd,lock,context); ++counter; wt = usec(&lock_end, &lock_start); if (wt <= 2.5) ++histo[8]; if (wt < 5.0) ++histo[0]; else if (wt < 50.0) ++histo[1]; else if (wt < 500.0) ++histo[2]; else if (wt < 5000.0) ++histo[3]; else if (wt < 50000.0) ++histo[4]; else if (wt < 500000.0) ++histo[5]; else if (wt < 5000000.0) ++histo[6]; else ++histo[7]; if (output) printf( "%.2f uSec, %d fast\n", wt, fast); } gettimeofday(&loop_end, NULL); printf( "Average wait time = %.2f usec, %d fast\n", usec(&loop_end, &loop_start) / counter, fast); printf( "%9d <= 2.5 uS\n", histo[8]); printf( "%9d < 5 uS\n", histo[0]); printf( "%9d < 50 uS\n", histo[1]); printf( "%9d < 500 uS\n", histo[2]); printf( "%9d < 5000 uS\n", histo[3]); printf( "%9d < 50000 uS\n", histo[4]); printf( "%9d < 500000 uS\n", histo[5]); printf( "%9d < 5000000 uS\n", histo[6]); printf( "%9d >= 5000000 uS\n", histo[7]); } #else printf( "before lock: 0x%08x\n", lock->lock); printf( "lock: 0x%08x\n", lock->lock); sleep(5); printf( "unlock: 0x%08x\n", lock->lock); #endif break; default: fprintf( stderr, "Usage: drmstat [options]\n" ); return 1; } return r; }