linux-old/drivers/char/drm/drm_agpsupport.h
<<
>>
Prefs
   1/* drm_agpsupport.h -- DRM support for AGP/GART backend -*- linux-c -*-
   2 * Created: Mon Dec 13 09:56:45 1999 by faith@precisioninsight.com
   3 *
   4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
   5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
   6 * All Rights Reserved.
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a
   9 * copy of this software and associated documentation files (the "Software"),
  10 * to deal in the Software without restriction, including without limitation
  11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12 * and/or sell copies of the Software, and to permit persons to whom the
  13 * Software is furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice (including the next
  16 * paragraph) shall be included in all copies or substantial portions of the
  17 * Software.
  18 *
  19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25 * OTHER DEALINGS IN THE SOFTWARE.
  26 *
  27 * Author:
  28 *    Rickard E. (Rik) Faith <faith@valinux.com>
  29 *    Gareth Hughes <gareth@valinux.com>
  30 */
  31
  32#include "drmP.h"
  33#include <linux/module.h>
  34
  35#if __REALLY_HAVE_AGP
  36
  37#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
  38#define DRM_AGP_PUT inter_module_put("drm_agp")
  39
  40static const drm_agp_t *drm_agp = NULL;
  41
  42int DRM(agp_info)(struct inode *inode, struct file *filp,
  43                  unsigned int cmd, unsigned long arg)
  44{
  45        drm_file_t       *priv   = filp->private_data;
  46        drm_device_t     *dev    = priv->dev;
  47        agp_kern_info    *kern;
  48        drm_agp_info_t   info;
  49
  50        if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
  51                return -EINVAL;
  52
  53        kern                   = &dev->agp->agp_info;
  54        info.agp_version_major = kern->version.major;
  55        info.agp_version_minor = kern->version.minor;
  56        info.mode              = kern->mode;
  57        info.aperture_base     = kern->aper_base;
  58        info.aperture_size     = kern->aper_size * 1024 * 1024;
  59        info.memory_allowed    = kern->max_memory << PAGE_SHIFT;
  60        info.memory_used       = kern->current_memory << PAGE_SHIFT;
  61        info.id_vendor         = kern->device->vendor;
  62        info.id_device         = kern->device->device;
  63
  64        if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info)))
  65                return -EFAULT;
  66        return 0;
  67}
  68
  69int DRM(agp_acquire)(struct inode *inode, struct file *filp,
  70                     unsigned int cmd, unsigned long arg)
  71{
  72        drm_file_t       *priv   = filp->private_data;
  73        drm_device_t     *dev    = priv->dev;
  74        int              retcode;
  75
  76        if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
  77                return -EINVAL;
  78        if ((retcode = drm_agp->acquire())) return retcode;
  79        dev->agp->acquired = 1;
  80        return 0;
  81}
  82
  83int DRM(agp_release)(struct inode *inode, struct file *filp,
  84                     unsigned int cmd, unsigned long arg)
  85{
  86        drm_file_t       *priv   = filp->private_data;
  87        drm_device_t     *dev    = priv->dev;
  88
  89        if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
  90                return -EINVAL;
  91        drm_agp->release();
  92        dev->agp->acquired = 0;
  93        return 0;
  94
  95}
  96
  97void DRM(agp_do_release)(void)
  98{
  99        if (drm_agp->release) drm_agp->release();
 100}
 101
 102int DRM(agp_enable)(struct inode *inode, struct file *filp,
 103                    unsigned int cmd, unsigned long arg)
 104{
 105        drm_file_t       *priv   = filp->private_data;
 106        drm_device_t     *dev    = priv->dev;
 107        drm_agp_mode_t   mode;
 108
 109        if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
 110                return -EINVAL;
 111
 112        if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
 113                return -EFAULT;
 114
 115        dev->agp->mode    = mode.mode;
 116        drm_agp->enable(mode.mode);
 117        dev->agp->base    = dev->agp->agp_info.aper_base;
 118        dev->agp->enabled = 1;
 119        return 0;
 120}
 121
 122int DRM(agp_alloc)(struct inode *inode, struct file *filp,
 123                   unsigned int cmd, unsigned long arg)
 124{
 125        drm_file_t       *priv   = filp->private_data;
 126        drm_device_t     *dev    = priv->dev;
 127        drm_agp_buffer_t request;
 128        drm_agp_mem_t    *entry;
 129        agp_memory       *memory;
 130        unsigned long    pages;
 131        u32              type;
 132
 133        if (!dev->agp || !dev->agp->acquired) return -EINVAL;
 134        if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
 135                return -EFAULT;
 136        if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
 137                return -ENOMEM;
 138
 139        memset(entry, 0, sizeof(*entry));
 140
 141        pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
 142        type = (u32) request.type;
 143
 144        if (!(memory = DRM(alloc_agp)(pages, type))) {
 145                DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
 146                return -ENOMEM;
 147        }
 148
 149        entry->handle    = (unsigned long)memory->memory;
 150        entry->memory    = memory;
 151        entry->bound     = 0;
 152        entry->pages     = pages;
 153        entry->prev      = NULL;
 154        entry->next      = dev->agp->memory;
 155        if (dev->agp->memory) dev->agp->memory->prev = entry;
 156        dev->agp->memory = entry;
 157
 158        request.handle   = entry->handle;
 159        request.physical = memory->physical;
 160
 161        if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) {
 162                dev->agp->memory       = entry->next;
 163                dev->agp->memory->prev = NULL;
 164                DRM(free_agp)(memory, pages);
 165                DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
 166                return -EFAULT;
 167        }
 168        return 0;
 169}
 170
 171static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
 172                                            unsigned long handle)
 173{
 174        drm_agp_mem_t *entry;
 175
 176        for (entry = dev->agp->memory; entry; entry = entry->next) {
 177                if (entry->handle == handle) return entry;
 178        }
 179        return NULL;
 180}
 181
 182int DRM(agp_unbind)(struct inode *inode, struct file *filp,
 183                    unsigned int cmd, unsigned long arg)
 184{
 185        drm_file_t        *priv  = filp->private_data;
 186        drm_device_t      *dev   = priv->dev;
 187        drm_agp_binding_t request;
 188        drm_agp_mem_t     *entry;
 189
 190        if (!dev->agp || !dev->agp->acquired) return -EINVAL;
 191        if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
 192                return -EFAULT;
 193        if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
 194                return -EINVAL;
 195        if (!entry->bound) return -EINVAL;
 196        return DRM(unbind_agp)(entry->memory);
 197}
 198
 199int DRM(agp_bind)(struct inode *inode, struct file *filp,
 200                  unsigned int cmd, unsigned long arg)
 201{
 202        drm_file_t        *priv  = filp->private_data;
 203        drm_device_t      *dev   = priv->dev;
 204        drm_agp_binding_t request;
 205        drm_agp_mem_t     *entry;
 206        int               retcode;
 207        int               page;
 208
 209        if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
 210                return -EINVAL;
 211        if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
 212                return -EFAULT;
 213        if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
 214                return -EINVAL;
 215        if (entry->bound) return -EINVAL;
 216        page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
 217        if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode;
 218        entry->bound = dev->agp->base + (page << PAGE_SHIFT);
 219        DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
 220                  dev->agp->base, entry->bound);
 221        return 0;
 222}
 223
 224int DRM(agp_free)(struct inode *inode, struct file *filp,
 225                  unsigned int cmd, unsigned long arg)
 226{
 227        drm_file_t       *priv   = filp->private_data;
 228        drm_device_t     *dev    = priv->dev;
 229        drm_agp_buffer_t request;
 230        drm_agp_mem_t    *entry;
 231
 232        if (!dev->agp || !dev->agp->acquired) return -EINVAL;
 233        if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
 234                return -EFAULT;
 235        if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
 236                return -EINVAL;
 237        if (entry->bound) DRM(unbind_agp)(entry->memory);
 238
 239        if (entry->prev) entry->prev->next = entry->next;
 240        else             dev->agp->memory  = entry->next;
 241        if (entry->next) entry->next->prev = entry->prev;
 242        DRM(free_agp)(entry->memory, entry->pages);
 243        DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
 244        return 0;
 245}
 246
 247drm_agp_head_t *DRM(agp_init)(void)
 248{
 249        drm_agp_head_t *head         = NULL;
 250
 251        drm_agp = DRM_AGP_GET;
 252        if (drm_agp) {
 253                if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
 254                        return NULL;
 255                memset((void *)head, 0, sizeof(*head));
 256                drm_agp->copy_info(&head->agp_info);
 257                if (head->agp_info.chipset == NOT_SUPPORTED) {
 258                        DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
 259                        return NULL;
 260                }
 261                head->memory = NULL;
 262                switch (head->agp_info.chipset) {
 263                case INTEL_GENERIC:     head->chipset = "Intel";         break;
 264                case INTEL_LX:          head->chipset = "Intel 440LX";   break;
 265                case INTEL_BX:          head->chipset = "Intel 440BX";   break;
 266                case INTEL_GX:          head->chipset = "Intel 440GX";   break;
 267                case INTEL_I810:        head->chipset = "Intel i810";    break;
 268                case INTEL_I815:        head->chipset = "Intel i815";    break;
 269                case INTEL_I820:        head->chipset = "Intel i820";    break;
 270                case INTEL_I840:        head->chipset = "Intel i840";    break;
 271                case INTEL_I845:        head->chipset = "Intel i845";    break;
 272                case INTEL_I850:        head->chipset = "Intel i850";    break;
 273
 274                case VIA_GENERIC:       head->chipset = "VIA";           break;
 275                case VIA_VP3:           head->chipset = "VIA VP3";       break;
 276                case VIA_MVP3:          head->chipset = "VIA MVP3";      break;
 277                case VIA_MVP4:          head->chipset = "VIA MVP4";      break;
 278                case VIA_APOLLO_KX133:  head->chipset = "VIA Apollo KX133";
 279                        break;
 280                case VIA_APOLLO_KT133:  head->chipset = "VIA Apollo KT133";
 281                        break;
 282                case VIA_APOLLO_KT400:  head->chipset = "VIA Apollo KT400";
 283                        break;
 284                case VIA_APOLLO_PRO:    head->chipset = "VIA Apollo Pro";
 285                        break;
 286                case VIA_APOLLO_P4X400: head->chipset = "VIA Apollo P4X400";
 287                        break;
 288
 289                case SIS_GENERIC:       head->chipset = "SiS";           break;
 290                case AMD_GENERIC:       head->chipset = "AMD";           break;
 291                case AMD_IRONGATE:      head->chipset = "AMD Irongate";  break;
 292                case AMD_8151:          head->chipset = "AMD 8151";      break;
 293                case ALI_GENERIC:       head->chipset = "ALi";           break;
 294                case ALI_M1541:         head->chipset = "ALi M1541";     break;
 295
 296                case ALI_M1621:         head->chipset = "ALi M1621";     break;
 297                case ALI_M1631:         head->chipset = "ALi M1631";     break;
 298                case ALI_M1632:         head->chipset = "ALi M1632";     break;
 299                case ALI_M1641:         head->chipset = "ALi M1641";     break;
 300                case ALI_M1644:         head->chipset = "ALi M1644";     break;
 301                case ALI_M1647:         head->chipset = "ALi M1647";     break;
 302                case ALI_M1651:         head->chipset = "ALi M1651";     break;
 303
 304                case SVWRKS_HE:         head->chipset = "Serverworks HE";
 305                        break;
 306                case SVWRKS_LE:         head->chipset = "Serverworks LE";
 307                        break;
 308                case SVWRKS_GENERIC:    head->chipset = "Serverworks Generic";
 309                        break;
 310
 311                case HP_ZX1:            head->chipset = "HP ZX1";        break;
 312
 313                default:                head->chipset = "Unknown";       break;
 314                }
 315
 316                head->cant_use_aperture = head->agp_info.cant_use_aperture;
 317                head->page_mask = head->agp_info.page_mask;
 318
 319                DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
 320                         head->agp_info.version.major,
 321                         head->agp_info.version.minor,
 322                         head->chipset,
 323                         head->agp_info.aper_base,
 324                         head->agp_info.aper_size);
 325        }
 326        return head;
 327}
 328
 329void DRM(agp_uninit)(void)
 330{
 331        DRM_AGP_PUT;
 332        drm_agp = NULL;
 333}
 334
 335agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
 336{
 337        if (!drm_agp->allocate_memory) return NULL;
 338        return drm_agp->allocate_memory(pages, type);
 339}
 340
 341int DRM(agp_free_memory)(agp_memory *handle)
 342{
 343        if (!handle || !drm_agp->free_memory) return 0;
 344        drm_agp->free_memory(handle);
 345        return 1;
 346}
 347
 348int DRM(agp_bind_memory)(agp_memory *handle, off_t start)
 349{
 350        if (!handle || !drm_agp->bind_memory) return -EINVAL;
 351        return drm_agp->bind_memory(handle, start);
 352}
 353
 354int DRM(agp_unbind_memory)(agp_memory *handle)
 355{
 356        if (!handle || !drm_agp->unbind_memory) return -EINVAL;
 357        return drm_agp->unbind_memory(handle);
 358}
 359
 360#endif /* __REALLY_HAVE_AGP */
 361
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.