drm_agpsupport.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:11k
源码类别:

嵌入式Linux

开发平台:

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