17e6fb56fSmrg/* 244802259Smrg * Copyright 2005-2015 The Openchrome Project 31090d90aSmrg * [https://www.freedesktop.org/wiki/Openchrome] 47e6fb56fSmrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 57e6fb56fSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 67e6fb56fSmrg * 77e6fb56fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 87e6fb56fSmrg * copy of this software and associated documentation files (the "Software"), 97e6fb56fSmrg * to deal in the Software without restriction, including without limitation 107e6fb56fSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 117e6fb56fSmrg * and/or sell copies of the Software, and to permit persons to whom the 127e6fb56fSmrg * Software is furnished to do so, subject to the following conditions: 137e6fb56fSmrg * 147e6fb56fSmrg * The above copyright notice and this permission notice (including the 157e6fb56fSmrg * next paragraph) shall be included in all copies or substantial portions 167e6fb56fSmrg * of the Software. 177e6fb56fSmrg * 187e6fb56fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 197e6fb56fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 207e6fb56fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 217e6fb56fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 227e6fb56fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 237e6fb56fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 247e6fb56fSmrg * DEALINGS IN THE SOFTWARE. 257e6fb56fSmrg */ 267e6fb56fSmrg 277e6fb56fSmrg#ifdef HAVE_CONFIG_H 287e6fb56fSmrg#include "config.h" 297e6fb56fSmrg#endif 307e6fb56fSmrg 317e6fb56fSmrg#include "xf86.h" 327e6fb56fSmrg#include "xf86_OSproc.h" 337e6fb56fSmrg#include "xf86Priv.h" 347e6fb56fSmrg 357e6fb56fSmrg#include "xf86Pci.h" 367e6fb56fSmrg 377e6fb56fSmrg#define _XF86DRI_SERVER_ 387e6fb56fSmrg#include "GL/glxtokens.h" 397e6fb56fSmrg#include "sarea.h" 407e6fb56fSmrg 417e6fb56fSmrg#include "via_driver.h" 427e6fb56fSmrg#include "via_drm.h" 437e6fb56fSmrg#include "via_dri.h" 447e6fb56fSmrg#include "xf86drm.h" 457e6fb56fSmrg 467e6fb56fSmrg#ifndef DRIINFO_MAJOR_VERSION 477e6fb56fSmrg#define DRIINFO_MAJOR_VERSION 4 487e6fb56fSmrg#endif 497e6fb56fSmrg#ifndef DRIINFO_MINOR_VERSION 507e6fb56fSmrg#define DRIINFO_MINOR_VERSION 0 517e6fb56fSmrg#endif 527e6fb56fSmrg 537e6fb56fSmrg#define VIDEO 0 547e6fb56fSmrg#define AGP 1 557e6fb56fSmrg#define AGP_CMDBUF_PAGES 512 567e6fb56fSmrg#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES) 577e6fb56fSmrg#define VIA_AGP_MODE_MASK 0x17 587e6fb56fSmrg#define VIA_AGPv3_MODE 0x08 597e6fb56fSmrg#define VIA_AGPv3_8X_MODE 0x02 607e6fb56fSmrg#define VIA_AGPv3_4X_MODE 0x01 617e6fb56fSmrg#define VIA_AGP_4X_MODE 0x04 627e6fb56fSmrg#define VIA_AGP_2X_MODE 0x02 637e6fb56fSmrg#define VIA_AGP_1X_MODE 0x01 647e6fb56fSmrg#define VIA_AGP_FW_MODE 0x10 657e6fb56fSmrg 667e6fb56fSmrgextern void GlxSetVisualConfigs(int nconfigs, 677e6fb56fSmrg __GLXvisualConfig * configs, 687e6fb56fSmrg void **configprivs); 697e6fb56fSmrg 707e6fb56fSmrgtypedef struct 717e6fb56fSmrg{ 727e6fb56fSmrg int major; 737e6fb56fSmrg int minor; 747e6fb56fSmrg int patchlevel; 757e6fb56fSmrg} ViaDRMVersion; 767e6fb56fSmrg 777e6fb56fSmrgstatic char VIAKernelDriverName[] = "via"; 787e6fb56fSmrgstatic char VIAClientDriverName[] = "unichrome"; 797e6fb56fSmrgstatic const ViaDRMVersion drmExpected = { 1, 3, 0 }; 807e6fb56fSmrgstatic const ViaDRMVersion drmCompat = { 2, 0, 0 }; 817e6fb56fSmrg 827e6fb56fSmrgstatic Bool VIAInitVisualConfigs(ScreenPtr pScreen); 837e6fb56fSmrgstatic Bool VIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia); 847e6fb56fSmrg 857e6fb56fSmrgstatic Bool VIACreateContext(ScreenPtr pScreen, VisualPtr visual, 867e6fb56fSmrg drm_context_t hwContext, void *pVisualConfigPriv, 877e6fb56fSmrg DRIContextType contextStore); 887e6fb56fSmrgstatic void VIADestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 897e6fb56fSmrg DRIContextType contextStore); 907e6fb56fSmrgstatic void VIADRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 917e6fb56fSmrg DRIContextType readContextType, 927e6fb56fSmrg void *readContextStore, 937e6fb56fSmrg DRIContextType writeContextType, 947e6fb56fSmrg void *writeContextStore); 957e6fb56fSmrgstatic void VIADRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); 967e6fb56fSmrgstatic void VIADRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 977e6fb56fSmrg RegionPtr prgnSrc, CARD32 index); 987e6fb56fSmrg 998aedb4f6Smrgvoid 1008aedb4f6SmrgkickVblank(ScrnInfoPtr pScrn) 1018aedb4f6Smrg{ 1028aedb4f6Smrg /* 1038aedb4f6Smrg * Switching mode will clear registers that make vblank 1048aedb4f6Smrg * interrupts happen. If the driver thinks interrupts 1058aedb4f6Smrg * are enabled, make sure vblank interrupts go through. 1068aedb4f6Smrg * registers are not documented in VIA docs. 1078aedb4f6Smrg */ 1088aedb4f6Smrg VIAPtr pVia = VIAPTR(pScrn); 1098aedb4f6Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1108aedb4f6Smrg VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; 1118aedb4f6Smrg 1128aedb4f6Smrg if (pVIADRI->irqEnabled) 1138aedb4f6Smrg hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x30); 1148aedb4f6Smrg} 1157e6fb56fSmrg 1167e6fb56fSmrgstatic void 1177e6fb56fSmrgVIADRIIrqInit(ScrnInfoPtr pScrn, VIADRIPtr pVIADRI) 1187e6fb56fSmrg{ 1197e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 1207e6fb56fSmrg 1217e6fb56fSmrg pVIADRI->irqEnabled = drmGetInterruptFromBusID 1228aedb4f6Smrg (pVia->drmmode.fd, 1238aedb4f6Smrg#ifdef HAVE_PCIACCESS 1247e6fb56fSmrg ((pVia->PciInfo->domain << 8) | pVia->PciInfo->bus), 1257e6fb56fSmrg pVia->PciInfo->dev, pVia->PciInfo->func 1267e6fb56fSmrg#else 1277e6fb56fSmrg ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum, 1287e6fb56fSmrg ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum, 1297e6fb56fSmrg ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum 1307e6fb56fSmrg#endif 1317e6fb56fSmrg ); 1328aedb4f6Smrg if ((drmCtlInstHandler(pVia->drmmode.fd, pVIADRI->irqEnabled))) { 1337e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1347e6fb56fSmrg "[drm] Failure adding IRQ handler. " 1357e6fb56fSmrg "Falling back to IRQ-free operation.\n"); 1367e6fb56fSmrg pVIADRI->irqEnabled = 0; 1377e6fb56fSmrg } 1387e6fb56fSmrg 1397e6fb56fSmrg if (pVIADRI->irqEnabled) 1407e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1417e6fb56fSmrg "[drm] IRQ handler installed, using IRQ %d.\n", 1427e6fb56fSmrg pVIADRI->irqEnabled); 1437e6fb56fSmrg} 1447e6fb56fSmrg 1457e6fb56fSmrgstatic void 1467e6fb56fSmrgVIADRIIrqExit(ScrnInfoPtr pScrn, VIADRIPtr pVIADRI) 1477e6fb56fSmrg{ 1487e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 1497e6fb56fSmrg 1507e6fb56fSmrg if (pVIADRI->irqEnabled) { 1518aedb4f6Smrg if (drmCtlUninstHandler(pVia->drmmode.fd)) { 1527e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1537e6fb56fSmrg "[drm] IRQ handler uninstalled.\n"); 1547e6fb56fSmrg } else { 1557e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1567e6fb56fSmrg "[drm] Could not uninstall IRQ handler.\n"); 1577e6fb56fSmrg } 1587e6fb56fSmrg } 1597e6fb56fSmrg} 1607e6fb56fSmrg 1617e6fb56fSmrgvoid 1627e6fb56fSmrgVIADRIRingBufferCleanup(ScrnInfoPtr pScrn) 1637e6fb56fSmrg{ 1647e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 1657e6fb56fSmrg VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; 1667e6fb56fSmrg 1677e6fb56fSmrg if (pVIADRI->ringBufActive) { 1687e6fb56fSmrg drm_via_dma_init_t ringBufInit; 1697e6fb56fSmrg 1707e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1717e6fb56fSmrg "[drm] Cleaning up DMA ring-buffer.\n"); 1727e6fb56fSmrg ringBufInit.func = VIA_CLEANUP_DMA; 1738aedb4f6Smrg if (drmCommandWrite(pVia->drmmode.fd, DRM_VIA_DMA_INIT, &ringBufInit, 1747e6fb56fSmrg sizeof(ringBufInit))) { 1757e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1767e6fb56fSmrg "[drm] Failed to clean up DMA ring-buffer: %d\n", errno); 1777e6fb56fSmrg } 1787e6fb56fSmrg pVIADRI->ringBufActive = 0; 1797e6fb56fSmrg } 1807e6fb56fSmrg} 1817e6fb56fSmrg 1827e6fb56fSmrgBool 1837e6fb56fSmrgVIADRIRingBufferInit(ScrnInfoPtr pScrn) 1847e6fb56fSmrg{ 1857e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 1867e6fb56fSmrg VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; 1877e6fb56fSmrg 1887e6fb56fSmrg if (pVIADRI->ringBufActive) 1897e6fb56fSmrg return TRUE; 1907e6fb56fSmrg 1917e6fb56fSmrg if (pVia->agpEnable) { 1927e6fb56fSmrg drm_via_dma_init_t ringBufInit; 1937e6fb56fSmrg 1947e6fb56fSmrg if ((pVia->drmVerMajor == 1) && (pVia->drmVerMinor <= 3)) 1957e6fb56fSmrg return FALSE; 1967e6fb56fSmrg 1977e6fb56fSmrg /* 1988aedb4f6Smrg * Info from code-snippet on DRI-DEVEL list; Erdi Chen. 1997e6fb56fSmrg */ 2007e6fb56fSmrg 2017e6fb56fSmrg switch (pVia->ChipId) { 2027e6fb56fSmrg case PCI_CHIP_VT3314: 2037e6fb56fSmrg case PCI_CHIP_VT3259: 2047e6fb56fSmrg pVIADRI->reg_pause_addr = 0x40c; 2057e6fb56fSmrg break; 2067e6fb56fSmrg default: 2077e6fb56fSmrg pVIADRI->reg_pause_addr = 0x418; 2087e6fb56fSmrg break; 2097e6fb56fSmrg } 2107e6fb56fSmrg 2117e6fb56fSmrg ringBufInit.offset = pVia->agpSize; 2127e6fb56fSmrg ringBufInit.size = AGP_CMDBUF_SIZE; 2137e6fb56fSmrg ringBufInit.reg_pause_addr = pVIADRI->reg_pause_addr; 2147e6fb56fSmrg ringBufInit.func = VIA_INIT_DMA; 2157e6fb56fSmrg 2168aedb4f6Smrg if (drmCommandWrite(pVia->drmmode.fd, DRM_VIA_DMA_INIT, &ringBufInit, 2177e6fb56fSmrg sizeof(ringBufInit))) { 2187e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2197e6fb56fSmrg "[drm] Failed to initialize DMA ring-buffer: %d\n", 2207e6fb56fSmrg errno); 2217e6fb56fSmrg return FALSE; 2227e6fb56fSmrg } 2237e6fb56fSmrg 2247e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2257e6fb56fSmrg "[drm] Initialized AGP ring-buffer, size 0x%lx at AGP " 2267e6fb56fSmrg "offset 0x%lx.\n", ringBufInit.size, ringBufInit.offset); 2277e6fb56fSmrg pVIADRI->ringBufActive = 1; 2287e6fb56fSmrg } 2297e6fb56fSmrg return TRUE; 2307e6fb56fSmrg} 2317e6fb56fSmrg 2327e6fb56fSmrgstatic Bool 2337e6fb56fSmrgVIASetAgpMode(ScrnInfoPtr pScrn) 2347e6fb56fSmrg{ 2357e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 2368aedb4f6Smrg CARD32 mode = drmAgpGetMode(pVia->drmmode.fd); 2378aedb4f6Smrg unsigned int vendor = drmAgpVendorId(pVia->drmmode.fd); 2388aedb4f6Smrg unsigned int device = drmAgpDeviceId(pVia->drmmode.fd); 2397e6fb56fSmrg 2407e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Detected AGP " 2417e6fb56fSmrg "vendor 0x%04x, device 0x%04x\n", vendor, device); 2427e6fb56fSmrg 2437e6fb56fSmrg mode &= ~VIA_AGP_MODE_MASK; 2447e6fb56fSmrg if (mode & VIA_AGPv3_MODE) { 2457e6fb56fSmrg mode |= VIA_AGPv3_8X_MODE; 2467e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Found AGP v3 " 2477e6fb56fSmrg "compatible device. Trying AGP 8X mode.\n"); 2487e6fb56fSmrg } else { 2497e6fb56fSmrg mode |= VIA_AGP_4X_MODE; 2507e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Didn't find any AGP v3 " 2517e6fb56fSmrg "compatible device. Trying AGP 4X mode.\n"); 2527e6fb56fSmrg } 2537e6fb56fSmrg 2547e6fb56fSmrg mode |= VIA_AGP_FW_MODE; 2557e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2567e6fb56fSmrg "[drm] Trying to enable AGP fast writes.\n"); 2577e6fb56fSmrg 2588aedb4f6Smrg if (drmAgpEnable(pVia->drmmode.fd, mode) < 0) 2597e6fb56fSmrg return FALSE; 2607e6fb56fSmrg return TRUE; 2617e6fb56fSmrg} 2627e6fb56fSmrg 2637e6fb56fSmrgstatic Bool 2648aedb4f6SmrgVIADRIAgpInit(ScrnInfoPtr pScrn) 2657e6fb56fSmrg{ 2668aedb4f6Smrg unsigned long agpCmdSize, agp_phys; 2678aedb4f6Smrg VIAPtr pVia = VIAPTR(pScrn); 2688aedb4f6Smrg drm_handle_t handle; 2697e6fb56fSmrg drmAddress agpaddr; 2708aedb4f6Smrg drm_via_agp_t agp; 2718aedb4f6Smrg int agpPages; 2727e6fb56fSmrg 2737e6fb56fSmrg pVia->agpSize = 0; 2748aedb4f6Smrg if (drmAgpAcquire(pVia->drmmode.fd) < 0) { 2758aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] drmAgpAcquire failed %d\n", 2767e6fb56fSmrg errno); 2777e6fb56fSmrg return FALSE; 2787e6fb56fSmrg } 2797e6fb56fSmrg 2808aedb4f6Smrg if (!VIASetAgpMode(pScrn)) { 2818aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] VIASetAgpMode failed\n"); 2828aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 2837e6fb56fSmrg return FALSE; 2847e6fb56fSmrg } 2857e6fb56fSmrg 2867e6fb56fSmrg agpCmdSize = (pVia->agpEnable) ? AGP_CMDBUF_SIZE : 0; 2877e6fb56fSmrg if (pVia->agpMem * 1024 < agpCmdSize + AGP_PAGE_SIZE) { 2887e6fb56fSmrg pVia->agpMem = (agpCmdSize + AGP_PAGE_SIZE) / 1024; 2898aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2907e6fb56fSmrg "[drm] Forcing AGP size to %d kB\n", pVia->agpMem); 2917e6fb56fSmrg } 2927e6fb56fSmrg 2937e6fb56fSmrg agpPages = (pVia->agpMem * 1024 + AGP_PAGE_SIZE - 1) / AGP_PAGE_SIZE; 2948aedb4f6Smrg if (drmAgpAlloc(pVia->drmmode.fd, agpPages * AGP_PAGE_SIZE, 2957e6fb56fSmrg 0, &agp_phys, &pVia->agpHandle) < 0) { 2968aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] drmAgpAlloc failed\n"); 2978aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 2987e6fb56fSmrg return FALSE; 2997e6fb56fSmrg } 3007e6fb56fSmrg 3018aedb4f6Smrg if (drmAgpBind(pVia->drmmode.fd, pVia->agpHandle, 0) < 0) { 3028aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] drmAgpBind failed\n"); 3038aedb4f6Smrg drmAgpFree(pVia->drmmode.fd, pVia->agpHandle); 3048aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 3057e6fb56fSmrg return FALSE; 3067e6fb56fSmrg } 3077e6fb56fSmrg 3087e6fb56fSmrg /* 3097e6fb56fSmrg * Place the ring-buffer last in the AGP region, and restrict the 3107e6fb56fSmrg * public map not to include the buffer for security reasons. 3117e6fb56fSmrg */ 3127e6fb56fSmrg pVia->agpSize = agpPages * AGP_PAGE_SIZE - agpCmdSize; 3138aedb4f6Smrg pVia->agpAddr = drmAgpBase(pVia->drmmode.fd); 3148aedb4f6Smrg agp.offset = 0; 3158aedb4f6Smrg agp.size = pVia->agpSize; 3168aedb4f6Smrg if (drmCommandWrite(pVia->drmmode.fd, DRM_VIA_AGP_INIT, &agp, 3178aedb4f6Smrg sizeof(drm_via_agp_t)) < 0) { 3188aedb4f6Smrg drmAgpUnbind(pVia->drmmode.fd, pVia->agpHandle); 3198aedb4f6Smrg drmAgpFree(pVia->drmmode.fd, pVia->agpHandle); 3208aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 3218aedb4f6Smrg return FALSE; 3228aedb4f6Smrg } 3238aedb4f6Smrg 3248aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] drmAgpEnabled succeeded\n"); 3257e6fb56fSmrg 3268aedb4f6Smrg /* Allocate all of AGP memory */ 3278aedb4f6Smrg if (drmAddMap(pVia->drmmode.fd, 0, pVia->agpSize, 3288aedb4f6Smrg DRM_AGP, 0, &handle) < 0) { 3298aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3307e6fb56fSmrg "[drm] Failed to map public agp area.\n"); 3318aedb4f6Smrg pVia->agpSize = 0; 3328aedb4f6Smrg drmAgpUnbind(pVia->drmmode.fd, pVia->agpHandle); 3338aedb4f6Smrg drmAgpFree(pVia->drmmode.fd, pVia->agpHandle); 3348aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 3357e6fb56fSmrg return FALSE; 3367e6fb56fSmrg } 3378aedb4f6Smrg drmMap(pVia->drmmode.fd, handle, pVia->agpSize, &agpaddr); 3387e6fb56fSmrg pVia->agpMappedAddr = agpaddr; 3397e6fb56fSmrg 3408aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3417e6fb56fSmrg "[drm] agpAddr = 0x%08lx\n", pVia->agpAddr); 3428aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3437e6fb56fSmrg "[drm] agpSize = 0x%08x\n", pVia->agpSize); 3448aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3458aedb4f6Smrg "[drm] agp physical addr = %p\n", pVia->agpMappedAddr); 3467e6fb56fSmrg return TRUE; 3477e6fb56fSmrg} 3487e6fb56fSmrg 3497e6fb56fSmrgstatic Bool 3508aedb4f6SmrgVIADRIFBInit(ScrnInfoPtr pScrn) 3517e6fb56fSmrg{ 3528aedb4f6Smrg VIAPtr pVia = VIAPTR(pScrn); 3538aedb4f6Smrg drm_via_fb_t fb; 3547e6fb56fSmrg 3558aedb4f6Smrg fb.offset = pVia->FBFreeStart; 3568aedb4f6Smrg fb.size = pVia->FBFreeEnd; 3578aedb4f6Smrg if (drmCommandWrite(pVia->drmmode.fd, DRM_VIA_FB_INIT, &fb, 3588aedb4f6Smrg sizeof(drm_via_fb_t)) < 0) { 3598aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3608aedb4f6Smrg "[drm] Failed to initialize frame buffer area.\n"); 3617e6fb56fSmrg return FALSE; 3628aedb4f6Smrg } else { 3638aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3648aedb4f6Smrg "[drm] Using %d KB for DRM memory heap.\n", fb.size >> 10); 3658aedb4f6Smrg return TRUE; 3667e6fb56fSmrg } 3677e6fb56fSmrg} 3687e6fb56fSmrg 3697e6fb56fSmrgstatic Bool 3707e6fb56fSmrgVIAInitVisualConfigs(ScreenPtr pScreen) 3717e6fb56fSmrg{ 3728aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 3737e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 3747e6fb56fSmrg int numConfigs = 0; 3757e6fb56fSmrg __GLXvisualConfig *pConfigs = 0; 3767e6fb56fSmrg VIAConfigPrivPtr pVIAConfigs = 0; 3777e6fb56fSmrg VIAConfigPrivPtr *pVIAConfigPtrs = 0; 3787e6fb56fSmrg int i, db, stencil, accum; 3797e6fb56fSmrg 3807e6fb56fSmrg if (pScrn->bitsPerPixel == 16 || pScrn->bitsPerPixel == 32) { 3817e6fb56fSmrg numConfigs = 12; 3827e6fb56fSmrg if (!(pConfigs = (__GLXvisualConfig *) 3838aedb4f6Smrg calloc(sizeof(__GLXvisualConfig), numConfigs))) 3847e6fb56fSmrg return FALSE; 3857e6fb56fSmrg if (!(pVIAConfigs = (VIAConfigPrivPtr) 3868aedb4f6Smrg calloc(sizeof(VIAConfigPrivRec), numConfigs))) { 3878aedb4f6Smrg free(pConfigs); 3887e6fb56fSmrg return FALSE; 3897e6fb56fSmrg } 3907e6fb56fSmrg if (!(pVIAConfigPtrs = (VIAConfigPrivPtr *) 3918aedb4f6Smrg calloc(sizeof(VIAConfigPrivPtr), numConfigs))) { 3928aedb4f6Smrg free(pConfigs); 3938aedb4f6Smrg free(pVIAConfigs); 3947e6fb56fSmrg return FALSE; 3957e6fb56fSmrg } 3967e6fb56fSmrg for (i = 0; i < numConfigs; i++) 3977e6fb56fSmrg pVIAConfigPtrs[i] = &pVIAConfigs[i]; 3987e6fb56fSmrg 3997e6fb56fSmrg i = 0; 4007e6fb56fSmrg for (accum = 0; accum <= 1; accum++) { 4017e6fb56fSmrg /* 32bpp depth buffer disabled, as Mesa has limitations */ 4027e6fb56fSmrg for (stencil = 0; stencil <= 2; stencil++) { 4037e6fb56fSmrg for (db = 0; db <= 1; db++) { 4047e6fb56fSmrg pConfigs[i].vid = -1; 4057e6fb56fSmrg pConfigs[i].class = -1; 4067e6fb56fSmrg pConfigs[i].rgba = TRUE; 4077e6fb56fSmrg pConfigs[i].redSize = -1; 4087e6fb56fSmrg pConfigs[i].greenSize = -1; 4097e6fb56fSmrg pConfigs[i].blueSize = -1; 4107e6fb56fSmrg pConfigs[i].redMask = -1; 4117e6fb56fSmrg pConfigs[i].greenMask = -1; 4127e6fb56fSmrg pConfigs[i].blueMask = -1; 4137e6fb56fSmrg if (pScrn->bitsPerPixel == 32) { 4147e6fb56fSmrg pConfigs[i].alphaSize = 8; 4157e6fb56fSmrg pConfigs[i].alphaMask = 0xFF000000; 4167e6fb56fSmrg } else { 4177e6fb56fSmrg pConfigs[i].alphaSize = 0; 4187e6fb56fSmrg pConfigs[i].alphaMask = 0; 4197e6fb56fSmrg } 4207e6fb56fSmrg 4217e6fb56fSmrg if (accum) { 4227e6fb56fSmrg pConfigs[i].accumRedSize = 16; 4237e6fb56fSmrg pConfigs[i].accumGreenSize = 16; 4247e6fb56fSmrg pConfigs[i].accumBlueSize = 16; 4257e6fb56fSmrg if (pScrn->bitsPerPixel == 32) 4267e6fb56fSmrg pConfigs[i].accumAlphaSize = 16; 4277e6fb56fSmrg else 4287e6fb56fSmrg pConfigs[i].accumAlphaSize = 0; 4297e6fb56fSmrg } else { 4307e6fb56fSmrg pConfigs[i].accumRedSize = 0; 4317e6fb56fSmrg pConfigs[i].accumGreenSize = 0; 4327e6fb56fSmrg pConfigs[i].accumBlueSize = 0; 4337e6fb56fSmrg pConfigs[i].accumAlphaSize = 0; 4347e6fb56fSmrg } 4357e6fb56fSmrg if (!db) 4367e6fb56fSmrg pConfigs[i].doubleBuffer = TRUE; 4377e6fb56fSmrg else 4387e6fb56fSmrg pConfigs[i].doubleBuffer = FALSE; 4397e6fb56fSmrg 4407e6fb56fSmrg pConfigs[i].stereo = FALSE; 4417e6fb56fSmrg pConfigs[i].bufferSize = -1; 4427e6fb56fSmrg 4437e6fb56fSmrg switch (stencil) { 4447e6fb56fSmrg case 0: 4457e6fb56fSmrg pConfigs[i].depthSize = 24; 4467e6fb56fSmrg pConfigs[i].stencilSize = 8; 4477e6fb56fSmrg break; 4487e6fb56fSmrg case 1: 4497e6fb56fSmrg pConfigs[i].depthSize = 16; 4507e6fb56fSmrg pConfigs[i].stencilSize = 0; 4517e6fb56fSmrg break; 4527e6fb56fSmrg case 2: 4537e6fb56fSmrg pConfigs[i].depthSize = 0; 4547e6fb56fSmrg pConfigs[i].stencilSize = 0; 4557e6fb56fSmrg break; 4567e6fb56fSmrg case 3: 4577e6fb56fSmrg pConfigs[i].depthSize = 32; 4587e6fb56fSmrg pConfigs[i].stencilSize = 0; 4597e6fb56fSmrg break; 4607e6fb56fSmrg } 4617e6fb56fSmrg 4627e6fb56fSmrg pConfigs[i].auxBuffers = 0; 4637e6fb56fSmrg pConfigs[i].level = 0; 4647e6fb56fSmrg if (accum) 4657e6fb56fSmrg pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; 4667e6fb56fSmrg else 4677e6fb56fSmrg pConfigs[i].visualRating = GLX_NONE_EXT; 4687e6fb56fSmrg pConfigs[i].transparentPixel = GLX_NONE_EXT; 4697e6fb56fSmrg pConfigs[i].transparentRed = 0; 4707e6fb56fSmrg pConfigs[i].transparentGreen = 0; 4717e6fb56fSmrg pConfigs[i].transparentBlue = 0; 4727e6fb56fSmrg pConfigs[i].transparentAlpha = 0; 4737e6fb56fSmrg pConfigs[i].transparentIndex = 0; 4747e6fb56fSmrg i++; 4757e6fb56fSmrg } 4767e6fb56fSmrg } 4777e6fb56fSmrg } 4787e6fb56fSmrg 4797e6fb56fSmrg if (i != numConfigs) { 4807e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] Incorrect " 4817e6fb56fSmrg "initialization of visuals. Disabling DRI.\n"); 48244802259Smrg 48344802259Smrg if (pConfigs) 48444802259Smrg free(pConfigs); 48544802259Smrg if (pVIAConfigs) 48644802259Smrg free(pVIAConfigs); 48744802259Smrg if (pVIAConfigPtrs) 48844802259Smrg free(pVIAConfigPtrs); 48944802259Smrg 4907e6fb56fSmrg return FALSE; 4917e6fb56fSmrg } 4927e6fb56fSmrg } 4937e6fb56fSmrg 4947e6fb56fSmrg pVia->numVisualConfigs = numConfigs; 4957e6fb56fSmrg pVia->pVisualConfigs = pConfigs; 4967e6fb56fSmrg pVia->pVisualConfigsPriv = pVIAConfigs; 4977e6fb56fSmrg GlxSetVisualConfigs(numConfigs, pConfigs, (void **)pVIAConfigPtrs); 4987e6fb56fSmrg 4997e6fb56fSmrg return TRUE; 5007e6fb56fSmrg} 5017e6fb56fSmrg 5027e6fb56fSmrgBool 5038aedb4f6SmrgVIADRI1ScreenInit(ScreenPtr pScreen) 5047e6fb56fSmrg{ 5058aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 5067e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 5078aedb4f6Smrg int major, minor, patch; 5087e6fb56fSmrg DRIInfoPtr pDRIInfo; 5097e6fb56fSmrg VIADRIPtr pVIADRI; 5107e6fb56fSmrg 5117e6fb56fSmrg /* If symbols or version check fails, we still want this to be NULL. */ 5127e6fb56fSmrg pVia->pDRIInfo = NULL; 5138aedb4f6Smrg drmClose(pVia->drmmode.fd); 5147e6fb56fSmrg 5157e6fb56fSmrg /* Check that the GLX, DRI, and DRM modules have been loaded by testing 5167e6fb56fSmrg * for canonical symbols in each module. */ 5177e6fb56fSmrg if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) 5187e6fb56fSmrg return FALSE; 5197e6fb56fSmrg if (!xf86LoaderCheckSymbol("drmAvailable")) 5207e6fb56fSmrg return FALSE; 5217e6fb56fSmrg if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { 5228aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5238aedb4f6Smrg "[dri] VIADRI1ScreenInit failed (libdri.a is too old).\n"); 5247e6fb56fSmrg return FALSE; 5257e6fb56fSmrg } 5267e6fb56fSmrg 5277e6fb56fSmrg /* Check the DRI version. */ 5288aedb4f6Smrg DRIQueryVersion(&major, &minor, &patch); 5298aedb4f6Smrg if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { 5308aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5318aedb4f6Smrg "[dri] VIADRI1ScreenInit failed -- FALSE mismatch.\n" 5328aedb4f6Smrg "[dri] libdri is %d.%d.%d, but %d.%d.x is needed.\n" 5338aedb4f6Smrg "[dri] Disabling DRI.\n", 5348aedb4f6Smrg major, minor, patch, 5358aedb4f6Smrg DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); 5368aedb4f6Smrg return FALSE; 5377e6fb56fSmrg } 5387e6fb56fSmrg 5397e6fb56fSmrg pVia->pDRIInfo = DRICreateInfoRec(); 5407e6fb56fSmrg if (!pVia->pDRIInfo) 5417e6fb56fSmrg return FALSE; 5427e6fb56fSmrg 5437e6fb56fSmrg pDRIInfo = pVia->pDRIInfo; 5447e6fb56fSmrg pDRIInfo->drmDriverName = VIAKernelDriverName; 5457e6fb56fSmrg switch (pVia->Chipset) { 5467e6fb56fSmrg case VIA_K8M890: 5477e6fb56fSmrg case VIA_P4M900: 5487e6fb56fSmrg case VIA_VX800: 5497e6fb56fSmrg case VIA_VX855: 5508aedb4f6Smrg case VIA_VX900: 5517e6fb56fSmrg pDRIInfo->clientDriverName = "swrast"; 5527e6fb56fSmrg break; 5537e6fb56fSmrg default: 5547e6fb56fSmrg pDRIInfo->clientDriverName = VIAClientDriverName; 5557e6fb56fSmrg break; 5567e6fb56fSmrg } 5578aedb4f6Smrg#if 0 558485acf3eSjmcneill if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 559485acf3eSjmcneill pDRIInfo->busIdString = DRICreatePCIBusID(pVia->PciInfo); 560485acf3eSjmcneill } else { 561485acf3eSjmcneill pDRIInfo->busIdString = xalloc(64); 562485acf3eSjmcneill sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", 5637e6fb56fSmrg#ifdef XSERVER_LIBPCIACCESS 564485acf3eSjmcneill ((pVia->PciInfo->domain << 8) | pVia->PciInfo->bus), 565485acf3eSjmcneill pVia->PciInfo->dev, pVia->PciInfo->func 5667e6fb56fSmrg#else 567485acf3eSjmcneill ((pciConfigPtr)pVia->PciInfo->thisCard)->busnum, 568485acf3eSjmcneill ((pciConfigPtr)pVia->PciInfo->thisCard)->devnum, 569485acf3eSjmcneill ((pciConfigPtr)pVia->PciInfo->thisCard)->funcnum 5707e6fb56fSmrg#endif 571485acf3eSjmcneill ); 572485acf3eSjmcneill } 5738aedb4f6Smrg#else 5748aedb4f6Smrg pDRIInfo->busIdString = DRICreatePCIBusID(pVia->PciInfo); 5758aedb4f6Smrg#endif 5767e6fb56fSmrg pDRIInfo->ddxDriverMajorVersion = VIA_DRIDDX_VERSION_MAJOR; 5777e6fb56fSmrg pDRIInfo->ddxDriverMinorVersion = VIA_DRIDDX_VERSION_MINOR; 5787e6fb56fSmrg pDRIInfo->ddxDriverPatchVersion = VIA_DRIDDX_VERSION_PATCH; 5797e6fb56fSmrg#if (DRIINFO_MAJOR_VERSION == 5) 5807e6fb56fSmrg pDRIInfo->frameBufferPhysicalAddress = (pointer) pVia->FrameBufferBase; 5817e6fb56fSmrg#else 5827e6fb56fSmrg pDRIInfo->frameBufferPhysicalAddress = pVia->FrameBufferBase; 5837e6fb56fSmrg#endif 5847e6fb56fSmrg pDRIInfo->frameBufferSize = pVia->videoRambytes; 5857e6fb56fSmrg 5867e6fb56fSmrg pDRIInfo->frameBufferStride = (pScrn->displayWidth * 5877e6fb56fSmrg pScrn->bitsPerPixel / 8); 5887e6fb56fSmrg pDRIInfo->ddxDrawableTableEntry = VIA_MAX_DRAWABLES; 5897e6fb56fSmrg 5907e6fb56fSmrg if (SAREA_MAX_DRAWABLES < VIA_MAX_DRAWABLES) 5917e6fb56fSmrg pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 5927e6fb56fSmrg else 5937e6fb56fSmrg pDRIInfo->maxDrawableTableEntry = VIA_MAX_DRAWABLES; 5947e6fb56fSmrg 5957e6fb56fSmrg#ifdef NOT_DONE 5967e6fb56fSmrg /* FIXME: need to extend DRI protocol to pass this size back to client 5977e6fb56fSmrg * for SAREA mapping that includes a device private record. */ 5987e6fb56fSmrg pDRIInfo->SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ 5997e6fb56fSmrg /* + shared memory device private rec */ 6007e6fb56fSmrg#else 6017e6fb56fSmrg /* For now the mapping works by using a fixed size defined 6027e6fb56fSmrg * in the SAREA header. */ 6037e6fb56fSmrg if (sizeof(XF86DRISAREARec) + sizeof(drm_via_sarea_t) > SAREA_MAX) { 6047e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Data does not fit in SAREA\n"); 6057e6fb56fSmrg DRIDestroyInfoRec(pVia->pDRIInfo); 6067e6fb56fSmrg pVia->pDRIInfo = NULL; 6077e6fb56fSmrg return FALSE; 6087e6fb56fSmrg } 6097e6fb56fSmrg pDRIInfo->SAREASize = SAREA_MAX; 6107e6fb56fSmrg#endif 6117e6fb56fSmrg 6128aedb4f6Smrg if (!(pVIADRI = (VIADRIPtr) calloc(sizeof(VIADRIRec), 1))) { 6137e6fb56fSmrg DRIDestroyInfoRec(pVia->pDRIInfo); 6147e6fb56fSmrg pVia->pDRIInfo = NULL; 6157e6fb56fSmrg return FALSE; 6167e6fb56fSmrg } 6177e6fb56fSmrg pDRIInfo->devPrivate = pVIADRI; 6187e6fb56fSmrg pDRIInfo->devPrivateSize = sizeof(VIADRIRec); 6197e6fb56fSmrg pDRIInfo->contextSize = sizeof(VIADRIContextRec); 6207e6fb56fSmrg 6217e6fb56fSmrg pDRIInfo->CreateContext = VIACreateContext; 6227e6fb56fSmrg pDRIInfo->DestroyContext = VIADestroyContext; 6237e6fb56fSmrg pDRIInfo->SwapContext = VIADRISwapContext; 6247e6fb56fSmrg pDRIInfo->InitBuffers = VIADRIInitBuffers; 6257e6fb56fSmrg pDRIInfo->MoveBuffers = VIADRIMoveBuffers; 6267e6fb56fSmrg pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 6277e6fb56fSmrg 6288aedb4f6Smrg if (!DRIScreenInit(pScreen, pDRIInfo, &pVia->drmmode.fd)) { 6298aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 6307e6fb56fSmrg "[dri] DRIScreenInit failed. Disabling DRI.\n"); 6318aedb4f6Smrg free(pDRIInfo->devPrivate); 6327e6fb56fSmrg pDRIInfo->devPrivate = NULL; 6337e6fb56fSmrg DRIDestroyInfoRec(pVia->pDRIInfo); 6347e6fb56fSmrg pVia->pDRIInfo = NULL; 6358aedb4f6Smrg pVia->drmmode.fd = -1; 6367e6fb56fSmrg return FALSE; 6377e6fb56fSmrg } 6387e6fb56fSmrg 6397e6fb56fSmrg if (!(VIAInitVisualConfigs(pScreen))) { 6407e6fb56fSmrg VIADRICloseScreen(pScreen); 6417e6fb56fSmrg return FALSE; 6427e6fb56fSmrg } 6437e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized.\n"); 6447e6fb56fSmrg 6457e6fb56fSmrg /* DRIScreenInit doesn't add all the common mappings. 6467e6fb56fSmrg * Add additional mappings here. */ 6477e6fb56fSmrg if (!VIADRIMapInit(pScreen, pVia)) { 6487e6fb56fSmrg VIADRICloseScreen(pScreen); 6497e6fb56fSmrg return FALSE; 6507e6fb56fSmrg } 6517e6fb56fSmrg pVIADRI->regs.size = VIA_MMIO_REGSIZE; 6527e6fb56fSmrg pVIADRI->regs.handle = pVia->registerHandle; 6538aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] mmio Registers = 0x%08lx\n", 6547e6fb56fSmrg (unsigned long)pVIADRI->regs.handle); 6557e6fb56fSmrg 6567e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n"); 6577e6fb56fSmrg return TRUE; 6587e6fb56fSmrg} 6597e6fb56fSmrg 6607e6fb56fSmrgvoid 6617e6fb56fSmrgVIADRICloseScreen(ScreenPtr pScreen) 6627e6fb56fSmrg{ 6638aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 6647e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 6657e6fb56fSmrg VIADRIPtr pVIADRI; 6667e6fb56fSmrg 6677e6fb56fSmrg VIADRIRingBufferCleanup(pScrn); 6687e6fb56fSmrg if (pVia->agpSize) { 6697e6fb56fSmrg drmUnmap(pVia->agpMappedAddr, pVia->agpSize); 6708aedb4f6Smrg drmRmMap(pVia->drmmode.fd, pVia->agpHandle); 6718aedb4f6Smrg drmAgpUnbind(pVia->drmmode.fd, pVia->agpHandle); 6728aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Freeing agp memory\n"); 6738aedb4f6Smrg drmAgpFree(pVia->drmmode.fd, pVia->agpHandle); 6748aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Releasing agp module\n"); 6758aedb4f6Smrg drmAgpRelease(pVia->drmmode.fd); 6767e6fb56fSmrg } 6777e6fb56fSmrg 6787e6fb56fSmrg DRICloseScreen(pScreen); 6798aedb4f6Smrg drm_bo_free(pScrn, pVia->driOffScreenMem); 6807e6fb56fSmrg 6817e6fb56fSmrg if (pVia->pDRIInfo) { 6827e6fb56fSmrg if ((pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate)) { 6837e6fb56fSmrg VIADRIIrqExit(pScrn, pVIADRI); 6848aedb4f6Smrg free(pVIADRI); 6857e6fb56fSmrg pVia->pDRIInfo->devPrivate = NULL; 6867e6fb56fSmrg } 6877e6fb56fSmrg DRIDestroyInfoRec(pVia->pDRIInfo); 6887e6fb56fSmrg pVia->pDRIInfo = NULL; 6897e6fb56fSmrg } 6907e6fb56fSmrg 6917e6fb56fSmrg if (pVia->pVisualConfigs) { 6928aedb4f6Smrg free(pVia->pVisualConfigs); 6937e6fb56fSmrg pVia->pVisualConfigs = NULL; 6947e6fb56fSmrg } 6957e6fb56fSmrg if (pVia->pVisualConfigsPriv) { 6968aedb4f6Smrg free(pVia->pVisualConfigsPriv); 6977e6fb56fSmrg pVia->pVisualConfigsPriv = NULL; 6987e6fb56fSmrg } 6997e6fb56fSmrg} 7007e6fb56fSmrg 7017e6fb56fSmrg/* TODO: xserver receives driver's swapping event and does something 7027e6fb56fSmrg * according the data initialized in this function. 7037e6fb56fSmrg */ 7047e6fb56fSmrgstatic Bool 7057e6fb56fSmrgVIACreateContext(ScreenPtr pScreen, VisualPtr visual, 7067e6fb56fSmrg drm_context_t hwContext, void *pVisualConfigPriv, 7077e6fb56fSmrg DRIContextType contextStore) 7087e6fb56fSmrg{ 7097e6fb56fSmrg return TRUE; 7107e6fb56fSmrg} 7117e6fb56fSmrg 7127e6fb56fSmrgstatic void 7137e6fb56fSmrgVIADestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 7147e6fb56fSmrg DRIContextType contextStore) 7157e6fb56fSmrg{ 7167e6fb56fSmrg} 7177e6fb56fSmrg 7187e6fb56fSmrgBool 7197e6fb56fSmrgVIADRIFinishScreenInit(ScreenPtr pScreen) 7207e6fb56fSmrg{ 7218aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7227e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 7237e6fb56fSmrg VIADRIPtr pVIADRI; 7247e6fb56fSmrg 7257e6fb56fSmrg pVia->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; 7268aedb4f6Smrg pVia->agpDMA = FALSE; 7277e6fb56fSmrg 7288aedb4f6Smrg pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate; 7298aedb4f6Smrg pVIADRI->drixinerama = FALSE; 7307e6fb56fSmrg 7318aedb4f6Smrg if (pVia->driSize < pVia->Bpl) { 7327e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 7338aedb4f6Smrg "[drm] No DRM framebuffer heap available.\n" 7348aedb4f6Smrg "[drm] Please increase the frame buffer\n" 7358aedb4f6Smrg "[drm] memory area in the BIOS. Disabling DRI.\n"); 7367e6fb56fSmrg return FALSE; 7377e6fb56fSmrg } 7388aedb4f6Smrg if (pVia->driSize < 3 * (pScrn->virtualY * pVia->Bpl)) { 7398aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 7408aedb4f6Smrg "[drm] The DRM heap and pixmap cache memory may be too\n" 7418aedb4f6Smrg "[drm] small for optimal performance. Please increase\n" 7428aedb4f6Smrg "[drm] the frame buffer memory area in the BIOS.\n"); 7438aedb4f6Smrg } 7447e6fb56fSmrg 7458aedb4f6Smrg pVia->driOffScreenMem = drm_bo_alloc(pScrn, pVia->driSize, 16, TTM_PL_FLAG_VRAM); 7467e6fb56fSmrg 7477e6fb56fSmrg DRIFinishScreenInit(pScreen); 7487e6fb56fSmrg 7497e6fb56fSmrg /* Set SAREA value. */ 7507e6fb56fSmrg { 7517e6fb56fSmrg drm_via_sarea_t *saPriv; 7527e6fb56fSmrg 7537e6fb56fSmrg saPriv = (drm_via_sarea_t *) DRIGetSAREAPrivate(pScreen); 7547e6fb56fSmrg assert(saPriv); 7557e6fb56fSmrg memset(saPriv, 0, sizeof(*saPriv)); 7567e6fb56fSmrg saPriv->ctxOwner = -1; 7577e6fb56fSmrg } 7587e6fb56fSmrg pVIADRI->deviceID = pVia->Chipset; 7597e6fb56fSmrg pVIADRI->width = pScrn->virtualX; 7607e6fb56fSmrg pVIADRI->height = pScrn->virtualY; 7617e6fb56fSmrg pVIADRI->mem = pScrn->videoRam * 1024; 7627e6fb56fSmrg pVIADRI->bytesPerPixel = (pScrn->bitsPerPixel + 7) / 8; 7637e6fb56fSmrg pVIADRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 7647e6fb56fSmrg /* TODO */ 7657e6fb56fSmrg pVIADRI->scrnX = pVIADRI->width; 7667e6fb56fSmrg pVIADRI->scrnY = pVIADRI->height; 7677e6fb56fSmrg 7687e6fb56fSmrg /* Initialize IRQ. */ 7697e6fb56fSmrg if (pVia->DRIIrqEnable) 7707e6fb56fSmrg VIADRIIrqInit(pScrn, pVIADRI); 7717e6fb56fSmrg 7727e6fb56fSmrg pVIADRI->ringBufActive = 0; 7737e6fb56fSmrg VIADRIRingBufferInit(pScrn); 7748aedb4f6Smrg pVia->agpDMA = pVia->dma2d && pVIADRI->ringBufActive; 7757e6fb56fSmrg return TRUE; 7767e6fb56fSmrg} 7777e6fb56fSmrg 7787e6fb56fSmrgstatic void 7797e6fb56fSmrgVIADRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 7807e6fb56fSmrg DRIContextType oldContextType, void *oldContext, 7817e6fb56fSmrg DRIContextType newContextType, void *newContext) 7827e6fb56fSmrg{ 7837e6fb56fSmrg#if 0 7848aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7857e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 7867e6fb56fSmrg#endif 7877e6fb56fSmrg return; 7887e6fb56fSmrg} 7897e6fb56fSmrg 7907e6fb56fSmrgstatic void 7917e6fb56fSmrgVIADRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) 7927e6fb56fSmrg{ 7937e6fb56fSmrg#if 0 7947e6fb56fSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 7958aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 7967e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 7977e6fb56fSmrg#endif 7987e6fb56fSmrg return; 7997e6fb56fSmrg} 8007e6fb56fSmrg 8017e6fb56fSmrgstatic void 8027e6fb56fSmrgVIADRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 8037e6fb56fSmrg RegionPtr prgnSrc, CARD32 index) 8047e6fb56fSmrg{ 8057e6fb56fSmrg#if 0 8067e6fb56fSmrg ScreenPtr pScreen = pParent->drawable.pScreen; 8078aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 8087e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 8097e6fb56fSmrg#endif 8107e6fb56fSmrg return; 8117e6fb56fSmrg} 8127e6fb56fSmrg 8137e6fb56fSmrg/* Initialize the kernel data structures. */ 8148aedb4f6SmrgBool 8158aedb4f6SmrgVIADRIKernelInit(ScrnInfoPtr pScrn) 8167e6fb56fSmrg{ 8178aedb4f6Smrg VIAPtr pVia = VIAPTR(pScrn); 8187e6fb56fSmrg drm_via_init_t drmInfo; 8197e6fb56fSmrg 8208aedb4f6Smrg pVia->IsPCI = !VIADRIAgpInit(pScrn); 8218aedb4f6Smrg if (pVia->IsPCI) 8228aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Using PCI.\n"); 8238aedb4f6Smrg else 8248aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Using AGP.\n"); 8258aedb4f6Smrg 8268aedb4f6Smrg if (!(VIADRIFBInit(pScrn))) { 8278aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 8288aedb4f6Smrg "[dri] Frame buffer initialization failed.\n"); 8298aedb4f6Smrg return FALSE; 8308aedb4f6Smrg } 8318aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Frame buffer initialized.\n"); 8328aedb4f6Smrg 8337e6fb56fSmrg memset(&drmInfo, 0, sizeof(drm_via_init_t)); 8347e6fb56fSmrg drmInfo.func = VIA_INIT_MAP; 8357e6fb56fSmrg drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); 8367e6fb56fSmrg drmInfo.fb_offset = pVia->frameBufferHandle; 8377e6fb56fSmrg drmInfo.mmio_offset = pVia->registerHandle; 8387e6fb56fSmrg 8397e6fb56fSmrg if (pVia->IsPCI) { 8408aedb4f6Smrg drmInfo.agpAddr = 0; 8417e6fb56fSmrg } else { 8427e6fb56fSmrg /*For AMD64*/ 8437e6fb56fSmrg#ifndef __x86_64__ 8448aedb4f6Smrg drmInfo.agpAddr = (CARD32)pVia->agpAddr; 8457e6fb56fSmrg#else 8468aedb4f6Smrg drmInfo.agpAddr = (CARD64)pVia->agpAddr; 8477e6fb56fSmrg#endif 8487e6fb56fSmrg } 8497e6fb56fSmrg 8508aedb4f6Smrg if ((drmCommandWrite(pVia->drmmode.fd, DRM_VIA_MAP_INIT, &drmInfo, 8517e6fb56fSmrg sizeof(drm_via_init_t))) < 0) 8527e6fb56fSmrg return FALSE; 8537e6fb56fSmrg 8548aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Kernel data initialized.\n"); 8557e6fb56fSmrg return TRUE; 8567e6fb56fSmrg} 8577e6fb56fSmrg 8587e6fb56fSmrg/* Add a map for the MMIO registers. */ 8597e6fb56fSmrgstatic Bool 8607e6fb56fSmrgVIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia) 8617e6fb56fSmrg{ 8628aedb4f6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 8637e6fb56fSmrg int flags = DRM_READ_ONLY; 8647e6fb56fSmrg 8658aedb4f6Smrg if (drmAddMap(pVia->drmmode.fd, pVia->MmioBase, VIA_MMIO_REGSIZE, 8667e6fb56fSmrg DRM_REGISTERS, flags, &pVia->registerHandle) < 0) { 8677e6fb56fSmrg return FALSE; 8687e6fb56fSmrg } 8698aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] register handle = 0x%08lx\n", 8707e6fb56fSmrg (unsigned long)pVia->registerHandle); 8718aedb4f6Smrg if (drmAddMap(pVia->drmmode.fd, pVia->FrameBufferBase, pVia->videoRambytes, 8727e6fb56fSmrg DRM_FRAME_BUFFER, 0, &pVia->frameBufferHandle) < 0) { 8737e6fb56fSmrg return FALSE; 8747e6fb56fSmrg } 8758aedb4f6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] framebuffer handle = 0x%08lx\n", 8767e6fb56fSmrg (unsigned long)pVia->frameBufferHandle); 8777e6fb56fSmrg 8787e6fb56fSmrg return TRUE; 8797e6fb56fSmrg} 8807e6fb56fSmrg 8817e6fb56fSmrg#define DRM_VIA_BLIT_MAX_SIZE (2048*2048*4) 8827e6fb56fSmrg 8837e6fb56fSmrgstatic int 8848aedb4f6SmrgviaDRIFBMemcpy(int fd, struct buffer_object *vram, unsigned char *addr, 8858aedb4f6Smrg Bool toFB) 8867e6fb56fSmrg{ 8878aedb4f6Smrg unsigned long fbOffset = vram->offset, size = vram->size, curSize; 8887e6fb56fSmrg drm_via_dmablit_t blit; 8898aedb4f6Smrg int err; 8907e6fb56fSmrg 8917e6fb56fSmrg do { 8927e6fb56fSmrg curSize = (size > DRM_VIA_BLIT_MAX_SIZE) ? DRM_VIA_BLIT_MAX_SIZE : size; 8937e6fb56fSmrg 8947e6fb56fSmrg blit.num_lines = 1; 8957e6fb56fSmrg blit.line_length = curSize; 8967e6fb56fSmrg blit.fb_addr = fbOffset; 8977e6fb56fSmrg blit.fb_stride = ALIGN_TO(curSize, 16); 8987e6fb56fSmrg blit.mem_addr = addr; 8997e6fb56fSmrg blit.mem_stride = blit.fb_stride; 9007e6fb56fSmrg blit.to_fb = (toFB) ? 1 : 0; 9017e6fb56fSmrg 9027e6fb56fSmrg do { 9037e6fb56fSmrg err = drmCommandWriteRead(fd, DRM_VIA_DMA_BLIT, 9047e6fb56fSmrg &blit, sizeof(blit)); 9057e6fb56fSmrg } while (-EAGAIN == err); 9067e6fb56fSmrg if (err) 9077e6fb56fSmrg return err; 9087e6fb56fSmrg 9097e6fb56fSmrg do { 9107e6fb56fSmrg err = drmCommandWriteRead(fd, DRM_VIA_BLIT_SYNC, 9117e6fb56fSmrg &blit.sync, sizeof(blit.sync)); 9127e6fb56fSmrg } while (-EAGAIN == err); 9137e6fb56fSmrg if (err) 9147e6fb56fSmrg return err; 9157e6fb56fSmrg 9167e6fb56fSmrg fbOffset += curSize; 9177e6fb56fSmrg addr += curSize; 9187e6fb56fSmrg size -= curSize; 9197e6fb56fSmrg 9207e6fb56fSmrg } while (size > 0); 9217e6fb56fSmrg return 0; 9227e6fb56fSmrg} 9237e6fb56fSmrg 9247e6fb56fSmrgvoid 9257e6fb56fSmrgviaDRIOffscreenSave(ScrnInfoPtr pScrn) 9267e6fb56fSmrg{ 9277e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 9288aedb4f6Smrg unsigned long srcSize = pVia->driOffScreenMem->size; 9297e6fb56fSmrg int err; 9307e6fb56fSmrg 9317e6fb56fSmrg if (pVia->driOffScreenSave) 9327e6fb56fSmrg free(pVia->driOffScreenSave); 9337e6fb56fSmrg 9348aedb4f6Smrg pVia->driOffScreenSave = malloc(srcSize + 16); 9357e6fb56fSmrg if (pVia->driOffScreenSave) { 9368aedb4f6Smrg void *dst, *src = drm_bo_map(pScrn, pVia->driOffScreenMem); 9378aedb4f6Smrg 93844802259Smrg dst = (void *) ALIGN_TO((unsigned long) pVia->driOffScreenSave, 16); 9397e6fb56fSmrg if ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 8)) { 9408aedb4f6Smrg err = viaDRIFBMemcpy(pVia->drmmode.fd, pVia->driOffScreenMem, dst, FALSE); 9417e6fb56fSmrg if (!err) 9427e6fb56fSmrg return; 9437e6fb56fSmrg 9447e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 9457e6fb56fSmrg "Hardware backup of DRI offscreen memory failed: %s.\n" 9467e6fb56fSmrg "\tUsing slow software backup instead.\n", 9477e6fb56fSmrg strerror(-err)); 9487e6fb56fSmrg } 9498aedb4f6Smrg memcpy(dst, src, srcSize); 9508aedb4f6Smrg drm_bo_unmap(pScrn, pVia->driOffScreenMem); 9517e6fb56fSmrg } else { 9527e6fb56fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 9537e6fb56fSmrg "Out of memory trying to backup DRI offscreen memory.\n"); 9547e6fb56fSmrg } 9557e6fb56fSmrg return; 9567e6fb56fSmrg} 9577e6fb56fSmrg 9587e6fb56fSmrgvoid 9597e6fb56fSmrgviaDRIOffscreenRestore(ScrnInfoPtr pScrn) 9607e6fb56fSmrg{ 9617e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 9627e6fb56fSmrg 9637e6fb56fSmrg if (pVia->driOffScreenSave) { 9648aedb4f6Smrg void *src, *dst = drm_bo_map(pScrn, pVia->driOffScreenMem); 9658aedb4f6Smrg 9668aedb4f6Smrg src = pVia->driOffScreenSave; 9678aedb4f6Smrg memcpy(dst, src, pVia->driOffScreenMem->size); 9687e6fb56fSmrg free(pVia->driOffScreenSave); 9697e6fb56fSmrg pVia->driOffScreenSave = NULL; 9708aedb4f6Smrg 9718aedb4f6Smrg drm_bo_unmap(pScrn, pVia->driOffScreenMem); 9728aedb4f6Smrg } else { 9737e6fb56fSmrg } 9747e6fb56fSmrg} 975