drm_agpsupport.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:11k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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. #include "drmP.h"
  32. #include <linux/module.h>
  33. #if __REALLY_HAVE_AGP
  34. #define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
  35. #define DRM_AGP_PUT inter_module_put("drm_agp")
  36. static const drm_agp_t *drm_agp = NULL;
  37. int DRM(agp_info)(struct inode *inode, struct file *filp,
  38.   unsigned int cmd, unsigned long arg)
  39. {
  40. drm_file_t  *priv  = filp->private_data;
  41. drm_device_t  *dev  = priv->dev;
  42. agp_kern_info    *kern;
  43. drm_agp_info_t   info;
  44. if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
  45. return -EINVAL;
  46. kern                   = &dev->agp->agp_info;
  47. info.agp_version_major = kern->version.major;
  48. info.agp_version_minor = kern->version.minor;
  49. info.mode              = kern->mode;
  50. info.aperture_base     = kern->aper_base;
  51. info.aperture_size     = kern->aper_size * 1024 * 1024;
  52. info.memory_allowed    = kern->max_memory << PAGE_SHIFT;
  53. info.memory_used       = kern->current_memory << PAGE_SHIFT;
  54. info.id_vendor         = kern->device->vendor;
  55. info.id_device         = kern->device->device;
  56. if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info)))
  57. return -EFAULT;
  58. return 0;
  59. }
  60. int DRM(agp_acquire)(struct inode *inode, struct file *filp,
  61.      unsigned int cmd, unsigned long arg)
  62. {
  63. drm_file_t  *priv  = filp->private_data;
  64. drm_device_t  *dev  = priv->dev;
  65. int              retcode;
  66. if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
  67. return -EINVAL;
  68. if ((retcode = drm_agp->acquire())) return retcode;
  69. dev->agp->acquired = 1;
  70. return 0;
  71. }
  72. int DRM(agp_release)(struct inode *inode, struct file *filp,
  73.      unsigned int cmd, unsigned long arg)
  74. {
  75. drm_file_t  *priv  = filp->private_data;
  76. drm_device_t  *dev  = priv->dev;
  77. if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
  78. return -EINVAL;
  79. drm_agp->release();
  80. dev->agp->acquired = 0;
  81. return 0;
  82. }
  83. void DRM(agp_do_release)(void)
  84. {
  85. if (drm_agp->release) drm_agp->release();
  86. }
  87. int DRM(agp_enable)(struct inode *inode, struct file *filp,
  88.     unsigned int cmd, unsigned long arg)
  89. {
  90. drm_file_t  *priv  = filp->private_data;
  91. drm_device_t  *dev  = priv->dev;
  92. drm_agp_mode_t   mode;
  93. if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
  94. return -EINVAL;
  95. if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
  96. return -EFAULT;
  97. dev->agp->mode    = mode.mode;
  98. drm_agp->enable(mode.mode);
  99. dev->agp->base    = dev->agp->agp_info.aper_base;
  100. dev->agp->enabled = 1;
  101. return 0;
  102. }
  103. int DRM(agp_alloc)(struct inode *inode, struct file *filp,
  104.    unsigned int cmd, unsigned long arg)
  105. {
  106. drm_file_t  *priv  = filp->private_data;
  107. drm_device_t  *dev  = priv->dev;
  108. drm_agp_buffer_t request;
  109. drm_agp_mem_t    *entry;
  110. agp_memory       *memory;
  111. unsigned long    pages;
  112. u32   type;
  113. if (!dev->agp || !dev->agp->acquired) return -EINVAL;
  114. if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
  115. return -EFAULT;
  116. if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
  117. return -ENOMEM;
  118.     memset(entry, 0, sizeof(*entry));
  119. pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
  120. type = (u32) request.type;
  121. if (!(memory = DRM(alloc_agp)(pages, type))) {
  122. DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
  123. return -ENOMEM;
  124. }
  125. entry->handle    = (unsigned long)memory->memory;
  126. entry->memory    = memory;
  127. entry->bound     = 0;
  128. entry->pages     = pages;
  129. entry->prev      = NULL;
  130. entry->next      = dev->agp->memory;
  131. if (dev->agp->memory) dev->agp->memory->prev = entry;
  132. dev->agp->memory = entry;
  133. request.handle   = entry->handle;
  134.         request.physical = memory->physical;
  135. if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) {
  136. dev->agp->memory       = entry->next;
  137. dev->agp->memory->prev = NULL;
  138. DRM(free_agp)(memory, pages);
  139. DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
  140. return -EFAULT;
  141. }
  142. return 0;
  143. }
  144. static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
  145.     unsigned long handle)
  146. {
  147. drm_agp_mem_t *entry;
  148. for (entry = dev->agp->memory; entry; entry = entry->next) {
  149. if (entry->handle == handle) return entry;
  150. }
  151. return NULL;
  152. }
  153. int DRM(agp_unbind)(struct inode *inode, struct file *filp,
  154.     unsigned int cmd, unsigned long arg)
  155. {
  156. drm_file_t   *priv  = filp->private_data;
  157. drm_device_t   *dev  = priv->dev;
  158. drm_agp_binding_t request;
  159. drm_agp_mem_t     *entry;
  160. if (!dev->agp || !dev->agp->acquired) return -EINVAL;
  161. if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
  162. return -EFAULT;
  163. if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
  164. return -EINVAL;
  165. if (!entry->bound) return -EINVAL;
  166. return DRM(unbind_agp)(entry->memory);
  167. }
  168. int DRM(agp_bind)(struct inode *inode, struct file *filp,
  169.   unsigned int cmd, unsigned long arg)
  170. {
  171. drm_file_t   *priv  = filp->private_data;
  172. drm_device_t   *dev  = priv->dev;
  173. drm_agp_binding_t request;
  174. drm_agp_mem_t     *entry;
  175. int               retcode;
  176. int               page;
  177. if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
  178. return -EINVAL;
  179. if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
  180. return -EFAULT;
  181. if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
  182. return -EINVAL;
  183. if (entry->bound) return -EINVAL;
  184. page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
  185. if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode;
  186. entry->bound = dev->agp->base + (page << PAGE_SHIFT);
  187. DRM_DEBUG("base = 0x%lx entry->bound = 0x%lxn",
  188.   dev->agp->base, entry->bound);
  189. return 0;
  190. }
  191. int DRM(agp_free)(struct inode *inode, struct file *filp,
  192.   unsigned int cmd, unsigned long arg)
  193. {
  194. drm_file_t  *priv  = filp->private_data;
  195. drm_device_t  *dev  = priv->dev;
  196. drm_agp_buffer_t request;
  197. drm_agp_mem_t    *entry;
  198. if (!dev->agp || !dev->agp->acquired) return -EINVAL;
  199. if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
  200. return -EFAULT;
  201. if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
  202. return -EINVAL;
  203. if (entry->bound) DRM(unbind_agp)(entry->memory);
  204. if (entry->prev) entry->prev->next = entry->next;
  205. else             dev->agp->memory  = entry->next;
  206. if (entry->next) entry->next->prev = entry->prev;
  207. DRM(free_agp)(entry->memory, entry->pages);
  208. DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
  209. return 0;
  210. }
  211. drm_agp_head_t *DRM(agp_init)(void)
  212. {
  213. drm_agp_head_t *head         = NULL;
  214. drm_agp = DRM_AGP_GET;
  215. if (drm_agp) {
  216. if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
  217. return NULL;
  218. memset((void *)head, 0, sizeof(*head));
  219. drm_agp->copy_info(&head->agp_info);
  220. if (head->agp_info.chipset == NOT_SUPPORTED) {
  221. DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
  222. return NULL;
  223. }
  224. head->memory = NULL;
  225. switch (head->agp_info.chipset) {
  226. case INTEL_GENERIC: head->chipset = "Intel";         break;
  227. case INTEL_LX: head->chipset = "Intel 440LX";   break;
  228. case INTEL_BX: head->chipset = "Intel 440BX";   break;
  229. case INTEL_GX: head->chipset = "Intel 440GX";   break;
  230. case INTEL_I810: head->chipset = "Intel i810";    break;
  231. case INTEL_I815: head->chipset = "Intel i815";  break;
  232.   case INTEL_I820: head->chipset = "Intel i820";  break;
  233. case INTEL_I840: head->chipset = "Intel i840";    break;
  234. case INTEL_I845: head->chipset = "Intel i845";    break;
  235. case INTEL_I850: head->chipset = "Intel i850";  break;
  236. case VIA_GENERIC: head->chipset = "VIA";           break;
  237. case VIA_VP3: head->chipset = "VIA VP3";       break;
  238. case VIA_MVP3: head->chipset = "VIA MVP3";      break;
  239. case VIA_MVP4: head->chipset = "VIA MVP4";      break;
  240. case VIA_APOLLO_KX133: head->chipset = "VIA Apollo KX133";
  241. break;
  242. case VIA_APOLLO_KT133: head->chipset = "VIA Apollo KT133";
  243. break;
  244. case VIA_APOLLO_PRO:  head->chipset = "VIA Apollo Pro";
  245. break;
  246. case SIS_GENERIC: head->chipset = "SiS";           break;
  247. case AMD_GENERIC: head->chipset = "AMD";           break;
  248. case AMD_IRONGATE: head->chipset = "AMD Irongate";  break;
  249. case AMD_8151: head->chipset = "AMD 8151";      break;
  250. case ALI_GENERIC: head->chipset = "ALi";           break;
  251. case ALI_M1541:  head->chipset = "ALi M1541";     break;
  252. case ALI_M1621:  head->chipset = "ALi M1621";  break;
  253. case ALI_M1631:  head->chipset = "ALi M1631";  break;
  254. case ALI_M1632:  head->chipset = "ALi M1632";  break;
  255. case ALI_M1641:  head->chipset = "ALi M1641";  break;
  256. case ALI_M1644:  head->chipset = "ALi M1644";  break;
  257. case ALI_M1647:  head->chipset = "ALi M1647";  break;
  258. case ALI_M1651:  head->chipset = "ALi M1651";  break;
  259. case SVWRKS_HE:  head->chipset = "Serverworks HE";
  260. break;
  261. case SVWRKS_LE:  head->chipset = "Serverworks LE";
  262. break;
  263. case SVWRKS_GENERIC:  head->chipset = "Serverworks Generic";
  264. break;
  265. case HP_ZX1: head->chipset = "HP ZX1";  break;
  266. default: head->chipset = "Unknown";       break;
  267. }
  268. head->cant_use_aperture = head->agp_info.cant_use_aperture;
  269. head->page_mask = head->agp_info.page_mask;
  270. DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMBn",
  271.  head->agp_info.version.major,
  272.  head->agp_info.version.minor,
  273.  head->chipset,
  274.  head->agp_info.aper_base,
  275.  head->agp_info.aper_size);
  276. }
  277. return head;
  278. }
  279. void DRM(agp_uninit)(void)
  280. {
  281. DRM_AGP_PUT;
  282. drm_agp = NULL;
  283. }
  284. agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
  285. {
  286. if (!drm_agp->allocate_memory) return NULL;
  287. return drm_agp->allocate_memory(pages, type);
  288. }
  289. int DRM(agp_free_memory)(agp_memory *handle)
  290. {
  291. if (!handle || !drm_agp->free_memory) return 0;
  292. drm_agp->free_memory(handle);
  293. return 1;
  294. }
  295. int DRM(agp_bind_memory)(agp_memory *handle, off_t start)
  296. {
  297. if (!handle || !drm_agp->bind_memory) return -EINVAL;
  298. return drm_agp->bind_memory(handle, start);
  299. }
  300. int DRM(agp_unbind_memory)(agp_memory *handle)
  301. {
  302. if (!handle || !drm_agp->unbind_memory) return -EINVAL;
  303. return drm_agp->unbind_memory(handle);
  304. }
  305. #endif /* __REALLY_HAVE_AGP */