summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-04-26 15:56:21 +1000
committerDave Airlie <airlied@linux.ie>2007-04-26 15:56:21 +1000
commitb589b846e73bfe6235cd702bb8ae89701c85eaab (patch)
treec54ddc23cfba3b5d9fafb86477d20fde4c36a52a
parent34be91fe4e9f0ad73b7c4354aea0c8ce10f45f68 (diff)
parent5c8561aae22138880673503d930af7f1b361d071 (diff)
Merge branch 'origin' into modesetting-101
-rw-r--r--README71
-rw-r--r--linux-core/drmP.h11
-rw-r--r--linux-core/drm_agpsupport.c105
-rw-r--r--linux-core/drm_fence.c10
-rw-r--r--linux-core/drm_objects.h13
-rw-r--r--linux-core/drm_ttm.c10
-rw-r--r--linux-core/i915_buffer.c2
-rw-r--r--linux-core/via_buffer.c2
-rw-r--r--shared-core/drm_pciids.txt2
9 files changed, 143 insertions, 83 deletions
diff --git a/README b/README
index b466dd88..40f7e114 100644
--- a/README
+++ b/README
@@ -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"