1*592ffb21SWarner Losh /** 2*592ffb21SWarner Losh * \file drm_agpsupport.c 3*592ffb21SWarner Losh * DRM support for AGP/GART backend 4*592ffb21SWarner Losh * 5*592ffb21SWarner Losh * \author Rickard E. (Rik) Faith <faith@valinux.com> 6*592ffb21SWarner Losh * \author Gareth Hughes <gareth@valinux.com> 7*592ffb21SWarner Losh */ 8*592ffb21SWarner Losh 9*592ffb21SWarner Losh /* 10*592ffb21SWarner Losh * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 11*592ffb21SWarner Losh * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 12*592ffb21SWarner Losh * All Rights Reserved. 13*592ffb21SWarner Losh * 14*592ffb21SWarner Losh * Permission is hereby granted, free of charge, to any person obtaining a 15*592ffb21SWarner Losh * copy of this software and associated documentation files (the "Software"), 16*592ffb21SWarner Losh * to deal in the Software without restriction, including without limitation 17*592ffb21SWarner Losh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 18*592ffb21SWarner Losh * and/or sell copies of the Software, and to permit persons to whom the 19*592ffb21SWarner Losh * Software is furnished to do so, subject to the following conditions: 20*592ffb21SWarner Losh * 21*592ffb21SWarner Losh * The above copyright notice and this permission notice (including the next 22*592ffb21SWarner Losh * paragraph) shall be included in all copies or substantial portions of the 23*592ffb21SWarner Losh * Software. 24*592ffb21SWarner Losh * 25*592ffb21SWarner Losh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26*592ffb21SWarner Losh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27*592ffb21SWarner Losh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 28*592ffb21SWarner Losh * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 29*592ffb21SWarner Losh * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 30*592ffb21SWarner Losh * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 31*592ffb21SWarner Losh * OTHER DEALINGS IN THE SOFTWARE. 32*592ffb21SWarner Losh */ 33*592ffb21SWarner Losh 34*592ffb21SWarner Losh #include <sys/cdefs.h> 35*592ffb21SWarner Losh __FBSDID("$FreeBSD$"); 36*592ffb21SWarner Losh 37*592ffb21SWarner Losh #include <dev/drm2/drmP.h> 38*592ffb21SWarner Losh 39*592ffb21SWarner Losh #if __OS_HAS_AGP 40*592ffb21SWarner Losh 41*592ffb21SWarner Losh /** 42*592ffb21SWarner Losh * Get AGP information. 43*592ffb21SWarner Losh * 44*592ffb21SWarner Losh * \param inode device inode. 45*592ffb21SWarner Losh * \param file_priv DRM file private. 46*592ffb21SWarner Losh * \param cmd command. 47*592ffb21SWarner Losh * \param arg pointer to a (output) drm_agp_info structure. 48*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 49*592ffb21SWarner Losh * 50*592ffb21SWarner Losh * Verifies the AGP device has been initialized and acquired and fills in the 51*592ffb21SWarner Losh * drm_agp_info structure with the information in drm_agp_head::agp_info. 52*592ffb21SWarner Losh */ 53*592ffb21SWarner Losh int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info) 54*592ffb21SWarner Losh { 55*592ffb21SWarner Losh DRM_AGP_KERN *kern; 56*592ffb21SWarner Losh 57*592ffb21SWarner Losh if (!dev->agp || !dev->agp->acquired) 58*592ffb21SWarner Losh return -EINVAL; 59*592ffb21SWarner Losh 60*592ffb21SWarner Losh kern = &dev->agp->agp_info; 61*592ffb21SWarner Losh agp_get_info(dev->agp->bridge, kern); 62*592ffb21SWarner Losh info->agp_version_major = 1; 63*592ffb21SWarner Losh info->agp_version_minor = 0; 64*592ffb21SWarner Losh info->mode = kern->ai_mode; 65*592ffb21SWarner Losh info->aperture_base = kern->ai_aperture_base; 66*592ffb21SWarner Losh info->aperture_size = kern->ai_aperture_size; 67*592ffb21SWarner Losh info->memory_allowed = kern->ai_memory_allowed; 68*592ffb21SWarner Losh info->memory_used = kern->ai_memory_used; 69*592ffb21SWarner Losh info->id_vendor = kern->ai_devid & 0xffff; 70*592ffb21SWarner Losh info->id_device = kern->ai_devid >> 16; 71*592ffb21SWarner Losh 72*592ffb21SWarner Losh return 0; 73*592ffb21SWarner Losh } 74*592ffb21SWarner Losh 75*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_info); 76*592ffb21SWarner Losh 77*592ffb21SWarner Losh int drm_agp_info_ioctl(struct drm_device *dev, void *data, 78*592ffb21SWarner Losh struct drm_file *file_priv) 79*592ffb21SWarner Losh { 80*592ffb21SWarner Losh struct drm_agp_info *info = data; 81*592ffb21SWarner Losh int err; 82*592ffb21SWarner Losh 83*592ffb21SWarner Losh err = drm_agp_info(dev, info); 84*592ffb21SWarner Losh if (err) 85*592ffb21SWarner Losh return err; 86*592ffb21SWarner Losh 87*592ffb21SWarner Losh return 0; 88*592ffb21SWarner Losh } 89*592ffb21SWarner Losh 90*592ffb21SWarner Losh /** 91*592ffb21SWarner Losh * Acquire the AGP device. 92*592ffb21SWarner Losh * 93*592ffb21SWarner Losh * \param dev DRM device that is to acquire AGP. 94*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 95*592ffb21SWarner Losh * 96*592ffb21SWarner Losh * Verifies the AGP device hasn't been acquired before and calls 97*592ffb21SWarner Losh * \c agp_backend_acquire. 98*592ffb21SWarner Losh */ 99*592ffb21SWarner Losh int drm_agp_acquire(struct drm_device * dev) 100*592ffb21SWarner Losh { 101*592ffb21SWarner Losh int retcode; 102*592ffb21SWarner Losh 103*592ffb21SWarner Losh if (!dev->agp) 104*592ffb21SWarner Losh return -ENODEV; 105*592ffb21SWarner Losh if (dev->agp->acquired) 106*592ffb21SWarner Losh return -EBUSY; 107*592ffb21SWarner Losh retcode = agp_acquire(dev->agp->bridge); 108*592ffb21SWarner Losh if (retcode) 109*592ffb21SWarner Losh return -retcode; 110*592ffb21SWarner Losh dev->agp->acquired = 1; 111*592ffb21SWarner Losh return 0; 112*592ffb21SWarner Losh } 113*592ffb21SWarner Losh 114*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_acquire); 115*592ffb21SWarner Losh 116*592ffb21SWarner Losh /** 117*592ffb21SWarner Losh * Acquire the AGP device (ioctl). 118*592ffb21SWarner Losh * 119*592ffb21SWarner Losh * \param inode device inode. 120*592ffb21SWarner Losh * \param file_priv DRM file private. 121*592ffb21SWarner Losh * \param cmd command. 122*592ffb21SWarner Losh * \param arg user argument. 123*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 124*592ffb21SWarner Losh * 125*592ffb21SWarner Losh * Verifies the AGP device hasn't been acquired before and calls 126*592ffb21SWarner Losh * \c agp_backend_acquire. 127*592ffb21SWarner Losh */ 128*592ffb21SWarner Losh int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, 129*592ffb21SWarner Losh struct drm_file *file_priv) 130*592ffb21SWarner Losh { 131*592ffb21SWarner Losh return drm_agp_acquire((struct drm_device *) file_priv->minor->dev); 132*592ffb21SWarner Losh } 133*592ffb21SWarner Losh 134*592ffb21SWarner Losh /** 135*592ffb21SWarner Losh * Release the AGP device. 136*592ffb21SWarner Losh * 137*592ffb21SWarner Losh * \param dev DRM device that is to release AGP. 138*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 139*592ffb21SWarner Losh * 140*592ffb21SWarner Losh * Verifies the AGP device has been acquired and calls \c agp_backend_release. 141*592ffb21SWarner Losh */ 142*592ffb21SWarner Losh int drm_agp_release(struct drm_device * dev) 143*592ffb21SWarner Losh { 144*592ffb21SWarner Losh if (!dev->agp || !dev->agp->acquired) 145*592ffb21SWarner Losh return -EINVAL; 146*592ffb21SWarner Losh agp_release(dev->agp->bridge); 147*592ffb21SWarner Losh dev->agp->acquired = 0; 148*592ffb21SWarner Losh return 0; 149*592ffb21SWarner Losh } 150*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_release); 151*592ffb21SWarner Losh 152*592ffb21SWarner Losh int drm_agp_release_ioctl(struct drm_device *dev, void *data, 153*592ffb21SWarner Losh struct drm_file *file_priv) 154*592ffb21SWarner Losh { 155*592ffb21SWarner Losh return drm_agp_release(dev); 156*592ffb21SWarner Losh } 157*592ffb21SWarner Losh 158*592ffb21SWarner Losh /** 159*592ffb21SWarner Losh * Enable the AGP bus. 160*592ffb21SWarner Losh * 161*592ffb21SWarner Losh * \param dev DRM device that has previously acquired AGP. 162*592ffb21SWarner Losh * \param mode Requested AGP mode. 163*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 164*592ffb21SWarner Losh * 165*592ffb21SWarner Losh * Verifies the AGP device has been acquired but not enabled, and calls 166*592ffb21SWarner Losh * \c agp_enable. 167*592ffb21SWarner Losh */ 168*592ffb21SWarner Losh int drm_agp_enable(struct drm_device * dev, struct drm_agp_mode mode) 169*592ffb21SWarner Losh { 170*592ffb21SWarner Losh if (!dev->agp || !dev->agp->acquired) 171*592ffb21SWarner Losh return -EINVAL; 172*592ffb21SWarner Losh 173*592ffb21SWarner Losh dev->agp->mode = mode.mode; 174*592ffb21SWarner Losh agp_enable(dev->agp->bridge, mode.mode); 175*592ffb21SWarner Losh dev->agp->enabled = 1; 176*592ffb21SWarner Losh return 0; 177*592ffb21SWarner Losh } 178*592ffb21SWarner Losh 179*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_enable); 180*592ffb21SWarner Losh 181*592ffb21SWarner Losh int drm_agp_enable_ioctl(struct drm_device *dev, void *data, 182*592ffb21SWarner Losh struct drm_file *file_priv) 183*592ffb21SWarner Losh { 184*592ffb21SWarner Losh struct drm_agp_mode *mode = data; 185*592ffb21SWarner Losh 186*592ffb21SWarner Losh return drm_agp_enable(dev, *mode); 187*592ffb21SWarner Losh } 188*592ffb21SWarner Losh 189*592ffb21SWarner Losh /** 190*592ffb21SWarner Losh * Allocate AGP memory. 191*592ffb21SWarner Losh * 192*592ffb21SWarner Losh * \param inode device inode. 193*592ffb21SWarner Losh * \param file_priv file private pointer. 194*592ffb21SWarner Losh * \param cmd command. 195*592ffb21SWarner Losh * \param arg pointer to a drm_agp_buffer structure. 196*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 197*592ffb21SWarner Losh * 198*592ffb21SWarner Losh * Verifies the AGP device is present and has been acquired, allocates the 199*592ffb21SWarner Losh * memory via agp_allocate_memory() and creates a drm_agp_mem entry for it. 200*592ffb21SWarner Losh */ 201*592ffb21SWarner Losh int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) 202*592ffb21SWarner Losh { 203*592ffb21SWarner Losh struct drm_agp_mem *entry; 204*592ffb21SWarner Losh DRM_AGP_MEM *memory; 205*592ffb21SWarner Losh unsigned long pages; 206*592ffb21SWarner Losh u32 type; 207*592ffb21SWarner Losh struct agp_memory_info info; 208*592ffb21SWarner Losh 209*592ffb21SWarner Losh if (!dev->agp || !dev->agp->acquired) 210*592ffb21SWarner Losh return -EINVAL; 211*592ffb21SWarner Losh if (!(entry = malloc(sizeof(*entry), DRM_MEM_AGPLISTS, M_NOWAIT))) 212*592ffb21SWarner Losh return -ENOMEM; 213*592ffb21SWarner Losh 214*592ffb21SWarner Losh memset(entry, 0, sizeof(*entry)); 215*592ffb21SWarner Losh 216*592ffb21SWarner Losh pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; 217*592ffb21SWarner Losh type = (u32) request->type; 218*592ffb21SWarner Losh if (!(memory = agp_alloc_memory(dev->agp->bridge, type, pages << PAGE_SHIFT))) { 219*592ffb21SWarner Losh free(entry, DRM_MEM_AGPLISTS); 220*592ffb21SWarner Losh return -ENOMEM; 221*592ffb21SWarner Losh } 222*592ffb21SWarner Losh 223*592ffb21SWarner Losh entry->handle = (unsigned long)memory; 224*592ffb21SWarner Losh entry->memory = memory; 225*592ffb21SWarner Losh entry->bound = 0; 226*592ffb21SWarner Losh entry->pages = pages; 227*592ffb21SWarner Losh list_add(&entry->head, &dev->agp->memory); 228*592ffb21SWarner Losh 229*592ffb21SWarner Losh agp_memory_info(dev->agp->bridge, entry->memory, &info); 230*592ffb21SWarner Losh 231*592ffb21SWarner Losh request->handle = entry->handle; 232*592ffb21SWarner Losh request->physical = info.ami_physical; 233*592ffb21SWarner Losh 234*592ffb21SWarner Losh return 0; 235*592ffb21SWarner Losh } 236*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_alloc); 237*592ffb21SWarner Losh 238*592ffb21SWarner Losh 239*592ffb21SWarner Losh int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, 240*592ffb21SWarner Losh struct drm_file *file_priv) 241*592ffb21SWarner Losh { 242*592ffb21SWarner Losh struct drm_agp_buffer *request = data; 243*592ffb21SWarner Losh 244*592ffb21SWarner Losh return drm_agp_alloc(dev, request); 245*592ffb21SWarner Losh } 246*592ffb21SWarner Losh 247*592ffb21SWarner Losh /** 248*592ffb21SWarner Losh * Search for the AGP memory entry associated with a handle. 249*592ffb21SWarner Losh * 250*592ffb21SWarner Losh * \param dev DRM device structure. 251*592ffb21SWarner Losh * \param handle AGP memory handle. 252*592ffb21SWarner Losh * \return pointer to the drm_agp_mem structure associated with \p handle. 253*592ffb21SWarner Losh * 254*592ffb21SWarner Losh * Walks through drm_agp_head::memory until finding a matching handle. 255*592ffb21SWarner Losh */ 256*592ffb21SWarner Losh static struct drm_agp_mem *drm_agp_lookup_entry(struct drm_device * dev, 257*592ffb21SWarner Losh unsigned long handle) 258*592ffb21SWarner Losh { 259*592ffb21SWarner Losh struct drm_agp_mem *entry; 260*592ffb21SWarner Losh 261*592ffb21SWarner Losh list_for_each_entry(entry, &dev->agp->memory, head) { 262*592ffb21SWarner Losh if (entry->handle == handle) 263*592ffb21SWarner Losh return entry; 264*592ffb21SWarner Losh } 265*592ffb21SWarner Losh return NULL; 266*592ffb21SWarner Losh } 267*592ffb21SWarner Losh 268*592ffb21SWarner Losh /** 269*592ffb21SWarner Losh * Unbind AGP memory from the GATT (ioctl). 270*592ffb21SWarner Losh * 271*592ffb21SWarner Losh * \param inode device inode. 272*592ffb21SWarner Losh * \param file_priv DRM file private. 273*592ffb21SWarner Losh * \param cmd command. 274*592ffb21SWarner Losh * \param arg pointer to a drm_agp_binding structure. 275*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 276*592ffb21SWarner Losh * 277*592ffb21SWarner Losh * Verifies the AGP device is present and acquired, looks-up the AGP memory 278*592ffb21SWarner Losh * entry and passes it to the unbind_agp() function. 279*592ffb21SWarner Losh */ 280*592ffb21SWarner Losh int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request) 281*592ffb21SWarner Losh { 282*592ffb21SWarner Losh struct drm_agp_mem *entry; 283*592ffb21SWarner Losh int ret; 284*592ffb21SWarner Losh 285*592ffb21SWarner Losh if (!dev->agp || !dev->agp->acquired) 286*592ffb21SWarner Losh return -EINVAL; 287*592ffb21SWarner Losh if (!(entry = drm_agp_lookup_entry(dev, request->handle))) 288*592ffb21SWarner Losh return -EINVAL; 289*592ffb21SWarner Losh if (!entry->bound) 290*592ffb21SWarner Losh return -EINVAL; 291*592ffb21SWarner Losh ret = drm_unbind_agp(entry->memory); 292*592ffb21SWarner Losh if (ret == 0) 293*592ffb21SWarner Losh entry->bound = 0; 294*592ffb21SWarner Losh return ret; 295*592ffb21SWarner Losh } 296*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_unbind); 297*592ffb21SWarner Losh 298*592ffb21SWarner Losh 299*592ffb21SWarner Losh int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, 300*592ffb21SWarner Losh struct drm_file *file_priv) 301*592ffb21SWarner Losh { 302*592ffb21SWarner Losh struct drm_agp_binding *request = data; 303*592ffb21SWarner Losh 304*592ffb21SWarner Losh return drm_agp_unbind(dev, request); 305*592ffb21SWarner Losh } 306*592ffb21SWarner Losh 307*592ffb21SWarner Losh /** 308*592ffb21SWarner Losh * Bind AGP memory into the GATT (ioctl) 309*592ffb21SWarner Losh * 310*592ffb21SWarner Losh * \param inode device inode. 311*592ffb21SWarner Losh * \param file_priv DRM file private. 312*592ffb21SWarner Losh * \param cmd command. 313*592ffb21SWarner Losh * \param arg pointer to a drm_agp_binding structure. 314*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 315*592ffb21SWarner Losh * 316*592ffb21SWarner Losh * Verifies the AGP device is present and has been acquired and that no memory 317*592ffb21SWarner Losh * is currently bound into the GATT. Looks-up the AGP memory entry and passes 318*592ffb21SWarner Losh * it to bind_agp() function. 319*592ffb21SWarner Losh */ 320*592ffb21SWarner Losh int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) 321*592ffb21SWarner Losh { 322*592ffb21SWarner Losh struct drm_agp_mem *entry; 323*592ffb21SWarner Losh int retcode; 324*592ffb21SWarner Losh int page; 325*592ffb21SWarner Losh 326*592ffb21SWarner Losh if (!dev->agp || !dev->agp->acquired) 327*592ffb21SWarner Losh return -EINVAL; 328*592ffb21SWarner Losh if (!(entry = drm_agp_lookup_entry(dev, request->handle))) 329*592ffb21SWarner Losh return -EINVAL; 330*592ffb21SWarner Losh if (entry->bound) 331*592ffb21SWarner Losh return -EINVAL; 332*592ffb21SWarner Losh page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; 333*592ffb21SWarner Losh if ((retcode = drm_bind_agp(entry->memory, page))) 334*592ffb21SWarner Losh return retcode; 335*592ffb21SWarner Losh entry->bound = dev->agp->base + (page << PAGE_SHIFT); 336*592ffb21SWarner Losh DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", 337*592ffb21SWarner Losh dev->agp->base, entry->bound); 338*592ffb21SWarner Losh return 0; 339*592ffb21SWarner Losh } 340*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_bind); 341*592ffb21SWarner Losh 342*592ffb21SWarner Losh 343*592ffb21SWarner Losh int drm_agp_bind_ioctl(struct drm_device *dev, void *data, 344*592ffb21SWarner Losh struct drm_file *file_priv) 345*592ffb21SWarner Losh { 346*592ffb21SWarner Losh struct drm_agp_binding *request = data; 347*592ffb21SWarner Losh 348*592ffb21SWarner Losh return drm_agp_bind(dev, request); 349*592ffb21SWarner Losh } 350*592ffb21SWarner Losh 351*592ffb21SWarner Losh /** 352*592ffb21SWarner Losh * Free AGP memory (ioctl). 353*592ffb21SWarner Losh * 354*592ffb21SWarner Losh * \param inode device inode. 355*592ffb21SWarner Losh * \param file_priv DRM file private. 356*592ffb21SWarner Losh * \param cmd command. 357*592ffb21SWarner Losh * \param arg pointer to a drm_agp_buffer structure. 358*592ffb21SWarner Losh * \return zero on success or a negative number on failure. 359*592ffb21SWarner Losh * 360*592ffb21SWarner Losh * Verifies the AGP device is present and has been acquired and looks up the 361*592ffb21SWarner Losh * AGP memory entry. If the memory it's currently bound, unbind it via 362*592ffb21SWarner Losh * unbind_agp(). Frees it via free_agp() as well as the entry itself 363*592ffb21SWarner Losh * and unlinks from the doubly linked list it's inserted in. 364*592ffb21SWarner Losh */ 365*592ffb21SWarner Losh int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) 366*592ffb21SWarner Losh { 367*592ffb21SWarner Losh struct drm_agp_mem *entry; 368*592ffb21SWarner Losh 369*592ffb21SWarner Losh if (!dev->agp || !dev->agp->acquired) 370*592ffb21SWarner Losh return -EINVAL; 371*592ffb21SWarner Losh if (!(entry = drm_agp_lookup_entry(dev, request->handle))) 372*592ffb21SWarner Losh return -EINVAL; 373*592ffb21SWarner Losh if (entry->bound) 374*592ffb21SWarner Losh drm_unbind_agp(entry->memory); 375*592ffb21SWarner Losh 376*592ffb21SWarner Losh list_del(&entry->head); 377*592ffb21SWarner Losh 378*592ffb21SWarner Losh drm_free_agp(entry->memory, entry->pages); 379*592ffb21SWarner Losh free(entry, DRM_MEM_AGPLISTS); 380*592ffb21SWarner Losh return 0; 381*592ffb21SWarner Losh } 382*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_free); 383*592ffb21SWarner Losh 384*592ffb21SWarner Losh 385*592ffb21SWarner Losh 386*592ffb21SWarner Losh int drm_agp_free_ioctl(struct drm_device *dev, void *data, 387*592ffb21SWarner Losh struct drm_file *file_priv) 388*592ffb21SWarner Losh { 389*592ffb21SWarner Losh struct drm_agp_buffer *request = data; 390*592ffb21SWarner Losh 391*592ffb21SWarner Losh return drm_agp_free(dev, request); 392*592ffb21SWarner Losh } 393*592ffb21SWarner Losh 394*592ffb21SWarner Losh /** 395*592ffb21SWarner Losh * Initialize the AGP resources. 396*592ffb21SWarner Losh * 397*592ffb21SWarner Losh * \return pointer to a drm_agp_head structure. 398*592ffb21SWarner Losh * 399*592ffb21SWarner Losh * Gets the drm_agp_t structure which is made available by the agpgart module 400*592ffb21SWarner Losh * via the inter_module_* functions. Creates and initializes a drm_agp_head 401*592ffb21SWarner Losh * structure. 402*592ffb21SWarner Losh */ 403*592ffb21SWarner Losh struct drm_agp_head *drm_agp_init(struct drm_device *dev) 404*592ffb21SWarner Losh { 405*592ffb21SWarner Losh struct drm_agp_head *head = NULL; 406*592ffb21SWarner Losh 407*592ffb21SWarner Losh if (!(head = malloc(sizeof(*head), DRM_MEM_AGPLISTS, M_NOWAIT))) 408*592ffb21SWarner Losh return NULL; 409*592ffb21SWarner Losh memset((void *)head, 0, sizeof(*head)); 410*592ffb21SWarner Losh head->bridge = agp_find_device(); 411*592ffb21SWarner Losh if (!head->bridge) { 412*592ffb21SWarner Losh free(head, DRM_MEM_AGPLISTS); 413*592ffb21SWarner Losh return NULL; 414*592ffb21SWarner Losh } else { 415*592ffb21SWarner Losh agp_get_info(head->bridge, &head->agp_info); 416*592ffb21SWarner Losh } 417*592ffb21SWarner Losh INIT_LIST_HEAD(&head->memory); 418*592ffb21SWarner Losh head->cant_use_aperture = 0; 419*592ffb21SWarner Losh head->base = head->agp_info.ai_aperture_base; 420*592ffb21SWarner Losh return head; 421*592ffb21SWarner Losh } 422*592ffb21SWarner Losh 423*592ffb21SWarner Losh #ifdef FREEBSD_NOTYET 424*592ffb21SWarner Losh /** 425*592ffb21SWarner Losh * Binds a collection of pages into AGP memory at the given offset, returning 426*592ffb21SWarner Losh * the AGP memory structure containing them. 427*592ffb21SWarner Losh * 428*592ffb21SWarner Losh * No reference is held on the pages during this time -- it is up to the 429*592ffb21SWarner Losh * caller to handle that. 430*592ffb21SWarner Losh */ 431*592ffb21SWarner Losh DRM_AGP_MEM * 432*592ffb21SWarner Losh drm_agp_bind_pages(struct drm_device *dev, 433*592ffb21SWarner Losh struct page **pages, 434*592ffb21SWarner Losh unsigned long num_pages, 435*592ffb21SWarner Losh uint32_t gtt_offset, 436*592ffb21SWarner Losh u32 type) 437*592ffb21SWarner Losh { 438*592ffb21SWarner Losh DRM_AGP_MEM *mem; 439*592ffb21SWarner Losh int ret, i; 440*592ffb21SWarner Losh 441*592ffb21SWarner Losh DRM_DEBUG("\n"); 442*592ffb21SWarner Losh 443*592ffb21SWarner Losh mem = agp_allocate_memory(dev->agp->bridge, num_pages, 444*592ffb21SWarner Losh type); 445*592ffb21SWarner Losh if (mem == NULL) { 446*592ffb21SWarner Losh DRM_ERROR("Failed to allocate memory for %ld pages\n", 447*592ffb21SWarner Losh num_pages); 448*592ffb21SWarner Losh return NULL; 449*592ffb21SWarner Losh } 450*592ffb21SWarner Losh 451*592ffb21SWarner Losh for (i = 0; i < num_pages; i++) 452*592ffb21SWarner Losh mem->pages[i] = pages[i]; 453*592ffb21SWarner Losh mem->page_count = num_pages; 454*592ffb21SWarner Losh 455*592ffb21SWarner Losh mem->is_flushed = true; 456*592ffb21SWarner Losh ret = agp_bind_memory(mem, gtt_offset / PAGE_SIZE); 457*592ffb21SWarner Losh if (ret != 0) { 458*592ffb21SWarner Losh DRM_ERROR("Failed to bind AGP memory: %d\n", ret); 459*592ffb21SWarner Losh agp_free_memory(mem); 460*592ffb21SWarner Losh return NULL; 461*592ffb21SWarner Losh } 462*592ffb21SWarner Losh 463*592ffb21SWarner Losh return mem; 464*592ffb21SWarner Losh } 465*592ffb21SWarner Losh EXPORT_SYMBOL(drm_agp_bind_pages); 466*592ffb21SWarner Losh #endif /* FREEBSD_NOTYET */ 467*592ffb21SWarner Losh 468*592ffb21SWarner Losh #endif /* __OS_HAS_AGP */ 469