via_dri.c revision 8aedb4f6
17e6fb56fSmrg/* 27e6fb56fSmrg * Copyright 2005-2008 The Openchrome Project [openchrome.org] 37e6fb56fSmrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 47e6fb56fSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 57e6fb56fSmrg * 67e6fb56fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 77e6fb56fSmrg * copy of this software and associated documentation files (the "Software"), 87e6fb56fSmrg * to deal in the Software without restriction, including without limitation 97e6fb56fSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 107e6fb56fSmrg * and/or sell copies of the Software, and to permit persons to whom the 117e6fb56fSmrg * Software is furnished to do so, subject to the following conditions: 127e6fb56fSmrg * 137e6fb56fSmrg * The above copyright notice and this permission notice (including the 147e6fb56fSmrg * next paragraph) shall be included in all copies or substantial portions 157e6fb56fSmrg * of the Software. 167e6fb56fSmrg * 177e6fb56fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 187e6fb56fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197e6fb56fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 207e6fb56fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 217e6fb56fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 227e6fb56fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 237e6fb56fSmrg * DEALINGS IN THE SOFTWARE. 247e6fb56fSmrg */ 257e6fb56fSmrg 267e6fb56fSmrg#ifdef HAVE_CONFIG_H 277e6fb56fSmrg#include "config.h" 287e6fb56fSmrg#endif 297e6fb56fSmrg 307e6fb56fSmrg#include "xf86.h" 317e6fb56fSmrg#include "xf86_OSproc.h" 327e6fb56fSmrg#include "xf86Priv.h" 337e6fb56fSmrg 347e6fb56fSmrg#include "xf86Pci.h" 357e6fb56fSmrg 367e6fb56fSmrg#define _XF86DRI_SERVER_ 377e6fb56fSmrg#include "GL/glxtokens.h" 387e6fb56fSmrg#include "sarea.h" 397e6fb56fSmrg 407e6fb56fSmrg#include "via_driver.h" 417e6fb56fSmrg#include "via_drm.h" 427e6fb56fSmrg#include "via_dri.h" 437e6fb56fSmrg#include "xf86drm.h" 447e6fb56fSmrg 457e6fb56fSmrg#ifndef DRIINFO_MAJOR_VERSION 467e6fb56fSmrg#define DRIINFO_MAJOR_VERSION 4 477e6fb56fSmrg#endif 487e6fb56fSmrg#ifndef DRIINFO_MINOR_VERSION 497e6fb56fSmrg#define DRIINFO_MINOR_VERSION 0 507e6fb56fSmrg#endif 517e6fb56fSmrg 527e6fb56fSmrg#define VIDEO 0 537e6fb56fSmrg#define AGP 1 547e6fb56fSmrg#define AGP_CMDBUF_PAGES 512 557e6fb56fSmrg#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES) 567e6fb56fSmrg#define VIA_AGP_MODE_MASK 0x17 577e6fb56fSmrg#define VIA_AGPv3_MODE 0x08 587e6fb56fSmrg#define VIA_AGPv3_8X_MODE 0x02 597e6fb56fSmrg#define VIA_AGPv3_4X_MODE 0x01 607e6fb56fSmrg#define VIA_AGP_4X_MODE 0x04 617e6fb56fSmrg#define VIA_AGP_2X_MODE 0x02 627e6fb56fSmrg#define VIA_AGP_1X_MODE 0x01 637e6fb56fSmrg#define VIA_AGP_FW_MODE 0x10 647e6fb56fSmrg 657e6fb56fSmrgextern void GlxSetVisualConfigs(int nconfigs, 667e6fb56fSmrg __GLXvisualConfig * configs, 677e6fb56fSmrg void **configprivs); 687e6fb56fSmrg 697e6fb56fSmrgtypedef struct 707e6fb56fSmrg{ 717e6fb56fSmrg int major; 727e6fb56fSmrg int minor; 737e6fb56fSmrg int patchlevel; 747e6fb56fSmrg} ViaDRMVersion; 757e6fb56fSmrg 767e6fb56fSmrgstatic char VIAKernelDriverName[] = "via"; 777e6fb56fSmrgstatic char VIAClientDriverName[] = "unichrome"; 787e6fb56fSmrgstatic const ViaDRMVersion drmExpected = { 1, 3, 0 }; 797e6fb56fSmrgstatic const ViaDRMVersion drmCompat = { 2, 0, 0 }; 807e6fb56fSmrg 817e6fb56fSmrgstatic Bool VIAInitVisualConfigs(ScreenPtr pScreen); 827e6fb56fSmrgstatic Bool VIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia); 837e6fb56fSmrg 847e6fb56fSmrgstatic Bool VIACreateContext(ScreenPtr pScreen, VisualPtr visual, 857e6fb56fSmrg drm_context_t hwContext, void *pVisualConfigPriv, 867e6fb56fSmrg DRIContextType contextStore); 877e6fb56fSmrgstatic void VIADestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 887e6fb56fSmrg DRIContextType contextStore); 897e6fb56fSmrgstatic void VIADRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 907e6fb56fSmrg DRIContextType readContextType, 917e6fb56fSmrg void *readContextStore, 927e6fb56fSmrg DRIContextType writeContextType, 937e6fb56fSmrg void *writeContextStore); 947e6fb56fSmrgstatic void VIADRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); 957e6fb56fSmrgstatic void VIADRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 967e6fb56fSmrg RegionPtr prgnSrc, CARD32 index); 977e6fb56fSmrg 988aedb4f6Smrgvoid 998aedb4f6SmrgkickVblank(ScrnInfoPtr pScrn) 1008aedb4f6Smrg{ 1018aedb4f6Smrg /* 1028aedb4f6Smrg * Switching mode will clear registers that make vblank 1038aedb4f6Smrg * interrupts happen. If the driver thinks interrupts 1048aedb4f6Smrg * are enabled, make sure vblank interrupts go through. 1058aedb4f6Smrg * registers are not documented in VIA docs. 1068aedb4f6Smrg */ 1078aedb4f6Smrg VIAPtr pVia = VIAPTR(pScrn); 1088aedb4f6Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1098aedb4f6Smrg VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; 1108aedb4f6Smrg 1118aedb4f6Smrg if (pVIADRI->irqEnabled) 1128aedb4f6Smrg hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x30); 1138aedb4f6Smrg} 1147e6fb56fSmrg 1157e6fb56fSmrgstatic void 1167e6fb56fSmrgVIADRIIrqInit(ScrnInfoPtr pScrn, VIADRIPtr pVIADRI) 1177e6fb56fSmrg{ 1187e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 1197e6fb56fSmrg 1207e6fb56fSmrg pVIADRI->irqEnabled = drmGetInterruptFromBusID 1218aedb4f6Smrg (pVia->drmmode.fd, 1228aedb4f6Smrg#ifdef HAVE_PCIACCESS 1237e6fb56fSmrg ((pVia->PciInfo->domain << 8) | pVia->PciInfo->bus), 1247e6fb56fSmrg pVia->PciInfo->dev, pVia->PciInfo->func 1257e6fb56fSmrg#else 1267e6fb56fSmrg ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum, 1277e6fb56fSmrg ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum, 1287e6fb56fSmrg ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum 1297e6fb56fSmrg#endif 1307e6fb56fSmrg ); 1318aedb4f6Smrg if ((drmCtlInstHandler(pVia->drmmode.fd, pVIADRI->irqEnabled))) { 1327e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1337e6fb56fSmrg "[drm] Failure adding IRQ handler. " 1347e6fb56fSmrg "Falling back to IRQ-free operation.\n"); 1357e6fb56fSmrg pVIADRI->irqEnabled = 0; 1367e6fb56fSmrg } 1377e6fb56fSmrg 1387e6fb56fSmrg if (pVIADRI->irqEnabled) 1397e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1407e6fb56fSmrg "[drm] IRQ handler installed, using IRQ %d.\n", 1417e6fb56fSmrg pVIADRI->irqEnabled); 1427e6fb56fSmrg} 1437e6fb56fSmrg 1447e6fb56fSmrgstatic void 1457e6fb56fSmrgVIADRIIrqExit(ScrnInfoPtr pScrn, VIADRIPtr pVIADRI) 1467e6fb56fSmrg{ 1477e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 1487e6fb56fSmrg 1497e6fb56fSmrg if (pVIADRI->irqEnabled) { 1508aedb4f6Smrg if (drmCtlUninstHandler(pVia->drmmode.fd)) { 1517e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1527e6fb56fSmrg "[drm] IRQ handler uninstalled.\n"); 1537e6fb56fSmrg } else { 1547e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1557e6fb56fSmrg "[drm] Could not uninstall IRQ handler.\n"); 1567e6fb56fSmrg } 1577e6fb56fSmrg } 1587e6fb56fSmrg} 1597e6fb56fSmrg 1607e6fb56fSmrgvoid 1617e6fb56fSmrgVIADRIRingBufferCleanup(ScrnInfoPtr pScrn) 1627e6fb56fSmrg{ 1637e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 1647e6fb56fSmrg VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; 1657e6fb56fSmrg 1667e6fb56fSmrg if (pVIADRI->ringBufActive) { 1677e6fb56fSmrg drm_via_dma_init_t ringBufInit; 1687e6fb56fSmrg 1697e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1707e6fb56fSmrg "[drm] Cleaning up DMA ring-buffer.\n"); 1717e6fb56fSmrg ringBufInit.func = VIA_CLEANUP_DMA; 1728aedb4f6Smrg if (drmCommandWrite(pVia->drmmode.fd, DRM_VIA_DMA_INIT, &ringBufInit, 1737e6fb56fSmrg sizeof(ringBufInit))) { 1747e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1757e6fb56fSmrg "[drm] Failed to clean up DMA ring-buffer: %d\n", errno); 1767e6fb56fSmrg } 1777e6fb56fSmrg pVIADRI->ringBufActive = 0; 1787e6fb56fSmrg } 1797e6fb56fSmrg} 1807e6fb56fSmrg 1817e6fb56fSmrgBool 1827e6fb56fSmrgVIADRIRingBufferInit(ScrnInfoPtr pScrn) 1837e6fb56fSmrg{ 1847e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 1857e6fb56fSmrg VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; 1867e6fb56fSmrg 1877e6fb56fSmrg if (pVIADRI->ringBufActive) 1887e6fb56fSmrg return TRUE; 1897e6fb56fSmrg 1907e6fb56fSmrg if (pVia->agpEnable) { 1917e6fb56fSmrg drm_via_dma_init_t ringBufInit; 1927e6fb56fSmrg 1937e6fb56fSmrg if ((pVia->drmVerMajor == 1) && (pVia->drmVerMinor <= 3)) 1947e6fb56fSmrg return FALSE; 1957e6fb56fSmrg 1967e6fb56fSmrg /* 1978aedb4f6Smrg * Info from code-snippet on DRI-DEVEL list; Erdi Chen. 1987e6fb56fSmrg */ 1997e6fb56fSmrg 2007e6fb56fSmrg switch (pVia->ChipId) { 2017e6fb56fSmrg case PCI_CHIP_VT3314: 2027e6fb56fSmrg case PCI_CHIP_VT3259: 2037e6fb56fSmrg pVIADRI->reg_pause_addr = 0x40c; 2047e6fb56fSmrg break; 2057e6fb56fSmrg default: 2067e6fb56fSmrg pVIADRI->reg_pause_addr = 0x418; 2077e6fb56fSmrg break; 2087e6fb56fSmrg } 2097e6fb56fSmrg 2107e6fb56fSmrg ringBufInit.offset = pVia->agpSize; 2117e6fb56fSmrg ringBufInit.size = AGP_CMDBUF_SIZE; 2127e6fb56fSmrg ringBufInit.reg_pause_addr = pVIADRI->reg_pause_addr; 2137e6fb56fSmrg ringBufInit.func = VIA_INIT_DMA; 2147e6fb56fSmrg 2158aedb4f6Smrg if (drmCommandWrite(pVia->drmmode.fd, DRM_VIA_DMA_INIT, &ringBufInit, 2167e6fb56fSmrg sizeof(ringBufInit))) { 2177e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2187e6fb56fSmrg "[drm] Failed to initialize DMA ring-buffer: %d\n", 2197e6fb56fSmrg errno); 2207e6fb56fSmrg return FALSE; 2217e6fb56fSmrg } 2227e6fb56fSmrg 2237e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2247e6fb56fSmrg "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP " 2257e6fb56fSmrg "offset 0x%lx.\n", ringBufInit.size, ringBufInit.offset); 2267e6fb56fSmrg pVIADRI->ringBufActive = 1; 2277e6fb56fSmrg } 2287e6fb56fSmrg return TRUE; 2297e6fb56fSmrg} 2307e6fb56fSmrg 2317e6fb56fSmrgstatic Bool 2327e6fb56fSmrgVIASetAgpMode(ScrnInfoPtr pScrn) 2337e6fb56fSmrg{ 2347e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 2358aedb4f6Smrg CARD32 mode = drmAgpGetMode(pVia->drmmode.fd); 2368aedb4f6Smrg unsigned int vendor = drmAgpVendorId(pVia->drmmode.fd); 2378aedb4f6Smrg unsigned int device = drmAgpDeviceId(pVia->drmmode.fd); 2387e6fb56fSmrg 2397e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Detected AGP " 2407e6fb56fSmrg "vendor 0x%04x, device 0x%04x\n", vendor, device); 2417e6fb56fSmrg 2427e6fb56fSmrg mode &= ~VIA_AGP_MODE_MASK; 2437e6fb56fSmrg if (mode & VIA_AGPv3_MODE) { 2447e6fb56fSmrg mode |= VIA_AGPv3_8X_MODE; 2457e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Found AGP v3 " 2467e6fb56fSmrg "compatible device. Trying AGP 8X mode.\n"); 2477e6fb56fSmrg } else { 2487e6fb56fSmrg mode |= VIA_AGP_4X_MODE; 2497e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Didn't find any AGP v3 " 2507e6fb56fSmrg "compatible device. Trying AGP 4X mode.\n"); 2517e6fb56fSmrg } 2527e6fb56fSmrg 2537e6fb56fSmrg mode |= VIA_AGP_FW_MODE; 2547e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2557e6fb56fSmrg "[drm] Trying to enable AGP fast writes.\n"); 2567e6fb56fSmrg 2578aedb4f6Smrg if (drmAgpEnable(pVia->drmmode.fd, mode) < 0) 2587e6fb56fSmrg return FALSE; 2597e6fb56fSmrg return TRUE; 2607e6fb56fSmrg} 2617e6fb56fSmrg 2627e6fb56fSmrgstatic Bool 2638aedb4f6SmrgVIADRIAgpInit(ScrnInfoPtr pScrn) 2647e6fb56fSmrg{ 2658aedb4f6Smrg unsigned long agpCmdSize, agp_phys; 2668aedb4f6Smrg VIAPtr pVia = VIAPTR(pScrn); 2678aedb4f6Smrg drm_handle_t handle; 2687e6fb56fSmrg drmAddress agpaddr; 2698aedb4f6Smrg drm_via_agp_t agp; 2708aedb4f6Smrg int agpPages; 2717e6fb56fSmrg 2727e6fb56fSmrg pVia->agpSize = 0; 2738aedb4f6Smrg if (drmAgpAcquire(pVia->drmmode.fd) < 0) { 2748aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] drmAgpAcquire failed %d\n", 2757e6fb56fSmrg errno); 2767e6fb56fSmrg return FALSE; 2777e6fb56fSmrg } 2787e6fb56fSmrg 2798aedb4f6Smrg if (!VIASetAgpMode(pScrn)) { 2808aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] VIASetAgpMode failed\n"); 2818aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 2827e6fb56fSmrg return FALSE; 2837e6fb56fSmrg } 2847e6fb56fSmrg 2857e6fb56fSmrg agpCmdSize = (pVia->agpEnable) ? AGP_CMDBUF_SIZE : 0; 2867e6fb56fSmrg if (pVia->agpMem * 1024 < agpCmdSize + AGP_PAGE_SIZE) { 2877e6fb56fSmrg pVia->agpMem = (agpCmdSize + AGP_PAGE_SIZE) / 1024; 2888aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2897e6fb56fSmrg "[drm] Forcing AGP size to %d kB\n", pVia->agpMem); 2907e6fb56fSmrg } 2917e6fb56fSmrg 2927e6fb56fSmrg agpPages = (pVia->agpMem * 1024 + AGP_PAGE_SIZE - 1) / AGP_PAGE_SIZE; 2938aedb4f6Smrg if (drmAgpAlloc(pVia->drmmode.fd, agpPages * AGP_PAGE_SIZE, 2947e6fb56fSmrg 0, &agp_phys, &pVia->agpHandle) < 0) { 2958aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] drmAgpAlloc failed\n"); 2968aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 2977e6fb56fSmrg return FALSE; 2987e6fb56fSmrg } 2997e6fb56fSmrg 3008aedb4f6Smrg if (drmAgpBind(pVia->drmmode.fd, pVia->agpHandle, 0) < 0) { 3018aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] drmAgpBind failed\n"); 3028aedb4f6Smrg drmAgpFree(pVia->drmmode.fd, pVia->agpHandle); 3038aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 3047e6fb56fSmrg return FALSE; 3057e6fb56fSmrg } 3067e6fb56fSmrg 3077e6fb56fSmrg /* 3087e6fb56fSmrg * Place the ring-buffer last in the AGP region, and restrict the 3097e6fb56fSmrg * public map not to include the buffer for security reasons. 3107e6fb56fSmrg */ 3117e6fb56fSmrg pVia->agpSize = agpPages * AGP_PAGE_SIZE - agpCmdSize; 3128aedb4f6Smrg pVia->agpAddr = drmAgpBase(pVia->drmmode.fd); 3138aedb4f6Smrg agp.offset = 0; 3148aedb4f6Smrg agp.size = pVia->agpSize; 3158aedb4f6Smrg if (drmCommandWrite(pVia->drmmode.fd, DRM_VIA_AGP_INIT, &agp, 3168aedb4f6Smrg sizeof(drm_via_agp_t)) < 0) { 3178aedb4f6Smrg drmAgpUnbind(pVia->drmmode.fd, pVia->agpHandle); 3188aedb4f6Smrg drmAgpFree(pVia->drmmode.fd, pVia->agpHandle); 3198aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 3208aedb4f6Smrg return FALSE; 3218aedb4f6Smrg } 3228aedb4f6Smrg 3238aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] drmAgpEnabled succeeded\n"); 3247e6fb56fSmrg 3258aedb4f6Smrg /* Allocate all of AGP memory */ 3268aedb4f6Smrg if (drmAddMap(pVia->drmmode.fd, 0, pVia->agpSize, 3278aedb4f6Smrg DRM_AGP, 0, &handle) < 0) { 3288aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3297e6fb56fSmrg "[drm] Failed to map public agp area.\n"); 3308aedb4f6Smrg pVia->agpSize = 0; 3318aedb4f6Smrg drmAgpUnbind(pVia->drmmode.fd, pVia->agpHandle); 3328aedb4f6Smrg drmAgpFree(pVia->drmmode.fd, pVia->agpHandle); 3338aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 3347e6fb56fSmrg return FALSE; 3357e6fb56fSmrg } 3368aedb4f6Smrg drmMap(pVia->drmmode.fd, handle, pVia->agpSize, &agpaddr); 3377e6fb56fSmrg pVia->agpMappedAddr = agpaddr; 3387e6fb56fSmrg 3398aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3407e6fb56fSmrg "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr); 3418aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3427e6fb56fSmrg "[drm] agpSize = 0x%08x\n", pVia->agpSize); 3438aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3448aedb4f6Smrg "[drm] agp physical addr = %p\n", pVia->agpMappedAddr); 3457e6fb56fSmrg return TRUE; 3467e6fb56fSmrg} 3477e6fb56fSmrg 3487e6fb56fSmrgstatic Bool 3498aedb4f6SmrgVIADRIFBInit(ScrnInfoPtr pScrn) 3507e6fb56fSmrg{ 3518aedb4f6Smrg VIAPtr pVia = VIAPTR(pScrn); 3528aedb4f6Smrg drm_via_fb_t fb; 3537e6fb56fSmrg 3548aedb4f6Smrg fb.offset = pVia->FBFreeStart; 3558aedb4f6Smrg fb.size = pVia->FBFreeEnd; 3568aedb4f6Smrg if (drmCommandWrite(pVia->drmmode.fd, DRM_VIA_FB_INIT, &fb, 3578aedb4f6Smrg sizeof(drm_via_fb_t)) < 0) { 3588aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3598aedb4f6Smrg "[drm] Failed to initialize frame buffer area.\n"); 3607e6fb56fSmrg return FALSE; 3618aedb4f6Smrg } else { 3628aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3638aedb4f6Smrg "[drm] Using %d KB for DRM memory heap.\n", fb.size >> 10); 3648aedb4f6Smrg return TRUE; 3657e6fb56fSmrg } 3667e6fb56fSmrg} 3677e6fb56fSmrg 3687e6fb56fSmrgstatic Bool 3697e6fb56fSmrgVIAInitVisualConfigs(ScreenPtr pScreen) 3707e6fb56fSmrg{ 3718aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 3727e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 3737e6fb56fSmrg int numConfigs = 0; 3747e6fb56fSmrg __GLXvisualConfig *pConfigs = 0; 3757e6fb56fSmrg VIAConfigPrivPtr pVIAConfigs = 0; 3767e6fb56fSmrg VIAConfigPrivPtr *pVIAConfigPtrs = 0; 3777e6fb56fSmrg int i, db, stencil, accum; 3787e6fb56fSmrg 3797e6fb56fSmrg if (pScrn->bitsPerPixel == 16 || pScrn->bitsPerPixel == 32) { 3807e6fb56fSmrg numConfigs = 12; 3817e6fb56fSmrg if (!(pConfigs = (__GLXvisualConfig *) 3828aedb4f6Smrg calloc(sizeof(__GLXvisualConfig), numConfigs))) 3837e6fb56fSmrg return FALSE; 3847e6fb56fSmrg if (!(pVIAConfigs = (VIAConfigPrivPtr) 3858aedb4f6Smrg calloc(sizeof(VIAConfigPrivRec), numConfigs))) { 3868aedb4f6Smrg free(pConfigs); 3877e6fb56fSmrg return FALSE; 3887e6fb56fSmrg } 3897e6fb56fSmrg if (!(pVIAConfigPtrs = (VIAConfigPrivPtr *) 3908aedb4f6Smrg calloc(sizeof(VIAConfigPrivPtr), numConfigs))) { 3918aedb4f6Smrg free(pConfigs); 3928aedb4f6Smrg free(pVIAConfigs); 3937e6fb56fSmrg return FALSE; 3947e6fb56fSmrg } 3957e6fb56fSmrg for (i = 0; i < numConfigs; i++) 3967e6fb56fSmrg pVIAConfigPtrs[i] = &pVIAConfigs[i]; 3977e6fb56fSmrg 3987e6fb56fSmrg i = 0; 3997e6fb56fSmrg for (accum = 0; accum <= 1; accum++) { 4007e6fb56fSmrg /* 32bpp depth buffer disabled, as Mesa has limitations */ 4017e6fb56fSmrg for (stencil = 0; stencil <= 2; stencil++) { 4027e6fb56fSmrg for (db = 0; db <= 1; db++) { 4037e6fb56fSmrg pConfigs[i].vid = -1; 4047e6fb56fSmrg pConfigs[i].class = -1; 4057e6fb56fSmrg pConfigs[i].rgba = TRUE; 4067e6fb56fSmrg pConfigs[i].redSize = -1; 4077e6fb56fSmrg pConfigs[i].greenSize = -1; 4087e6fb56fSmrg pConfigs[i].blueSize = -1; 4097e6fb56fSmrg pConfigs[i].redMask = -1; 4107e6fb56fSmrg pConfigs[i].greenMask = -1; 4117e6fb56fSmrg pConfigs[i].blueMask = -1; 4127e6fb56fSmrg if (pScrn->bitsPerPixel == 32) { 4137e6fb56fSmrg pConfigs[i].alphaSize = 8; 4147e6fb56fSmrg pConfigs[i].alphaMask = 0xFF000000; 4157e6fb56fSmrg } else { 4167e6fb56fSmrg pConfigs[i].alphaSize = 0; 4177e6fb56fSmrg pConfigs[i].alphaMask = 0; 4187e6fb56fSmrg } 4197e6fb56fSmrg 4207e6fb56fSmrg if (accum) { 4217e6fb56fSmrg pConfigs[i].accumRedSize = 16; 4227e6fb56fSmrg pConfigs[i].accumGreenSize = 16; 4237e6fb56fSmrg pConfigs[i].accumBlueSize = 16; 4247e6fb56fSmrg if (pScrn->bitsPerPixel == 32) 4257e6fb56fSmrg pConfigs[i].accumAlphaSize = 16; 4267e6fb56fSmrg else 4277e6fb56fSmrg pConfigs[i].accumAlphaSize = 0; 4287e6fb56fSmrg } else { 4297e6fb56fSmrg pConfigs[i].accumRedSize = 0; 4307e6fb56fSmrg pConfigs[i].accumGreenSize = 0; 4317e6fb56fSmrg pConfigs[i].accumBlueSize = 0; 4327e6fb56fSmrg pConfigs[i].accumAlphaSize = 0; 4337e6fb56fSmrg } 4347e6fb56fSmrg if (!db) 4357e6fb56fSmrg pConfigs[i].doubleBuffer = TRUE; 4367e6fb56fSmrg else 4377e6fb56fSmrg pConfigs[i].doubleBuffer = FALSE; 4387e6fb56fSmrg 4397e6fb56fSmrg pConfigs[i].stereo = FALSE; 4407e6fb56fSmrg pConfigs[i].bufferSize = -1; 4417e6fb56fSmrg 4427e6fb56fSmrg switch (stencil) { 4437e6fb56fSmrg case 0: 4447e6fb56fSmrg pConfigs[i].depthSize = 24; 4457e6fb56fSmrg pConfigs[i].stencilSize = 8; 4467e6fb56fSmrg break; 4477e6fb56fSmrg case 1: 4487e6fb56fSmrg pConfigs[i].depthSize = 16; 4497e6fb56fSmrg pConfigs[i].stencilSize = 0; 4507e6fb56fSmrg break; 4517e6fb56fSmrg case 2: 4527e6fb56fSmrg pConfigs[i].depthSize = 0; 4537e6fb56fSmrg pConfigs[i].stencilSize = 0; 4547e6fb56fSmrg break; 4557e6fb56fSmrg case 3: 4567e6fb56fSmrg pConfigs[i].depthSize = 32; 4577e6fb56fSmrg pConfigs[i].stencilSize = 0; 4587e6fb56fSmrg break; 4597e6fb56fSmrg } 4607e6fb56fSmrg 4617e6fb56fSmrg pConfigs[i].auxBuffers = 0; 4627e6fb56fSmrg pConfigs[i].level = 0; 4637e6fb56fSmrg if (accum) 4647e6fb56fSmrg pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; 4657e6fb56fSmrg else 4667e6fb56fSmrg pConfigs[i].visualRating = GLX_NONE_EXT; 4677e6fb56fSmrg pConfigs[i].transparentPixel = GLX_NONE_EXT; 4687e6fb56fSmrg pConfigs[i].transparentRed = 0; 4697e6fb56fSmrg pConfigs[i].transparentGreen = 0; 4707e6fb56fSmrg pConfigs[i].transparentBlue = 0; 4717e6fb56fSmrg pConfigs[i].transparentAlpha = 0; 4727e6fb56fSmrg pConfigs[i].transparentIndex = 0; 4737e6fb56fSmrg i++; 4747e6fb56fSmrg } 4757e6fb56fSmrg } 4767e6fb56fSmrg } 4777e6fb56fSmrg 4787e6fb56fSmrg if (i != numConfigs) { 4797e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] Incorrect " 4807e6fb56fSmrg "initialization of visuals. Disabling DRI.\n"); 4817e6fb56fSmrg return FALSE; 4827e6fb56fSmrg } 4837e6fb56fSmrg } 4847e6fb56fSmrg 4857e6fb56fSmrg pVia->numVisualConfigs = numConfigs; 4867e6fb56fSmrg pVia->pVisualConfigs = pConfigs; 4877e6fb56fSmrg pVia->pVisualConfigsPriv = pVIAConfigs; 4887e6fb56fSmrg GlxSetVisualConfigs(numConfigs, pConfigs, (void **)pVIAConfigPtrs); 4897e6fb56fSmrg 4907e6fb56fSmrg return TRUE; 4917e6fb56fSmrg} 4927e6fb56fSmrg 4937e6fb56fSmrgBool 4948aedb4f6SmrgVIADRI1ScreenInit(ScreenPtr pScreen) 4957e6fb56fSmrg{ 4968aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 4977e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 4988aedb4f6Smrg int major, minor, patch; 4997e6fb56fSmrg DRIInfoPtr pDRIInfo; 5007e6fb56fSmrg VIADRIPtr pVIADRI; 5017e6fb56fSmrg 5027e6fb56fSmrg /* If symbols or version check fails, we still want this to be NULL. */ 5037e6fb56fSmrg pVia->pDRIInfo = NULL; 5048aedb4f6Smrg drmClose(pVia->drmmode.fd); 5057e6fb56fSmrg 5067e6fb56fSmrg /* Check that the GLX, DRI, and DRM modules have been loaded by testing 5077e6fb56fSmrg * for canonical symbols in each module. */ 5087e6fb56fSmrg if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) 5097e6fb56fSmrg return FALSE; 5107e6fb56fSmrg if (!xf86LoaderCheckSymbol("drmAvailable")) 5117e6fb56fSmrg return FALSE; 5127e6fb56fSmrg if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { 5138aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5148aedb4f6Smrg "[dri] VIADRI1ScreenInit failed (libdri.a is too old).\n"); 5157e6fb56fSmrg return FALSE; 5167e6fb56fSmrg } 5177e6fb56fSmrg 5187e6fb56fSmrg /* Check the DRI version. */ 5198aedb4f6Smrg DRIQueryVersion(&major, &minor, &patch); 5208aedb4f6Smrg if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { 5218aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5228aedb4f6Smrg "[dri] VIADRI1ScreenInit failed -- FALSE mismatch.\n" 5238aedb4f6Smrg "[dri] libdri is %d.%d.%d, but %d.%d.x is needed.\n" 5248aedb4f6Smrg "[dri] Disabling DRI.\n", 5258aedb4f6Smrg major, minor, patch, 5268aedb4f6Smrg DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); 5278aedb4f6Smrg return FALSE; 5287e6fb56fSmrg } 5297e6fb56fSmrg 5307e6fb56fSmrg pVia->pDRIInfo = DRICreateInfoRec(); 5317e6fb56fSmrg if (!pVia->pDRIInfo) 5327e6fb56fSmrg return FALSE; 5337e6fb56fSmrg 5347e6fb56fSmrg pDRIInfo = pVia->pDRIInfo; 5357e6fb56fSmrg pDRIInfo->drmDriverName = VIAKernelDriverName; 5367e6fb56fSmrg switch (pVia->Chipset) { 5377e6fb56fSmrg case VIA_K8M890: 5387e6fb56fSmrg case VIA_P4M900: 5397e6fb56fSmrg case VIA_VX800: 5407e6fb56fSmrg case VIA_VX855: 5418aedb4f6Smrg case VIA_VX900: 5427e6fb56fSmrg pDRIInfo->clientDriverName = "swrast"; 5437e6fb56fSmrg break; 5447e6fb56fSmrg default: 5457e6fb56fSmrg pDRIInfo->clientDriverName = VIAClientDriverName; 5467e6fb56fSmrg break; 5477e6fb56fSmrg } 5488aedb4f6Smrg#if 0 549485acf3eSjmcneill if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 550485acf3eSjmcneill pDRIInfo->busIdString = DRICreatePCIBusID(pVia->PciInfo); 551485acf3eSjmcneill } else { 552485acf3eSjmcneill pDRIInfo->busIdString = xalloc(64); 553485acf3eSjmcneill sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", 5547e6fb56fSmrg#ifdef XSERVER_LIBPCIACCESS 555485acf3eSjmcneill ((pVia->PciInfo->domain << 8) | pVia->PciInfo->bus), 556485acf3eSjmcneill pVia->PciInfo->dev, pVia->PciInfo->func 5577e6fb56fSmrg#else 558485acf3eSjmcneill ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum, 559485acf3eSjmcneill ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum, 560485acf3eSjmcneill ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum 5617e6fb56fSmrg#endif 562485acf3eSjmcneill ); 563485acf3eSjmcneill } 5648aedb4f6Smrg#else 5658aedb4f6Smrg pDRIInfo->busIdString = DRICreatePCIBusID(pVia->PciInfo); 5668aedb4f6Smrg#endif 5677e6fb56fSmrg pDRIInfo->ddxDriverMajorVersion = VIA_DRIDDX_VERSION_MAJOR; 5687e6fb56fSmrg pDRIInfo->ddxDriverMinorVersion = VIA_DRIDDX_VERSION_MINOR; 5697e6fb56fSmrg pDRIInfo->ddxDriverPatchVersion = VIA_DRIDDX_VERSION_PATCH; 5707e6fb56fSmrg#if (DRIINFO_MAJOR_VERSION == 5) 5717e6fb56fSmrg pDRIInfo->frameBufferPhysicalAddress = (pointer) pVia->FrameBufferBase; 5727e6fb56fSmrg#else 5737e6fb56fSmrg pDRIInfo->frameBufferPhysicalAddress = pVia->FrameBufferBase; 5747e6fb56fSmrg#endif 5757e6fb56fSmrg pDRIInfo->frameBufferSize = pVia->videoRambytes; 5767e6fb56fSmrg 5777e6fb56fSmrg pDRIInfo->frameBufferStride = (pScrn->displayWidth * 5787e6fb56fSmrg pScrn->bitsPerPixel / 8); 5797e6fb56fSmrg pDRIInfo->ddxDrawableTableEntry = VIA_MAX_DRAWABLES; 5807e6fb56fSmrg 5817e6fb56fSmrg if (SAREA_MAX_DRAWABLES < VIA_MAX_DRAWABLES) 5827e6fb56fSmrg pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 5837e6fb56fSmrg else 5847e6fb56fSmrg pDRIInfo->maxDrawableTableEntry = VIA_MAX_DRAWABLES; 5857e6fb56fSmrg 5867e6fb56fSmrg#ifdef NOT_DONE 5877e6fb56fSmrg /* FIXME: need to extend DRI protocol to pass this size back to client 5887e6fb56fSmrg * for SAREA mapping that includes a device private record. */ 5897e6fb56fSmrg pDRIInfo->SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ 5907e6fb56fSmrg /* + shared memory device private rec */ 5917e6fb56fSmrg#else 5927e6fb56fSmrg /* For now the mapping works by using a fixed size defined 5937e6fb56fSmrg * in the SAREA header. */ 5947e6fb56fSmrg if (sizeof(XF86DRISAREARec) + sizeof(drm_via_sarea_t) > SAREA_MAX) { 5957e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Data does not fit in SAREA\n"); 5967e6fb56fSmrg DRIDestroyInfoRec(pVia->pDRIInfo); 5977e6fb56fSmrg pVia->pDRIInfo = NULL; 5987e6fb56fSmrg return FALSE; 5997e6fb56fSmrg } 6007e6fb56fSmrg pDRIInfo->SAREASize = SAREA_MAX; 6017e6fb56fSmrg#endif 6027e6fb56fSmrg 6038aedb4f6Smrg if (!(pVIADRI = (VIADRIPtr) calloc(sizeof(VIADRIRec), 1))) { 6047e6fb56fSmrg DRIDestroyInfoRec(pVia->pDRIInfo); 6057e6fb56fSmrg pVia->pDRIInfo = NULL; 6067e6fb56fSmrg return FALSE; 6077e6fb56fSmrg } 6087e6fb56fSmrg pDRIInfo->devPrivate = pVIADRI; 6097e6fb56fSmrg pDRIInfo->devPrivateSize = sizeof(VIADRIRec); 6107e6fb56fSmrg pDRIInfo->contextSize = sizeof(VIADRIContextRec); 6117e6fb56fSmrg 6127e6fb56fSmrg pDRIInfo->CreateContext = VIACreateContext; 6137e6fb56fSmrg pDRIInfo->DestroyContext = VIADestroyContext; 6147e6fb56fSmrg pDRIInfo->SwapContext = VIADRISwapContext; 6157e6fb56fSmrg pDRIInfo->InitBuffers = VIADRIInitBuffers; 6167e6fb56fSmrg pDRIInfo->MoveBuffers = VIADRIMoveBuffers; 6177e6fb56fSmrg pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 6187e6fb56fSmrg 6198aedb4f6Smrg if (!DRIScreenInit(pScreen, pDRIInfo, &pVia->drmmode.fd)) { 6208aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 6217e6fb56fSmrg "[dri] DRIScreenInit failed. Disabling DRI.\n"); 6228aedb4f6Smrg free(pDRIInfo->devPrivate); 6237e6fb56fSmrg pDRIInfo->devPrivate = NULL; 6247e6fb56fSmrg DRIDestroyInfoRec(pVia->pDRIInfo); 6257e6fb56fSmrg pVia->pDRIInfo = NULL; 6268aedb4f6Smrg pVia->drmmode.fd = -1; 6277e6fb56fSmrg return FALSE; 6287e6fb56fSmrg } 6297e6fb56fSmrg 6307e6fb56fSmrg if (!(VIAInitVisualConfigs(pScreen))) { 6317e6fb56fSmrg VIADRICloseScreen(pScreen); 6327e6fb56fSmrg return FALSE; 6337e6fb56fSmrg } 6347e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized.\n"); 6357e6fb56fSmrg 6367e6fb56fSmrg /* DRIScreenInit doesn't add all the common mappings. 6377e6fb56fSmrg * Add additional mappings here. */ 6387e6fb56fSmrg if (!VIADRIMapInit(pScreen, pVia)) { 6397e6fb56fSmrg VIADRICloseScreen(pScreen); 6407e6fb56fSmrg return FALSE; 6417e6fb56fSmrg } 6427e6fb56fSmrg pVIADRI->regs.size = VIA_MMIO_REGSIZE; 6437e6fb56fSmrg pVIADRI->regs.handle = pVia->registerHandle; 6448aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] mmio Registers = 0x%08lx\n", 6457e6fb56fSmrg (unsigned long)pVIADRI->regs.handle); 6467e6fb56fSmrg 6477e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n"); 6487e6fb56fSmrg return TRUE; 6497e6fb56fSmrg} 6507e6fb56fSmrg 6517e6fb56fSmrgvoid 6527e6fb56fSmrgVIADRICloseScreen(ScreenPtr pScreen) 6537e6fb56fSmrg{ 6548aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 6557e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 6567e6fb56fSmrg VIADRIPtr pVIADRI; 6577e6fb56fSmrg 6587e6fb56fSmrg VIADRIRingBufferCleanup(pScrn); 6597e6fb56fSmrg if (pVia->agpSize) { 6607e6fb56fSmrg drmUnmap(pVia->agpMappedAddr, pVia->agpSize); 6618aedb4f6Smrg drmRmMap(pVia->drmmode.fd, pVia->agpHandle); 6628aedb4f6Smrg drmAgpUnbind(pVia->drmmode.fd, pVia->agpHandle); 6638aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Freeing agp memory\n"); 6648aedb4f6Smrg drmAgpFree(pVia->drmmode.fd, pVia->agpHandle); 6658aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Releasing agp module\n"); 6668aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 6677e6fb56fSmrg } 6687e6fb56fSmrg 6697e6fb56fSmrg DRICloseScreen(pScreen); 6708aedb4f6Smrg drm_bo_free(pScrn, pVia->driOffScreenMem); 6717e6fb56fSmrg 6727e6fb56fSmrg if (pVia->pDRIInfo) { 6737e6fb56fSmrg if ((pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate)) { 6747e6fb56fSmrg VIADRIIrqExit(pScrn, pVIADRI); 6758aedb4f6Smrg free(pVIADRI); 6767e6fb56fSmrg pVia->pDRIInfo->devPrivate = NULL; 6777e6fb56fSmrg } 6787e6fb56fSmrg DRIDestroyInfoRec(pVia->pDRIInfo); 6797e6fb56fSmrg pVia->pDRIInfo = NULL; 6807e6fb56fSmrg } 6817e6fb56fSmrg 6827e6fb56fSmrg if (pVia->pVisualConfigs) { 6838aedb4f6Smrg free(pVia->pVisualConfigs); 6847e6fb56fSmrg pVia->pVisualConfigs = NULL; 6857e6fb56fSmrg } 6867e6fb56fSmrg if (pVia->pVisualConfigsPriv) { 6878aedb4f6Smrg free(pVia->pVisualConfigsPriv); 6887e6fb56fSmrg pVia->pVisualConfigsPriv = NULL; 6897e6fb56fSmrg } 6907e6fb56fSmrg} 6917e6fb56fSmrg 6927e6fb56fSmrg/* TODO: xserver receives driver's swapping event and does something 6937e6fb56fSmrg * according the data initialized in this function. 6947e6fb56fSmrg */ 6957e6fb56fSmrgstatic Bool 6967e6fb56fSmrgVIACreateContext(ScreenPtr pScreen, VisualPtr visual, 6977e6fb56fSmrg drm_context_t hwContext, void *pVisualConfigPriv, 6987e6fb56fSmrg DRIContextType contextStore) 6997e6fb56fSmrg{ 7007e6fb56fSmrg return TRUE; 7017e6fb56fSmrg} 7027e6fb56fSmrg 7037e6fb56fSmrgstatic void 7047e6fb56fSmrgVIADestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 7057e6fb56fSmrg DRIContextType contextStore) 7067e6fb56fSmrg{ 7077e6fb56fSmrg} 7087e6fb56fSmrg 7097e6fb56fSmrgBool 7107e6fb56fSmrgVIADRIFinishScreenInit(ScreenPtr pScreen) 7117e6fb56fSmrg{ 7128aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7137e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 7147e6fb56fSmrg VIADRIPtr pVIADRI; 7157e6fb56fSmrg 7167e6fb56fSmrg pVia->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; 7178aedb4f6Smrg pVia->agpDMA = FALSE; 7187e6fb56fSmrg 7198aedb4f6Smrg pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate; 7208aedb4f6Smrg pVIADRI->drixinerama = FALSE; 7217e6fb56fSmrg 7228aedb4f6Smrg if (pVia->driSize < pVia->Bpl) { 7237e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 7248aedb4f6Smrg "[drm] No DRM framebuffer heap available.\n" 7258aedb4f6Smrg "[drm] Please increase the frame buffer\n" 7268aedb4f6Smrg "[drm] memory area in the BIOS. Disabling DRI.\n"); 7277e6fb56fSmrg return FALSE; 7287e6fb56fSmrg } 7298aedb4f6Smrg if (pVia->driSize < 3 * (pScrn->virtualY * pVia->Bpl)) { 7308aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 7318aedb4f6Smrg "[drm] The DRM heap and pixmap cache memory may be too\n" 7328aedb4f6Smrg "[drm] small for optimal performance. Please increase\n" 7338aedb4f6Smrg "[drm] the frame buffer memory area in the BIOS.\n"); 7348aedb4f6Smrg } 7357e6fb56fSmrg 7368aedb4f6Smrg pVia->driOffScreenMem = drm_bo_alloc(pScrn, pVia->driSize, 16, TTM_PL_FLAG_VRAM); 7377e6fb56fSmrg 7387e6fb56fSmrg DRIFinishScreenInit(pScreen); 7397e6fb56fSmrg 7407e6fb56fSmrg /* Set SAREA value. */ 7417e6fb56fSmrg { 7427e6fb56fSmrg drm_via_sarea_t *saPriv; 7437e6fb56fSmrg 7447e6fb56fSmrg saPriv = (drm_via_sarea_t *) DRIGetSAREAPrivate(pScreen); 7457e6fb56fSmrg assert(saPriv); 7467e6fb56fSmrg memset(saPriv, 0, sizeof(*saPriv)); 7477e6fb56fSmrg saPriv->ctxOwner = -1; 7487e6fb56fSmrg } 7497e6fb56fSmrg pVIADRI->deviceID = pVia->Chipset; 7507e6fb56fSmrg pVIADRI->width = pScrn->virtualX; 7517e6fb56fSmrg pVIADRI->height = pScrn->virtualY; 7527e6fb56fSmrg pVIADRI->mem = pScrn->videoRam * 1024; 7537e6fb56fSmrg pVIADRI->bytesPerPixel = (pScrn->bitsPerPixel + 7) / 8; 7547e6fb56fSmrg pVIADRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 7557e6fb56fSmrg /* TODO */ 7567e6fb56fSmrg pVIADRI->scrnX = pVIADRI->width; 7577e6fb56fSmrg pVIADRI->scrnY = pVIADRI->height; 7587e6fb56fSmrg 7597e6fb56fSmrg /* Initialize IRQ. */ 7607e6fb56fSmrg if (pVia->DRIIrqEnable) 7617e6fb56fSmrg VIADRIIrqInit(pScrn, pVIADRI); 7627e6fb56fSmrg 7637e6fb56fSmrg pVIADRI->ringBufActive = 0; 7647e6fb56fSmrg VIADRIRingBufferInit(pScrn); 7658aedb4f6Smrg pVia->agpDMA = pVia->dma2d && pVIADRI->ringBufActive; 7667e6fb56fSmrg return TRUE; 7677e6fb56fSmrg} 7687e6fb56fSmrg 7697e6fb56fSmrgstatic void 7707e6fb56fSmrgVIADRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 7717e6fb56fSmrg DRIContextType oldContextType, void *oldContext, 7727e6fb56fSmrg DRIContextType newContextType, void *newContext) 7737e6fb56fSmrg{ 7747e6fb56fSmrg#if 0 7758aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7767e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 7777e6fb56fSmrg#endif 7787e6fb56fSmrg return; 7797e6fb56fSmrg} 7807e6fb56fSmrg 7817e6fb56fSmrgstatic void 7827e6fb56fSmrgVIADRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) 7837e6fb56fSmrg{ 7847e6fb56fSmrg#if 0 7857e6fb56fSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 7868aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7877e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 7887e6fb56fSmrg#endif 7897e6fb56fSmrg return; 7907e6fb56fSmrg} 7917e6fb56fSmrg 7927e6fb56fSmrgstatic void 7937e6fb56fSmrgVIADRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 7947e6fb56fSmrg RegionPtr prgnSrc, CARD32 index) 7957e6fb56fSmrg{ 7967e6fb56fSmrg#if 0 7977e6fb56fSmrg ScreenPtr pScreen = pParent->drawable.pScreen; 7988aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7997e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 8007e6fb56fSmrg#endif 8017e6fb56fSmrg return; 8027e6fb56fSmrg} 8037e6fb56fSmrg 8047e6fb56fSmrg/* Initialize the kernel data structures. */ 8058aedb4f6SmrgBool 8068aedb4f6SmrgVIADRIKernelInit(ScrnInfoPtr pScrn) 8077e6fb56fSmrg{ 8088aedb4f6Smrg VIAPtr pVia = VIAPTR(pScrn); 8097e6fb56fSmrg drm_via_init_t drmInfo; 8107e6fb56fSmrg 8118aedb4f6Smrg pVia->IsPCI = !VIADRIAgpInit(pScrn); 8128aedb4f6Smrg if (pVia->IsPCI) 8138aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Using PCI.\n"); 8148aedb4f6Smrg else 8158aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Using AGP.\n"); 8168aedb4f6Smrg 8178aedb4f6Smrg if (!(VIADRIFBInit(pScrn))) { 8188aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 8198aedb4f6Smrg "[dri] Frame buffer initialization failed.\n"); 8208aedb4f6Smrg return FALSE; 8218aedb4f6Smrg } 8228aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Frame buffer initialized.\n"); 8238aedb4f6Smrg 8247e6fb56fSmrg memset(&drmInfo, 0, sizeof(drm_via_init_t)); 8257e6fb56fSmrg drmInfo.func = VIA_INIT_MAP; 8267e6fb56fSmrg drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); 8277e6fb56fSmrg drmInfo.fb_offset = pVia->frameBufferHandle; 8287e6fb56fSmrg drmInfo.mmio_offset = pVia->registerHandle; 8297e6fb56fSmrg 8307e6fb56fSmrg if (pVia->IsPCI) { 8318aedb4f6Smrg drmInfo.agpAddr = 0; 8327e6fb56fSmrg } else { 8337e6fb56fSmrg /*For AMD64*/ 8347e6fb56fSmrg#ifndef __x86_64__ 8358aedb4f6Smrg drmInfo.agpAddr = (CARD32)pVia->agpAddr; 8367e6fb56fSmrg#else 8378aedb4f6Smrg drmInfo.agpAddr = (CARD64)pVia->agpAddr; 8387e6fb56fSmrg#endif 8397e6fb56fSmrg } 8407e6fb56fSmrg 8418aedb4f6Smrg if ((drmCommandWrite(pVia->drmmode.fd, DRM_VIA_MAP_INIT, &drmInfo, 8427e6fb56fSmrg sizeof(drm_via_init_t))) < 0) 8437e6fb56fSmrg return FALSE; 8447e6fb56fSmrg 8458aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Kernel data initialized.\n"); 8467e6fb56fSmrg return TRUE; 8477e6fb56fSmrg} 8487e6fb56fSmrg 8497e6fb56fSmrg/* Add a map for the MMIO registers. */ 8507e6fb56fSmrgstatic Bool 8517e6fb56fSmrgVIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia) 8527e6fb56fSmrg{ 8538aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 8547e6fb56fSmrg int flags = DRM_READ_ONLY; 8557e6fb56fSmrg 8568aedb4f6Smrg if (drmAddMap(pVia->drmmode.fd, pVia->MmioBase, VIA_MMIO_REGSIZE, 8577e6fb56fSmrg DRM_REGISTERS, flags, &pVia->registerHandle) < 0) { 8587e6fb56fSmrg return FALSE; 8597e6fb56fSmrg } 8608aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] register handle = 0x%08lx\n", 8617e6fb56fSmrg (unsigned long)pVia->registerHandle); 8628aedb4f6Smrg if (drmAddMap(pVia->drmmode.fd, pVia->FrameBufferBase, pVia->videoRambytes, 8637e6fb56fSmrg DRM_FRAME_BUFFER, 0, &pVia->frameBufferHandle) < 0) { 8647e6fb56fSmrg return FALSE; 8657e6fb56fSmrg } 8668aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] framebuffer handle = 0x%08lx\n", 8677e6fb56fSmrg (unsigned long)pVia->frameBufferHandle); 8687e6fb56fSmrg 8697e6fb56fSmrg return TRUE; 8707e6fb56fSmrg} 8717e6fb56fSmrg 8727e6fb56fSmrg#define DRM_VIA_BLIT_MAX_SIZE (2048*2048*4) 8737e6fb56fSmrg 8747e6fb56fSmrgstatic int 8758aedb4f6SmrgviaDRIFBMemcpy(int fd, struct buffer_object *vram, unsigned char *addr, 8768aedb4f6Smrg Bool toFB) 8777e6fb56fSmrg{ 8788aedb4f6Smrg unsigned long fbOffset = vram->offset, size = vram->size, curSize; 8797e6fb56fSmrg drm_via_dmablit_t blit; 8808aedb4f6Smrg int err; 8817e6fb56fSmrg 8827e6fb56fSmrg do { 8837e6fb56fSmrg curSize = (size > DRM_VIA_BLIT_MAX_SIZE) ? DRM_VIA_BLIT_MAX_SIZE : size; 8847e6fb56fSmrg 8857e6fb56fSmrg blit.num_lines = 1; 8867e6fb56fSmrg blit.line_length = curSize; 8877e6fb56fSmrg blit.fb_addr = fbOffset; 8887e6fb56fSmrg blit.fb_stride = ALIGN_TO(curSize, 16); 8897e6fb56fSmrg blit.mem_addr = addr; 8907e6fb56fSmrg blit.mem_stride = blit.fb_stride; 8917e6fb56fSmrg blit.to_fb = (toFB) ? 1 : 0; 8927e6fb56fSmrg 8937e6fb56fSmrg do { 8947e6fb56fSmrg err = drmCommandWriteRead(fd, DRM_VIA_DMA_BLIT, 8957e6fb56fSmrg &blit, sizeof(blit)); 8967e6fb56fSmrg } while (-EAGAIN == err); 8977e6fb56fSmrg if (err) 8987e6fb56fSmrg return err; 8997e6fb56fSmrg 9007e6fb56fSmrg do { 9017e6fb56fSmrg err = drmCommandWriteRead(fd, DRM_VIA_BLIT_SYNC, 9027e6fb56fSmrg &blit.sync, sizeof(blit.sync)); 9037e6fb56fSmrg } while (-EAGAIN == err); 9047e6fb56fSmrg if (err) 9057e6fb56fSmrg return err; 9067e6fb56fSmrg 9077e6fb56fSmrg fbOffset += curSize; 9087e6fb56fSmrg addr += curSize; 9097e6fb56fSmrg size -= curSize; 9107e6fb56fSmrg 9117e6fb56fSmrg } while (size > 0); 9127e6fb56fSmrg return 0; 9137e6fb56fSmrg} 9147e6fb56fSmrg 9157e6fb56fSmrgvoid 9167e6fb56fSmrgviaDRIOffscreenSave(ScrnInfoPtr pScrn) 9177e6fb56fSmrg{ 9187e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 9198aedb4f6Smrg unsigned long srcSize = pVia->driOffScreenMem->size; 9207e6fb56fSmrg int err; 9217e6fb56fSmrg 9227e6fb56fSmrg if (pVia->driOffScreenSave) 9237e6fb56fSmrg free(pVia->driOffScreenSave); 9247e6fb56fSmrg 9258aedb4f6Smrg pVia->driOffScreenSave = malloc(srcSize + 16); 9267e6fb56fSmrg if (pVia->driOffScreenSave) { 9278aedb4f6Smrg void *dst, *src = drm_bo_map(pScrn, pVia->driOffScreenMem); 9288aedb4f6Smrg 9298aedb4f6Smrg dst = pVia->driOffScreenSave; 9307e6fb56fSmrg if ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 8)) { 9318aedb4f6Smrg err = viaDRIFBMemcpy(pVia->drmmode.fd, pVia->driOffScreenMem, dst, FALSE); 9327e6fb56fSmrg if (!err) 9337e6fb56fSmrg return; 9347e6fb56fSmrg 9357e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 9367e6fb56fSmrg "Hardware backup of DRI offscreen memory failed: %s.\n" 9377e6fb56fSmrg "\tUsing slow software backup instead.\n", 9387e6fb56fSmrg strerror(-err)); 9397e6fb56fSmrg } 9408aedb4f6Smrg memcpy(dst, src, srcSize); 9418aedb4f6Smrg drm_bo_unmap(pScrn, pVia->driOffScreenMem); 9427e6fb56fSmrg } else { 9437e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 9447e6fb56fSmrg "Out of memory trying to backup DRI offscreen memory.\n"); 9457e6fb56fSmrg } 9467e6fb56fSmrg return; 9477e6fb56fSmrg} 9487e6fb56fSmrg 9497e6fb56fSmrgvoid 9507e6fb56fSmrgviaDRIOffscreenRestore(ScrnInfoPtr pScrn) 9517e6fb56fSmrg{ 9527e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 9537e6fb56fSmrg 9547e6fb56fSmrg if (pVia->driOffScreenSave) { 9558aedb4f6Smrg void *src, *dst = drm_bo_map(pScrn, pVia->driOffScreenMem); 9568aedb4f6Smrg 9578aedb4f6Smrg src = pVia->driOffScreenSave; 9588aedb4f6Smrg memcpy(dst, src, pVia->driOffScreenMem->size); 9597e6fb56fSmrg free(pVia->driOffScreenSave); 9607e6fb56fSmrg pVia->driOffScreenSave = NULL; 9618aedb4f6Smrg 9628aedb4f6Smrg drm_bo_unmap(pScrn, pVia->driOffScreenMem); 9638aedb4f6Smrg } else { 9647e6fb56fSmrg } 9657e6fb56fSmrg} 966