xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

sun_agp.c (8944B)


      1 /*
      2  * Abstraction of the AGP GART interface.
      3  *
      4  * This version is for Solaris.
      5  *
      6  * Copyright © 2000 VA Linux Systems, Inc.
      7  * Copyright © 2001 The XFree86 Project, Inc.
      8  */
      9 /* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
     10  *
     11  * Permission is hereby granted, free of charge, to any person obtaining a
     12  * copy of this software and associated documentation files (the "Software"),
     13  * to deal in the Software without restriction, including without limitation
     14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     15  * and/or sell copies of the Software, and to permit persons to whom the
     16  * Software is furnished to do so, subject to the following conditions:
     17  *
     18  * The above copyright notice and this permission notice (including the next
     19  * paragraph) shall be included in all copies or substantial portions of the
     20  * Software.
     21  *
     22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     28  * DEALINGS IN THE SOFTWARE.
     29  */
     30 
     31 #ifdef HAVE_XORG_CONFIG_H
     32 #include <xorg-config.h>
     33 #endif
     34 
     35 #include <X11/X.h>
     36 #include "xf86.h"
     37 #include "xf86Priv.h"
     38 #include "xf86_OSlib.h"
     39 #include "xf86_OSproc.h"
     40 #include <unistd.h>
     41 #include <sys/ioccom.h>
     42 #include <sys/types.h>
     43 #include <fcntl.h>
     44 #include <sys/agpgart.h>
     45 
     46 /* AGP page size is independent of the host page size. */
     47 #ifndef	AGP_PAGE_SIZE
     48 #define	AGP_PAGE_SIZE		4096
     49 #endif
     50 
     51 static int gartFd = -1;
     52 static int acquiredScreen = -1;
     53 static Bool initDone = FALSE;
     54 
     55 /*
     56  * Close /dev/agpgart.  This frees all associated memory allocated during
     57  * this server generation.
     58  */
     59 Bool
     60 xf86GARTCloseScreen(int screenNum)
     61 {
     62     if (gartFd != -1) {
     63         close(gartFd);
     64         acquiredScreen = -1;
     65         gartFd = -1;
     66         initDone = FALSE;
     67 
     68         xf86DrvMsg(screenNum, X_INFO,
     69                    "xf86GARTCloseScreen: device closed successfully\n");
     70 
     71     }
     72     return TRUE;
     73 }
     74 
     75 /*
     76  * Open /dev/agpgart.  Keep it open until xf86GARTCloseScreen is called.
     77  */
     78 static Bool
     79 GARTInit(int screenNum)
     80 {
     81     if (initDone)
     82         return gartFd != -1;
     83 
     84     if (gartFd == -1)
     85         gartFd = open(AGP_DEVICE, O_RDWR);
     86     else
     87         return FALSE;
     88 
     89     if (gartFd == -1) {
     90         xf86DrvMsg(screenNum, X_ERROR,
     91                    "GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
     92                    strerror(errno));
     93         return FALSE;
     94     }
     95 
     96     initDone = TRUE;
     97     xf86DrvMsg(screenNum, X_INFO,
     98                "GARTInit: " AGP_DEVICE " opened successfully\n");
     99 
    100     return TRUE;
    101 }
    102 
    103 Bool
    104 xf86AgpGARTSupported(void)
    105 {
    106     return (GARTInit(-1));
    107 
    108 }
    109 
    110 AgpInfoPtr
    111 xf86GetAGPInfo(int screenNum)
    112 {
    113     agp_info_t agpinf;
    114     AgpInfoPtr info;
    115 
    116     if (!GARTInit(screenNum))
    117         return NULL;
    118 
    119     if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
    120         xf86DrvMsg(screenNum, X_ERROR,
    121                    "xf86GetAGPInfo: AGPIOC_INFO failed (%s)\n",
    122                    strerror(errno));
    123         return NULL;
    124     }
    125 
    126     if ((info = calloc(sizeof(AgpInfo), 1)) == NULL) {
    127         xf86DrvMsg(screenNum, X_ERROR,
    128                    "xf86GetAGPInfo: Failed to allocate AgpInfo\n");
    129         return NULL;
    130     }
    131 
    132     info->bridgeId = agpinf.agpi_devid;
    133     info->agpMode = agpinf.agpi_mode;
    134     info->base = agpinf.agpi_aperbase;
    135     info->size = agpinf.agpi_apersize;
    136     info->totalPages = (unsigned long) agpinf.agpi_pgtotal;
    137     info->systemPages = (unsigned long) agpinf.agpi_pgsystem;
    138     info->usedPages = (unsigned long) agpinf.agpi_pgused;
    139 
    140     return info;
    141 }
    142 
    143 Bool
    144 xf86AcquireGART(int screenNum)
    145 {
    146 
    147     if (!GARTInit(screenNum))
    148         return FALSE;
    149 
    150     if (acquiredScreen != screenNum) {
    151         if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
    152             xf86DrvMsg(screenNum, X_WARNING,
    153                        "xf86AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
    154                        strerror(errno));
    155             return FALSE;
    156         }
    157         acquiredScreen = screenNum;
    158         xf86DrvMsg(screenNum, X_INFO,
    159                    "xf86AcquireGART: AGPIOC_ACQUIRE succeeded\n");
    160     }
    161     return TRUE;
    162 }
    163 
    164 Bool
    165 xf86ReleaseGART(int screenNum)
    166 {
    167 
    168     if (!GARTInit(screenNum))
    169         return FALSE;
    170 
    171     if (acquiredScreen == screenNum) {
    172         /*
    173          * The FreeBSD agp driver removes allocations on release.
    174          * The Solaris driver doesn't.  xf86ReleaseGART() is expected
    175          * to give up access to the GART, but not to remove any
    176          * allocations.
    177          */
    178 
    179         if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
    180             xf86DrvMsg(screenNum, X_WARNING,
    181                        "xf86ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
    182                        strerror(errno));
    183             return FALSE;
    184         }
    185         acquiredScreen = -1;
    186         xf86DrvMsg(screenNum, X_INFO,
    187                    "xf86ReleaseGART: AGPIOC_RELEASE succeeded\n");
    188         return TRUE;
    189     }
    190     return FALSE;
    191 }
    192 
    193 int
    194 xf86AllocateGARTMemory(int screenNum, unsigned long size, int type,
    195                        unsigned long *physical)
    196 {
    197     agp_allocate_t alloc;
    198     int pages;
    199 
    200     /*
    201      * Allocates "size" bytes of GART memory (rounds up to the next
    202      * page multiple) or type "type".  A handle (key) for the allocated
    203      * memory is returned.  On error, the return value is -1.
    204      * "size" should be larger than 0, or AGPIOC_ALLOCATE ioctl will
    205      * return error.
    206      */
    207 
    208     if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
    209         return -1;
    210 
    211     pages = (size / AGP_PAGE_SIZE);
    212     if (size % AGP_PAGE_SIZE != 0)
    213         pages++;
    214 
    215     alloc.agpa_pgcount = pages;
    216     alloc.agpa_type = type;
    217 
    218     if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
    219         xf86DrvMsg(screenNum, X_WARNING, "xf86AllocateGARTMemory: "
    220                    "allocation of %d pages failed\n\t(%s)\n", pages,
    221                    strerror(errno));
    222         return -1;
    223     }
    224 
    225     if (physical)
    226         *physical = (unsigned long) alloc.agpa_physical;
    227 
    228     return alloc.agpa_key;
    229 }
    230 
    231 Bool
    232 xf86DeallocateGARTMemory(int screenNum, int key)
    233 {
    234     if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
    235         return FALSE;
    236 
    237     if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *) (uintptr_t) key) != 0) {
    238         xf86DrvMsg(screenNum, X_WARNING, "xf86DeAllocateGARTMemory: "
    239                    "deallocation of gart memory with key %d failed\n"
    240                    "\t(%s)\n", key, strerror(errno));
    241         return FALSE;
    242     }
    243 
    244     return TRUE;
    245 }
    246 
    247 /* Bind GART memory with "key" at "offset" */
    248 Bool
    249 xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
    250 {
    251     agp_bind_t bind;
    252     int pageOffset;
    253 
    254     if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
    255         return FALSE;
    256 
    257     if (offset % AGP_PAGE_SIZE != 0) {
    258         xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
    259                    "offset (0x%lx) is not page-aligned (%d)\n",
    260                    offset, AGP_PAGE_SIZE);
    261         return FALSE;
    262     }
    263     pageOffset = offset / AGP_PAGE_SIZE;
    264 
    265     xf86DrvMsgVerb(screenNum, X_INFO, 3,
    266                    "xf86BindGARTMemory: bind key %d at 0x%08lx "
    267                    "(pgoffset %d)\n", key, offset, pageOffset);
    268 
    269     bind.agpb_pgstart = pageOffset;
    270     bind.agpb_key = key;
    271 
    272     if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
    273         xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
    274                    "binding of gart memory with key %d\n"
    275                    "\tat offset 0x%lx failed (%s)\n",
    276                    key, offset, strerror(errno));
    277         return FALSE;
    278     }
    279 
    280     return TRUE;
    281 }
    282 
    283 /* Unbind GART memory with "key" */
    284 Bool
    285 xf86UnbindGARTMemory(int screenNum, int key)
    286 {
    287     agp_unbind_t unbind;
    288 
    289     if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
    290         return FALSE;
    291 
    292     unbind.agpu_pri = 0;
    293     unbind.agpu_key = key;
    294 
    295     if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
    296         xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
    297                    "unbinding of gart memory with key %d "
    298                    "failed (%s)\n", key, strerror(errno));
    299         return FALSE;
    300     }
    301 
    302     xf86DrvMsgVerb(screenNum, X_INFO, 3,
    303                    "xf86UnbindGARTMemory: unbind key %d\n", key);
    304 
    305     return TRUE;
    306 }
    307 
    308 /* XXX Interface may change. */
    309 Bool
    310 xf86EnableAGP(int screenNum, CARD32 mode)
    311 {
    312     agp_setup_t setup;
    313 
    314     if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
    315         return FALSE;
    316 
    317     setup.agps_mode = mode;
    318     if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
    319         xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: "
    320                    "AGPIOC_SETUP with mode %x failed (%s)\n",
    321                    (unsigned int) mode, strerror(errno));
    322         return FALSE;
    323     }
    324 
    325     return TRUE;
    326 }