diff options
-rw-r--r-- | README | 71 | ||||
-rw-r--r-- | linux-core/drmP.h | 11 | ||||
-rw-r--r-- | linux-core/drm_agpsupport.c | 105 | ||||
-rw-r--r-- | linux-core/drm_fence.c | 10 | ||||
-rw-r--r-- | linux-core/drm_objects.h | 13 | ||||
-rw-r--r-- | linux-core/drm_ttm.c | 10 | ||||
-rw-r--r-- | linux-core/i915_buffer.c | 2 | ||||
-rw-r--r-- | linux-core/via_buffer.c | 2 | ||||
-rw-r--r-- | shared-core/drm_pciids.txt | 2 |
9 files changed, 143 insertions, 83 deletions
@@ -1,4 +1,69 @@ -By default, this will install into /usr/local. If you want to install this -libdrm to replace your system copy, say: -./configure --prefix=/usr --exec-prefix=/ +DRM README file + + +There are two main parts to this package: the DRM client library/interface +(libdrm.so) and kernel/hardware-specific device modules (such as i915.ko). + + + +Compiling +--------- + +By default, libdrm and the DRM header files will install into /usr/local/. +If you want to install this DRM to replace your system copy, say: + + ./configure --prefix=/usr --exec-prefix=/ + +Then, + make install + + +To build the device-specific kernel modules: + + cd linux-core/ + make + cp *.ko /lib/modules/VERSION/kernel/drivers/char/drm/ + (where VERSION is your kernel version: uname -f) + +Or, + cd bsd-core/ + make + copy the kernel modules to the appropriate place + + + +Tips & Trouble-shooting +----------------------- + +1. You'll need kernel sources. If using Fedora Core 5, for example, you may + need to install RPMs such as: + + kernel-smp-devel-2.6.15-1.2054_FC5.i686.rpm + kernel-devel-2.6.15-1.2054_FC5.i686.rpm + etc. + + +2. You may need to make a symlink from /lib/modules/VERSION/build to your + kernel sources in /usr/src/kernels/VERSION (where version is `uname -r`): + + cd /lib/modules/VERSION + ln -s /usr/src/kernels/VERSION build + + +3. If you've build the kernel modules but they won't load because of an + error like this: + + $ /sbin/modprobe drm + FATAL: Error inserting drm (/lib/modules/2.6.15-1.2054_FC5smp/kernel/drivers/char/drm/drm.ko): Invalid module format + + And 'dmesg|tail' says: + + drm: disagrees about version of symbol struct_module + + Try recompiling your drm modules without the Module.symvers file. + That is rm the /usr/src/kernels/2.6.15-1.2054_FC5-smp-i686/Module.symvers + file (or rename it). Then do a 'make clean' before rebuilding your drm + modules. + + diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 326565cb..377f447a 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -841,14 +841,12 @@ typedef struct drm_device { } drm_device_t; #if __OS_HAS_AGP -typedef struct drm_agp_ttm_priv { +typedef struct drm_agp_ttm_backend { + drm_ttm_backend_t backend; DRM_AGP_MEM *mem; struct agp_bridge_data *bridge; - unsigned alloc_type; - unsigned cached_type; - unsigned uncached_type; int populated; -} drm_agp_ttm_priv; +} drm_agp_ttm_backend_t; #endif @@ -1125,8 +1123,7 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size extern int drm_agp_free_memory(DRM_AGP_MEM * handle); extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start); extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); -extern drm_ttm_backend_t *drm_agp_init_ttm(struct drm_device *dev, - drm_ttm_backend_t *backend); +extern drm_ttm_backend_t *drm_agp_init_ttm(struct drm_device *dev); /* Stub support (drm_stub.h) */ extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index 0f7b1d2e..7d8f0737 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -570,7 +570,8 @@ static int drm_agp_needs_unbind_cache_adjust(drm_ttm_backend_t *backend) { static int drm_agp_populate(drm_ttm_backend_t *backend, unsigned long num_pages, struct page **pages) { - drm_agp_ttm_priv *agp_priv = (drm_agp_ttm_priv *) backend->private; + drm_agp_ttm_backend_t *agp_be = + container_of(backend, drm_agp_ttm_backend_t, backend); struct page **cur_page, **last_page = pages + num_pages; DRM_AGP_MEM *mem; @@ -579,9 +580,9 @@ static int drm_agp_populate(drm_ttm_backend_t *backend, unsigned long num_pages, DRM_DEBUG("drm_agp_populate_ttm\n"); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11) - mem = drm_agp_allocate_memory(num_pages, agp_priv->alloc_type); + mem = drm_agp_allocate_memory(num_pages, AGP_USER_MEMORY); #else - mem = drm_agp_allocate_memory(agp_priv->bridge, num_pages, agp_priv->alloc_type); + mem = drm_agp_allocate_memory(agp_be->bridge, num_pages, AGP_USER_MEMORY); #endif if (!mem) { drm_free_memctl(num_pages *sizeof(void *)); @@ -593,7 +594,7 @@ static int drm_agp_populate(drm_ttm_backend_t *backend, unsigned long num_pages, for (cur_page = pages; cur_page < last_page; ++cur_page) { mem->memory[mem->page_count++] = phys_to_gart(page_to_phys(*cur_page)); } - agp_priv->mem = mem; + agp_be->mem = mem; return 0; } @@ -601,76 +602,82 @@ static int drm_agp_bind_ttm(drm_ttm_backend_t *backend, unsigned long offset, int cached) { - drm_agp_ttm_priv *agp_priv = (drm_agp_ttm_priv *) backend->private; - DRM_AGP_MEM *mem = agp_priv->mem; + drm_agp_ttm_backend_t *agp_be = + container_of(backend, drm_agp_ttm_backend_t, backend); + DRM_AGP_MEM *mem = agp_be->mem; int ret; DRM_DEBUG("drm_agp_bind_ttm\n"); - DRM_FLAG_MASKED(backend->flags, (cached) ? DRM_BE_FLAG_BOUND_CACHED : 0, - DRM_BE_FLAG_BOUND_CACHED); mem->is_flushed = TRUE; - mem->type = (cached) ? agp_priv->cached_type : agp_priv->uncached_type; + mem->type = (cached) ? AGP_USER_CACHED_MEMORY : + AGP_USER_MEMORY; ret = drm_agp_bind_memory(mem, offset); if (ret) { DRM_ERROR("AGP Bind memory failed\n"); } + DRM_FLAG_MASKED(backend->flags, (cached) ? DRM_BE_FLAG_BOUND_CACHED : 0, + DRM_BE_FLAG_BOUND_CACHED); return ret; } static int drm_agp_unbind_ttm(drm_ttm_backend_t *backend) { - drm_agp_ttm_priv *agp_priv = (drm_agp_ttm_priv *) backend->private; + drm_agp_ttm_backend_t *agp_be = + container_of(backend, drm_agp_ttm_backend_t, backend); DRM_DEBUG("drm_agp_unbind_ttm\n"); - if (agp_priv->mem->is_bound) - return drm_agp_unbind_memory(agp_priv->mem); + if (agp_be->mem->is_bound) + return drm_agp_unbind_memory(agp_be->mem); else return 0; } static void drm_agp_clear_ttm(drm_ttm_backend_t *backend) { - drm_agp_ttm_priv *agp_priv = (drm_agp_ttm_priv *) backend->private; - DRM_AGP_MEM *mem = agp_priv->mem; + drm_agp_ttm_backend_t *agp_be = + container_of(backend, drm_agp_ttm_backend_t, backend); + DRM_AGP_MEM *mem = agp_be->mem; DRM_DEBUG("drm_agp_clear_ttm\n"); if (mem) { unsigned long num_pages = mem->page_count; - backend->unbind(backend); + backend->func->unbind(backend); agp_free_memory(mem); drm_free_memctl(num_pages *sizeof(void *)); } - - agp_priv->mem = NULL; + agp_be->mem = NULL; } static void drm_agp_destroy_ttm(drm_ttm_backend_t *backend) { - drm_agp_ttm_priv *agp_priv; + drm_agp_ttm_backend_t *agp_be; if (backend) { DRM_DEBUG("drm_agp_destroy_ttm\n"); - agp_priv = (drm_agp_ttm_priv *) backend->private; - if (agp_priv) { - if (agp_priv->mem) { - backend->clear(backend); + agp_be = container_of(backend, drm_agp_ttm_backend_t, backend); + if (agp_be) { + if (agp_be->mem) { + backend->func->clear(backend); } - drm_ctl_free(agp_priv, sizeof(*agp_priv), DRM_MEM_MAPPINGS); - backend->private = NULL; - } - if (backend->flags & DRM_BE_FLAG_NEEDS_FREE) { - drm_ctl_free(backend, sizeof(*backend), DRM_MEM_MAPPINGS); + drm_ctl_free(agp_be, sizeof(*agp_be), DRM_MEM_TTM); } } } - -drm_ttm_backend_t *drm_agp_init_ttm(struct drm_device *dev, - drm_ttm_backend_t *backend) +static drm_ttm_backend_func_t agp_ttm_backend = +{ + .needs_ub_cache_adjust = drm_agp_needs_unbind_cache_adjust, + .populate = drm_agp_populate, + .clear = drm_agp_clear_ttm, + .bind = drm_agp_bind_ttm, + .unbind = drm_agp_unbind_ttm, + .destroy = drm_agp_destroy_ttm, +}; + +drm_ttm_backend_t *drm_agp_init_ttm(struct drm_device *dev) { - drm_ttm_backend_t *agp_be; - drm_agp_ttm_priv *agp_priv; + drm_agp_ttm_backend_t *agp_be; struct agp_kern_info *info; if (!dev->agp) { @@ -690,37 +697,19 @@ drm_ttm_backend_t *drm_agp_init_ttm(struct drm_device *dev, return NULL; } - agp_be = (backend != NULL) ? backend: - drm_ctl_calloc(1, sizeof(*agp_be), DRM_MEM_MAPPINGS); - + + agp_be = drm_ctl_calloc(1, sizeof(*agp_be), DRM_MEM_TTM); if (!agp_be) return NULL; - agp_priv = drm_ctl_calloc(1, sizeof(*agp_priv), DRM_MEM_MAPPINGS); - - if (!agp_priv) { - drm_ctl_free(agp_be, sizeof(*agp_be), DRM_MEM_MAPPINGS); - return NULL; - } + agp_be->mem = NULL; + agp_be->bridge = dev->agp->bridge; + agp_be->populated = FALSE; + agp_be->backend.func = &agp_ttm_backend; + agp_be->backend.mem_type = DRM_BO_MEM_TT; - agp_priv->mem = NULL; - agp_priv->alloc_type = AGP_USER_MEMORY; - agp_priv->cached_type = AGP_USER_CACHED_MEMORY; - agp_priv->uncached_type = AGP_USER_MEMORY; - agp_priv->bridge = dev->agp->bridge; - agp_priv->populated = FALSE; - agp_be->private = (void *) agp_priv; - agp_be->needs_ub_cache_adjust = drm_agp_needs_unbind_cache_adjust; - agp_be->populate = drm_agp_populate; - agp_be->clear = drm_agp_clear_ttm; - agp_be->bind = drm_agp_bind_ttm; - agp_be->unbind = drm_agp_unbind_ttm; - agp_be->destroy = drm_agp_destroy_ttm; - DRM_FLAG_MASKED(agp_be->flags, (backend == NULL) ? DRM_BE_FLAG_NEEDS_FREE : 0, - DRM_BE_FLAG_NEEDS_FREE); - agp_be->drm_map_type = _DRM_AGP; - return agp_be; + return &agp_be->backend; } EXPORT_SYMBOL(drm_agp_init_ttm); diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c index 6be6f218..088c50d6 100644 --- a/linux-core/drm_fence.c +++ b/linux-core/drm_fence.c @@ -295,17 +295,21 @@ static int drm_fence_lazy_wait(drm_device_t *dev, { drm_fence_manager_t *fm = &dev->fm; drm_fence_class_manager_t *fc = &fm->class[fence->class]; - + int signaled; unsigned long _end = jiffies + 3*DRM_HZ; int ret = 0; do { DRM_WAIT_ON(ret, fc->fence_queue, 3 * DRM_HZ, - fence_signaled(dev, fence, mask, 1)); + (signaled = fence_signaled(dev, fence, mask, 1))); + if (signaled) + return 0; if (time_after_eq(jiffies, _end)) break; } while (ret == -EINTR && ignore_signals); - if (time_after_eq(jiffies, _end) && (ret != 0)) + if (fence_signaled(dev, fence, mask, 0)) + return 0; + if (time_after_eq(jiffies, _end)) ret = -EBUSY; if (ret) { if (ret == -EBUSY) { diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 1cdf6964..8a70c734 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -234,10 +234,8 @@ extern int drm_fence_ioctl(DRM_IOCTL_ARGS); #define DRM_BE_FLAG_NEEDS_FREE 0x00000001 #define DRM_BE_FLAG_BOUND_CACHED 0x00000002 -typedef struct drm_ttm_backend { - void *private; - uint32_t flags; - uint32_t drm_map_type; +struct drm_ttm_backend; +typedef struct drm_ttm_backend_func { int (*needs_ub_cache_adjust) (struct drm_ttm_backend * backend); int (*populate) (struct drm_ttm_backend * backend, unsigned long num_pages, struct page ** pages); @@ -246,6 +244,13 @@ typedef struct drm_ttm_backend { unsigned long offset, int cached); int (*unbind) (struct drm_ttm_backend * backend); void (*destroy) (struct drm_ttm_backend * backend); +} drm_ttm_backend_func_t; + + +typedef struct drm_ttm_backend { + uint32_t flags; + int mem_type; + drm_ttm_backend_func_t *func; } drm_ttm_backend_t; typedef struct drm_ttm { diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c index 25566340..31503c9c 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -154,7 +154,7 @@ int drm_destroy_ttm(drm_ttm_t * ttm) be = ttm->be; if (be) { - be->destroy(be); + be->func->destroy(be); ttm->be = NULL; } @@ -222,7 +222,7 @@ static int drm_ttm_populate(drm_ttm_t * ttm) if (!page) return -ENOMEM; } - be->populate(be, ttm->num_pages, ttm->pages); + be->func->populate(be, ttm->num_pages, ttm->pages); ttm->state = ttm_unbound; return 0; } @@ -281,7 +281,7 @@ void drm_ttm_evict(drm_ttm_t * ttm) int ret; if (ttm->state == ttm_bound) { - ret = be->unbind(be); + ret = be->func->unbind(be); BUG_ON(ret); } @@ -293,7 +293,7 @@ void drm_ttm_fixup_caching(drm_ttm_t * ttm) if (ttm->state == ttm_evicted) { drm_ttm_backend_t *be = ttm->be; - if (be->needs_ub_cache_adjust(be)) { + if (be->func->needs_ub_cache_adjust(be)) { drm_set_caching(ttm, 0); } ttm->state = ttm_unbound; @@ -329,7 +329,7 @@ int drm_bind_ttm(drm_ttm_t * ttm, int cached, unsigned long aper_offset) drm_set_caching(ttm, DRM_TTM_PAGE_UNCACHED); } - if ((ret = be->bind(be, aper_offset, cached))) { + if ((ret = be->func->bind(be, aper_offset, cached))) { ttm->state = ttm_evicted; DRM_ERROR("Couldn't bind backend.\n"); return ret; diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 8797de89..8589f467 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -35,7 +35,7 @@ drm_ttm_backend_t *i915_create_ttm_backend_entry(drm_device_t * dev) { - return drm_agp_init_ttm(dev, NULL); + return drm_agp_init_ttm(dev); } int i915_fence_types(drm_buffer_object_t *bo, uint32_t * class, uint32_t * type) diff --git a/linux-core/via_buffer.c b/linux-core/via_buffer.c index f156ee6d..ebc8c371 100644 --- a/linux-core/via_buffer.c +++ b/linux-core/via_buffer.c @@ -34,7 +34,7 @@ drm_ttm_backend_t *via_create_ttm_backend_entry(drm_device_t * dev) { - return drm_agp_init_ttm(dev, NULL); + return drm_agp_init_ttm(dev); } int via_fence_types(drm_buffer_object_t *bo, uint32_t * class, uint32_t * type) diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index 72c28627..f090489f 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -358,7 +358,7 @@ 0x10DE 0x0309 NV30 "NVidia Quadro FX 1000" 0x10DE 0x0311 NV30 "NVidia GeForce FX 5600 Ultra" 0x10DE 0x0312 NV30 "NVidia GeForce FX 5600" -0x10DE 0x0313 NV30 "NVidia 0x0313"}, +0x10DE 0x0313 NV30 "NVidia 0x0313" 0x10DE 0x0314 NV30 "NVidia GeForce FX 5600SE" 0x10DE 0x0316 NV30 "NVidia 0x0316" 0x10DE 0x0317 NV30 "NVidia 0x0317" |