summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/drmP.h1
-rw-r--r--linux-core/drm_bo.c107
-rw-r--r--linux-core/drm_drv.c2
3 files changed, 94 insertions, 16 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 59926968..6cce6b8d 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -963,7 +963,6 @@ typedef struct drm_buffer_object{
uint32_t map_flags;
uint32_t flags;
uint32_t mask;
- uint32_t hint;
drm_mm_node_t *vram;
drm_mm_node_t *tt;
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index aa59238f..057de9a0 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -55,6 +55,17 @@
* 2.) Refer to ttm locking orders.
*/
+
+#define DRM_FLAG_MASKED(_old, _new, _mask) {\
+(_old) ^= (((_old) ^ (_new)) & (_mask)); \
+}
+
+static inline uint32_t drm_flag_masked(uint32_t old, uint32_t new,
+ uint32_t mask)
+{
+ return old ^ ((old ^ new) & mask);
+}
+
int drm_fence_buffer_objects(drm_file_t * priv)
{
drm_device_t *dev = priv->head->dev;
@@ -243,7 +254,7 @@ static int drm_bo_new_flags(drm_bo_driver_t * driver,
}
}
if (new_flags & DRM_BO_FLAG_MEM_TT) {
- if ((hint & DRM_BO_HINT_PREFER_VRAM) &&
+ if ((new_mask & DRM_BO_FLAG_PREFER_VRAM) &&
new_flags & DRM_BO_FLAG_MEM_VRAM) {
new_flags = DRM_BO_FLAG_MEM_VRAM;
} else {
@@ -264,7 +275,7 @@ static int drm_bo_new_flags(drm_bo_driver_t * driver,
new_flags |= new_mask & ~DRM_BO_MASK_MEM;
- if (hint & DRM_BO_HINT_BIND_CACHED) {
+ if (new_mask & DRM_BO_FLAG_BIND_CACHED) {
new_flags |= DRM_BO_FLAG_CACHED;
if (((new_flags & DRM_BO_FLAG_MEM_TT) && !driver->cached_tt) ||
((new_flags & DRM_BO_FLAG_MEM_VRAM)
@@ -513,11 +524,8 @@ static int drm_buffer_object_unmap(drm_file_t * priv, uint32_t handle)
goto out;
}
- DRM_ERROR("Removing ref object\n");
drm_remove_ref_object(priv, ro);
- DRM_ERROR("Deregistering usage\n");
drm_bo_usage_deref_locked(dev, bo);
- DRM_ERROR("Done\n");
out:
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -548,19 +556,91 @@ static void drm_buffer_user_object_unmap(drm_file_t * priv,
}
}
-static int drm_buffer_object_validate(drm_device_t * dev, uint32_t new_flags,
- drm_buffer_object_t * bo)
+static int drm_bo_move_buffer(drm_buffer_object_t *bo, uint32_t new_flags,
+ int no_wait)
{
- bo->flags = new_flags;
return 0;
}
+
+/*
+ * bo locked.
+ */
+
+
+static int drm_buffer_object_validate(drm_buffer_object_t * bo,
+ uint32_t new_flags,
+ int move_unfenced,
+ int no_wait)
+{
+ drm_device_t *dev = bo->dev;
+ drm_buffer_manager_t *bm = &dev->bm;
+ uint32_t flag_diff = (new_flags ^ bo->flags);
+
+ int ret;
+
+ if (new_flags & DRM_BO_FLAG_MEM_VRAM) {
+ DRM_ERROR("Vram support not implemented yet\n");
+ return -EINVAL;
+ }
+ if ((new_flags & (DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM)) &&
+ (new_flags & DRM_BO_FLAG_CACHED)) {
+ DRM_ERROR("Cached binding not implemented yet\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Check whether we need to move buffer.
+ */
+
+ if (flag_diff & DRM_BO_MASK_MEM) {
+ mutex_lock(&bm->mutex);
+ ret = drm_bo_move_buffer(bo, new_flags, no_wait);
+ mutex_unlock(&bm->mutex);
+ if (ret)
+ return ret;
+ }
+
+ if (flag_diff & DRM_BO_FLAG_NO_EVICT) {
+ mutex_lock(&bm->mutex);
+ list_del_init(&bo->head);
+ if (!(new_flags & DRM_BO_FLAG_NO_EVICT)) {
+ if (new_flags & DRM_BO_FLAG_MEM_TT) {
+ list_add_tail(&bo->head, &bm->tt_lru);
+ } else {
+ list_add_tail(&bo->head, &bm->vram_lru);
+ }
+ }
+ mutex_unlock(&bm->mutex);
+ DRM_FLAG_MASKED(bo->flags, new_flags, DRM_BO_FLAG_NO_EVICT);
+ }
+
+ if (move_unfenced) {
+
+ /*
+ * Place on unfenced list.
+ */
+
+ mutex_lock(&bm->mutex);
+ list_del_init(&bo->head);
+ list_add_tail(&bo->head, &bm->unfenced);
+ mutex_unlock(&bm->mutex);
+ }
+
+ /*
+ * FIXME: Remove below.
+ */
+
+ bo->flags = new_flags;
+ return 0;
+}
+
/*
* Call bo->mutex locked.
*/
static int drm_bo_add_ttm(drm_file_t * priv, drm_buffer_object_t * bo,
- uint32_t hint, uint32_t ttm_handle)
+ uint32_t mask, uint32_t ttm_handle)
{
drm_device_t *dev = bo->dev;
drm_ttm_object_t *to = NULL;
@@ -605,7 +685,7 @@ static int drm_bo_add_ttm(drm_file_t * priv, drm_buffer_object_t * bo,
ttm = drm_ttm_from_object(to);
ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT,
bo->num_pages,
- hint & DRM_BO_HINT_BIND_CACHED,
+ mask & DRM_BO_FLAG_BIND_CACHED,
&bo->ttm_region);
if (ret) {
drm_ttm_object_deref_unlocked(dev, to);
@@ -661,14 +741,14 @@ int drm_buffer_object_create(drm_file_t * priv,
1, &new_flags);
if (ret)
goto out_err;
- ret = drm_bo_add_ttm(priv, bo, new_flags, ttm_handle);
+ ret = drm_bo_add_ttm(priv, bo, mask, ttm_handle);
if (ret)
goto out_err;
bo->mask = mask;
- bo->hint = hint;
- ret = drm_buffer_object_validate(dev, new_flags, bo);
+ ret = drm_buffer_object_validate(bo, new_flags, 0,
+ hint & DRM_BO_HINT_DONT_BLOCK);
if (ret)
goto out_err;
@@ -719,7 +799,6 @@ static void drm_bo_fill_rep_arg(const drm_buffer_object_t * bo,
rep->map_flags = bo->map_flags;
rep->mask = bo->mask;
- rep->hint = bo->hint;
rep->buffer_start = bo->buffer_start;
}
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 62df6803..1bf87703 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -123,7 +123,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_TTM)] = {drm_ttm_ioctl, DRM_AUTH},
[DRM_IOCTL_NR(DRM_IOCTL_BUFOBJ)] = {drm_bo_ioctl, DRM_AUTH},
[DRM_IOCTL_NR(DRM_IOCTL_MM_INIT)] = {drm_mm_init_ioctl,
- DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY},
+ DRM_AUTH }
};
#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )