Checkpoint ttm addition to buffer objects.
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Tue, 29 Aug 2006 12:52:02 +0000 (14:52 +0200)
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Tue, 29 Aug 2006 12:52:02 +0000 (14:52 +0200)
linux-core/drmP.h
linux-core/drm_bo.c
linux-core/drm_ttm.c
linux-core/drm_ttm.h
shared-core/drm.h

index af082ad..81b7a1b 100644 (file)
@@ -951,8 +951,9 @@ typedef struct drm_buffer_object{
        atomic_t usage;
        drm_ttm_object_t *ttm_object;
        drm_ttm_backend_list_t *ttm_region;
-        void __user *user_pages;
        unsigned long num_pages;
+        unsigned long buffer_start;
+        drm_bo_type_t type;
 
        atomic_t mapped;
        uint32_t flags;
index 2363495..3065606 100644 (file)
@@ -141,8 +141,8 @@ static int drm_move_tt_to_local(drm_buffer_object_t *buf, int lazy)
        drm_unbind_ttm_region(buf->ttm_region);
        drm_mm_put_block(&bm->tt_manager, buf->tt);
        buf->tt = NULL;
-       buf->flags &= ~(DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_UNCACHED);
-       buf->flags |= DRM_BO_FLAG_MEM_LOCAL;
+       buf->flags &= ~(DRM_BO_FLAG_MEM_TT);
+       buf->flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
 
        return 0;
 }
@@ -531,9 +531,65 @@ static int drm_buffer_object_validate(drm_device_t *dev, drm_buffer_object_t *bo
        return 0;
 }
 
+/*
+ * Call bo->mutex locked.
+ */
+
+static int drm_bo_add_ttm(drm_file_t *priv, drm_buffer_object_t *bo, uint32_t new_flags, 
+                         uint32_t ttm_handle)
+
+{
+       drm_device_t *dev = bo->dev;
+       drm_ttm_object_t *to = NULL;
+       drm_ttm_t *ttm;
+       int ret=0;
+       uint32_t ttm_flags = 0;
+
+       bo->ttm_object = NULL;
+       bo->ttm_region = NULL;
+
+       switch(bo->type) {
+       case drm_bo_type_dc:
+               mutex_lock(&dev->struct_mutex);
+               ret = drm_ttm_object_create(dev, bo->num_pages*PAGE_SIZE, 
+                                           ttm_flags, &to);
+               mutex_unlock(&dev->struct_mutex);
+               break;
+       case drm_bo_type_ttm:
+               mutex_lock(&dev->struct_mutex);
+               to = drm_lookup_ttm_object(priv, ttm_handle, 1);
+               mutex_unlock(&dev->struct_mutex);
+               if (!to) 
+                       ret = -EINVAL;
+               break;
+       case drm_bo_type_user:
+
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       if (ret) {
+               return ret;
+       }
+
+       if (to) {
+               bo->ttm_object = to;
+               ttm = drm_ttm_from_object(to);
+               ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT,
+                                           bo->num_pages, 
+                                           new_flags & DRM_BO_FLAG_CACHED, 
+                                           &bo->ttm_region);
+               if (ret) {
+                       drm_ttm_object_deref_unlocked(dev, to);
+               }
+       }
+       return ret;
+}
+                      
 
 int drm_buffer_object_create(drm_file_t *priv,
-                            int size,
+                            unsigned long size,
                             drm_bo_type_t type,
                             uint32_t ttm_handle,
                             uint32_t mask,
@@ -544,8 +600,18 @@ int drm_buffer_object_create(drm_file_t *priv,
        drm_device_t *dev = priv->head->dev;
        drm_buffer_object_t *bo;
        int ret = 0;
-       uint32_t ttm_flags = 0;
-       drm_ttm_t *ttm;
+       uint32_t new_flags;
+       unsigned long num_pages;
+       
+       if (buffer_start & ~PAGE_MASK) {
+               DRM_ERROR("Invalid buffer object start.\n");
+               return -EINVAL;
+       }
+       num_pages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
+       if (num_pages == 0) {
+               DRM_ERROR("Illegal buffer object size.\n");
+               return -EINVAL;
+       }
 
        bo = drm_calloc(1, sizeof(*bo), DRM_MEM_BUFOBJ);
 
@@ -561,50 +627,14 @@ int drm_buffer_object_create(drm_file_t *priv,
        INIT_LIST_HEAD(&bo->head);
        INIT_LIST_HEAD(&bo->ddestroy);
        bo->dev = dev;
+       bo->type = type;
+       bo->num_pages = num_pages;
+       bo->buffer_start = buffer_start;
 
-       switch(type) {
-       case drm_bo_type_dc:
-               ret = drm_ttm_object_create(dev, size, ttm_flags, &bo->ttm_object);
-               if (ret) 
-                       goto out_err;
-               break;
-       case drm_bo_type_ttm:
-               if (buffer_start & ~PAGE_MASK) {
-                       DRM_ERROR("Illegal buffer object start\n");
-                       ret = -EINVAL;
-               }
-               bo->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-               if (!bo->num_pages) {
-                       DRM_ERROR("Illegal buffer object size\n");
-                       ret = -EINVAL;
-                       goto out_err;
-               }                       
-               bo->ttm_object = drm_lookup_ttm_object(priv, ttm_handle, 1);
-               if (!bo->ttm_object) {
-                       DRM_ERROR("Could not find buffer object TTM\n");
-                       ret = -EINVAL;
-                       goto out_err;
-               }
-               ttm = drm_ttm_from_object(bo->ttm_object);
-               ret = drm_create_ttm_region(ttm, buffer_start >> PAGE_SHIFT,
-                                           bo->num_pages, 0, &bo->ttm_region);
-               if (ret) 
-                       goto out_err;
-               break;
-       case drm_bo_type_user:
-               if (buffer_start & ~PAGE_MASK) {
-                       DRM_ERROR("Illegal buffer object start\n");
-                       ret = -EINVAL;
-                       goto out_err;
-               }
-               bo->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 
-               bo->user_pages = (void __user *)buffer_start;
-               break;
-       default:
-               ret = -EINVAL;
+       ret = drm_bo_add_ttm(priv, bo, new_flags, ttm_handle);
+       if (ret) 
                goto out_err;
-       }
-                               
+
        bo->mask = mask;
        bo->mask_hint = hint;
 
index 8cd0af6..e111070 100644 (file)
@@ -784,6 +784,16 @@ void drm_ttm_object_deref_locked(drm_device_t *dev, drm_ttm_object_t *to)
        }
 }
 
+void drm_ttm_object_deref_unlocked(drm_device_t *dev, drm_ttm_object_t *to)
+{
+       if (atomic_dec_and_test(&to->usage)) {
+               mutex_lock(&dev->struct_mutex);
+               if (atomic_read(&to->usage) == 0)
+                       drm_ttm_object_remove(dev, to);
+               mutex_unlock(&dev->struct_mutex);
+       }
+}
+
 
 /*
  * dev->struct_mutex locked.
index ba4261b..a181050 100644 (file)
@@ -111,6 +111,7 @@ typedef struct drm_ttm_object {
 extern int drm_ttm_object_create(struct drm_device *dev, unsigned long size, 
                                 uint32_t flags, drm_ttm_object_t **ttm_object);
 extern void drm_ttm_object_deref_locked(struct drm_device *dev, drm_ttm_object_t *to);
+extern void drm_ttm_object_deref_unlocked(struct drm_device *dev, drm_ttm_object_t *to);
 extern drm_ttm_object_t *drm_lookup_ttm_object(drm_file_t *priv, uint32_t handle, 
                                               int check_owner);
 
index f8479dd..e50ebfe 100644 (file)
@@ -686,7 +686,7 @@ typedef struct drm_ttm_arg {
 #define DRM_BO_FLAG_NO_EVICT    0x00000010
 #define DRM_BO_FLAG_SHADOW_VRAM 0x00000020
 #define DRM_BO_FLAG_READ_LOCAL  0x00000040
-#define DRM_BO_FLAG_UNCACHED    0x00000080
+#define DRM_BO_FLAG_CACHED      0x00000080
 #define DRM_BO_FLAG_SHAREABLE   0x00000100
 
 #define DRM_BO_FLAG_MEM_TT      0x01000000