aboutsummaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-07-31 12:54:48 +1000
committerDave Airlie <airlied@redhat.com>2008-07-31 12:54:48 +1000
commit9b8d71b5eb09857b07409731d3de182751f712a2 (patch)
tree452efcf85dffd27d292f480b536b20f52332f389 /linux-core
parentfb5542aaa87aca9b6b312968abe0a6044812cf0e (diff)
TTM: remove API and userspace objects.
This removes all the TTM userspace API and all userspace objects. It also removes the drm_bo_lock.c code
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/Makefile.kernel7
-rw-r--r--linux-core/drmP.h18
-rw-r--r--linux-core/drm_bo.c729
-rw-r--r--linux-core/drm_bo_lock.c189
-rw-r--r--linux-core/drm_crtc_helper.c44
-rw-r--r--linux-core/drm_drv.c30
-rw-r--r--linux-core/drm_fence.c298
-rw-r--r--linux-core/drm_fops.c43
-rw-r--r--linux-core/drm_object.c294
-rw-r--r--linux-core/drm_objects.h273
-rw-r--r--linux-core/drm_ttm.c2
-rw-r--r--linux-core/i915_buffer.c311
-rw-r--r--linux-core/i915_execbuf.c921
-rw-r--r--linux-core/i915_fence.c273
-rw-r--r--linux-core/radeon_gem.c15
15 files changed, 188 insertions, 3259 deletions
diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel
index 404944bf..b15a12ab 100644
--- a/linux-core/Makefile.kernel
+++ b/linux-core/Makefile.kernel
@@ -12,16 +12,15 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_sysfs.o drm_pci.o drm_agpsupport.o drm_scatter.o \
drm_memory_debug.o ati_pcigart.o drm_sman.o \
- drm_hashtab.o drm_memrange.o drm_object.o drm_compat.o \
- drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_bo_lock.o \
+ drm_hashtab.o drm_memrange.o drm_compat.o \
+ drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o \
drm_crtc.o drm_edid.o drm_modes.o drm_crtc_helper.o \
drm_regman.o drm_vm_nopage_compat.o drm_gem.o
tdfx-objs := tdfx_drv.o
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
i810-objs := i810_drv.o i810_dma.o
-i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \
- i915_buffer.o i915_execbuf.o i915_gem.o \
+i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_gem.o \
intel_display.o intel_crt.o intel_lvds.o intel_bios.o \
intel_sdvo.o intel_modes.o intel_i2c.o i915_init.o intel_fb.o \
intel_tv.o i915_compat.o intel_dvo.o dvo_ch7xxx.o \
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index e3a08e79..4938881f 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -405,14 +405,6 @@ struct drm_buf_entry {
struct drm_freelist freelist;
};
-
-enum drm_ref_type {
- _DRM_REF_USE = 0,
- _DRM_REF_TYPE1,
- _DRM_NO_REF_TYPES
-};
-
-
/** File private data */
struct drm_file {
int authenticated;
@@ -424,21 +416,11 @@ struct drm_file {
struct drm_minor *minor;
unsigned long lock_count;
- /*
- * The user object hash table is global and resides in the
- * drm_device structure. We protect the lists and hash tables with the
- * device struct_mutex. A bit coarse-grained but probably the best
- * option.
- */
-
- struct list_head refd_objects;
-
/** Mapping of mm object handles to object pointers. */
struct idr object_idr;
/** Lock for synchronization of access to object_idr. */
spinlock_t table_lock;
- struct drm_open_hash refd_object_hash[_DRM_NO_REF_TYPES];
struct file *filp;
void *driver_priv;
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index 0021530b..84cf69bd 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -565,18 +565,6 @@ void drm_bo_usage_deref_locked(struct drm_buffer_object **bo)
}
EXPORT_SYMBOL(drm_bo_usage_deref_locked);
-static void drm_bo_base_deref_locked(struct drm_file *file_priv,
- struct drm_user_object *uo)
-{
- struct drm_buffer_object *bo =
- drm_user_object_entry(uo, struct drm_buffer_object, base);
-
- DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
-
- drm_bo_takedown_vm_locked(bo);
- drm_bo_usage_deref_locked(&bo);
-}
-
void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo)
{
struct drm_buffer_object *tmp_bo = *bo;
@@ -1068,34 +1056,6 @@ static int drm_bo_modify_proposed_flags (struct drm_buffer_object *bo,
}
/*
- * Call dev->struct_mutex locked.
- */
-
-struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file *file_priv,
- uint32_t handle, int check_owner)
-{
- struct drm_user_object *uo;
- struct drm_buffer_object *bo;
-
- uo = drm_lookup_user_object(file_priv, handle);
-
- if (!uo || (uo->type != drm_buffer_type)) {
- DRM_ERROR("Could not find buffer object 0x%08x\n", handle);
- return NULL;
- }
-
- if (check_owner && file_priv != uo->owner) {
- if (!drm_lookup_ref_object(file_priv, uo, _DRM_REF_USE))
- return NULL;
- }
-
- bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
- atomic_inc(&bo->usage);
- return bo;
-}
-EXPORT_SYMBOL(drm_lookup_buffer_object);
-
-/*
* Call bo->mutex locked.
* Returns -EBUSY if the buffer is currently rendered to or from. 0 otherwise.
* Doesn't do any fence flushing as opposed to the drm_bo_busy function.
@@ -1158,149 +1118,6 @@ static int drm_bo_wait_unmapped(struct drm_buffer_object *bo, int no_wait)
}
/*
- * Fill in the ioctl reply argument with buffer info.
- * Bo locked.
- */
-
-void drm_bo_fill_rep_arg(struct drm_buffer_object *bo,
- struct drm_bo_info_rep *rep)
-{
- if (!rep)
- return;
-
- rep->handle = bo->base.hash.key;
- rep->flags = bo->mem.flags;
- rep->size = bo->num_pages * PAGE_SIZE;
- rep->offset = bo->offset;
-
- /*
- * drm_bo_type_device buffers have user-visible
- * handles which can be used to share across
- * processes. Hand that back to the application
- */
- if (bo->type == drm_bo_type_device)
- rep->arg_handle = bo->map_list.user_token;
- else
- rep->arg_handle = 0;
-
- rep->proposed_flags = bo->mem.proposed_flags;
- rep->buffer_start = bo->buffer_start;
- rep->fence_flags = bo->fence_type;
- rep->rep_flags = 0;
- rep->page_alignment = bo->mem.page_alignment;
-
- if ((bo->priv_flags & _DRM_BO_FLAG_UNFENCED) || drm_bo_quick_busy(bo, 1)) {
- DRM_FLAG_MASKED(rep->rep_flags, DRM_BO_REP_BUSY,
- DRM_BO_REP_BUSY);
- }
-}
-EXPORT_SYMBOL(drm_bo_fill_rep_arg);
-
-/*
- * Wait for buffer idle and register that we've mapped the buffer.
- * Mapping is registered as a drm_ref_object with type _DRM_REF_TYPE1,
- * so that if the client dies, the mapping is automatically
- * unregistered.
- */
-
-static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle,
- uint32_t map_flags, unsigned hint,
- struct drm_bo_info_rep *rep)
-{
- struct drm_buffer_object *bo;
- struct drm_device *dev = file_priv->minor->dev;
- int ret = 0;
- int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- mutex_lock(&bo->mutex);
- do {
- bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED;
-
- ret = drm_bo_wait(bo, 0, 1, no_wait, 1);
- if (unlikely(ret))
- goto out;
-
- if (bo->mem.flags & DRM_BO_FLAG_CACHED_MAPPED)
- drm_bo_evict_cached(bo);
-
- } while (unlikely(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED));
-
- atomic_inc(&bo->mapped);
- mutex_lock(&dev->struct_mutex);
- ret = drm_add_ref_object(file_priv, &bo->base, _DRM_REF_TYPE1);
- mutex_unlock(&dev->struct_mutex);
- if (ret) {
- if (atomic_dec_and_test(&bo->mapped))
- wake_up_all(&bo->event_queue);
-
- } else
- drm_bo_fill_rep_arg(bo, rep);
-
- out:
- mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(&bo);
-
- return ret;
-}
-
-static int drm_buffer_object_unmap(struct drm_file *file_priv, uint32_t handle)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *bo;
- struct drm_ref_object *ro;
- int ret = 0;
-
- mutex_lock(&dev->struct_mutex);
-
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- if (!bo) {
- ret = -EINVAL;
- goto out;
- }
-
- ro = drm_lookup_ref_object(file_priv, &bo->base, _DRM_REF_TYPE1);
- if (!ro) {
- ret = -EINVAL;
- goto out;
- }
-
- drm_remove_ref_object(file_priv, ro);
- drm_bo_usage_deref_locked(&bo);
-out:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-/*
- * Call struct-sem locked.
- */
-
-static void drm_buffer_user_object_unmap(struct drm_file *file_priv,
- struct drm_user_object *uo,
- enum drm_ref_type action)
-{
- struct drm_buffer_object *bo =
- drm_user_object_entry(uo, struct drm_buffer_object, base);
-
- /*
- * We DON'T want to take the bo->lock here, because we want to
- * hold it when we wait for unmapped buffer.
- */
-
- BUG_ON(action != _DRM_REF_TYPE1);
-
- if (atomic_dec_and_test(&bo->mapped))
- wake_up_all(&bo->event_queue);
-}
-
-/*
* bo->mutex locked.
* Note that new_mem_flags are NOT transferred to the bo->mem.proposed_flags.
*/
@@ -1594,8 +1411,7 @@ static int drm_bo_prepare_for_validate(struct drm_buffer_object *bo,
int drm_bo_do_validate(struct drm_buffer_object *bo,
uint64_t flags, uint64_t mask, uint32_t hint,
- uint32_t fence_class,
- struct drm_bo_info_rep *rep)
+ uint32_t fence_class)
{
int ret;
int no_wait = (hint & DRM_BO_HINT_DONT_BLOCK) != 0;
@@ -1622,132 +1438,12 @@ int drm_bo_do_validate(struct drm_buffer_object *bo,
BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED);
out:
- if (rep)
- drm_bo_fill_rep_arg(bo, rep);
-
mutex_unlock(&bo->mutex);
return ret;
}
EXPORT_SYMBOL(drm_bo_do_validate);
-/**
- * drm_bo_handle_validate
- *
- * @file_priv: the drm file private, used to get a handle to the user context
- *
- * @handle: the buffer object handle
- *
- * @flags: access rights, mapping parameters and cacheability. See
- * the DRM_BO_FLAG_* values in drm.h
- *
- * @mask: Which flag values to change; this allows callers to modify
- * things without knowing the current state of other flags.
- *
- * @hint: changes the proceedure for this operation, see the DRM_BO_HINT_*
- * values in drm.h.
- *
- * @fence_class: a driver-specific way of doing fences. Presumably,
- * this would be used if the driver had more than one submission and
- * fencing mechanism. At this point, there isn't any use of this
- * from the user mode code.
- *
- * @rep: To be stuffed with the reply from validation
- *
- * @bp_rep: To be stuffed with the buffer object pointer
- *
- * Perform drm_bo_do_validate on a buffer referenced by a user-space handle instead
- * of a pointer to a buffer object. Optionally return a pointer to the buffer object.
- * This is a convenience wrapper only.
- */
-
-int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle,
- uint64_t flags, uint64_t mask,
- uint32_t hint,
- uint32_t fence_class,
- struct drm_bo_info_rep *rep,
- struct drm_buffer_object **bo_rep)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *bo;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- if (bo->base.owner != file_priv)
- mask &= ~(DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE);
-
- ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class, rep);
-
- if (!ret && bo_rep)
- *bo_rep = bo;
- else
- drm_bo_usage_deref_unlocked(&bo);
-
- return ret;
-}
-EXPORT_SYMBOL(drm_bo_handle_validate);
-
-
-static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle,
- struct drm_bo_info_rep *rep)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *bo;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- mutex_lock(&bo->mutex);
-
- /*
- * FIXME: Quick busy here?
- */
-
- drm_bo_busy(bo, 1);
- drm_bo_fill_rep_arg(bo, rep);
- mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(&bo);
- return 0;
-}
-
-static int drm_bo_handle_wait(struct drm_file *file_priv, uint32_t handle,
- uint32_t hint,
- struct drm_bo_info_rep *rep)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *bo;
- int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- mutex_lock(&bo->mutex);
- ret = drm_bo_wait(bo, hint & DRM_BO_HINT_WAIT_LAZY, 1, no_wait, 1);
- if (ret)
- goto out;
-
- drm_bo_fill_rep_arg(bo, rep);
-out:
- mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(&bo);
- return ret;
-}
-
int drm_buffer_object_create(struct drm_device *dev,
unsigned long size,
enum drm_bo_type type,
@@ -1822,7 +1518,7 @@ int drm_buffer_object_create(struct drm_device *dev,
mutex_unlock(&bo->mutex);
ret = drm_bo_do_validate(bo, 0, 0, hint | DRM_BO_HINT_DONT_FENCE,
- 0, NULL);
+ 0);
if (ret)
goto out_err_unlocked;
@@ -1837,230 +1533,6 @@ out_err_unlocked:
}
EXPORT_SYMBOL(drm_buffer_object_create);
-
-int drm_bo_add_user_object(struct drm_file *file_priv,
- struct drm_buffer_object *bo, int shareable)
-{
- struct drm_device *dev = file_priv->minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm_add_user_object(file_priv, &bo->base, shareable);
- if (ret)
- goto out;
-
- bo->base.remove = drm_bo_base_deref_locked;
- bo->base.type = drm_buffer_type;
- bo->base.ref_struct_locked = NULL;
- bo->base.unref = drm_buffer_user_object_unmap;
-
-out:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-EXPORT_SYMBOL(drm_bo_add_user_object);
-
-int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_create_arg *arg = data;
- struct drm_bo_create_req *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- struct drm_buffer_object *entry;
- enum drm_bo_type bo_type;
- int ret = 0;
-
- DRM_DEBUG("drm_bo_create_ioctl: %dkb, %dkb align\n",
- (int)(req->size / 1024), req->page_alignment * 4);
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- /*
- * If the buffer creation request comes in with a starting address,
- * that points at the desired user pages to map. Otherwise, create
- * a drm_bo_type_device buffer, which uses pages allocated from the kernel
- */
- bo_type = (req->buffer_start) ? drm_bo_type_user : drm_bo_type_device;
-
- /*
- * User buffers cannot be shared
- */
- if (bo_type == drm_bo_type_user)
- req->flags &= ~DRM_BO_FLAG_SHAREABLE;
-
- ret = drm_buffer_object_create(file_priv->minor->dev,
- req->size, bo_type, req->flags,
- req->hint, req->page_alignment,
- req->buffer_start, &entry);
- if (ret)
- goto out;
-
- ret = drm_bo_add_user_object(file_priv, entry,
- req->flags & DRM_BO_FLAG_SHAREABLE);
- if (ret) {
- drm_bo_usage_deref_unlocked(&entry);
- goto out;
- }
-
- mutex_lock(&entry->mutex);
- drm_bo_fill_rep_arg(entry, rep);
- mutex_unlock(&entry->mutex);
-
-out:
- return ret;
-}
-
-int drm_bo_setstatus_ioctl(struct drm_device *dev,
- void *data, struct drm_file *file_priv)
-{
- struct drm_bo_map_wait_idle_arg *arg = data;
- struct drm_bo_info_req *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- struct drm_buffer_object *bo;
- int ret;
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_bo_read_lock(&dev->bm.bm_lock, 1);
- if (ret)
- return ret;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, req->handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- if (bo->base.owner != file_priv)
- req->mask &= ~(DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE);
-
- ret = drm_bo_do_validate(bo, req->flags, req->mask,
- req->hint | DRM_BO_HINT_DONT_FENCE,
- bo->fence_class, rep);
-
- drm_bo_usage_deref_unlocked(&bo);
-
- (void) drm_bo_read_unlock(&dev->bm.bm_lock);
-
- return ret;
-}
-
-int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_map_wait_idle_arg *arg = data;
- struct drm_bo_info_req *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- int ret;
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_buffer_object_map(file_priv, req->handle, req->mask,
- req->hint, rep);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_handle_arg *arg = data;
- int ret;
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_buffer_object_unmap(file_priv, arg->handle);
- return ret;
-}
-
-
-int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_reference_info_arg *arg = data;
- struct drm_bo_handle_arg *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- struct drm_user_object *uo;
- int ret;
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_user_object_ref(file_priv, req->handle,
- drm_buffer_type, &uo);
- if (ret)
- return ret;
-
- ret = drm_bo_handle_info(file_priv, req->handle, rep);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_handle_arg *arg = data;
- int ret = 0;
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_user_object_unref(file_priv, arg->handle, drm_buffer_type);
- return ret;
-}
-
-int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_reference_info_arg *arg = data;
- struct drm_bo_handle_arg *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- int ret;
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_bo_handle_info(file_priv, req->handle, rep);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_map_wait_idle_arg *arg = data;
- struct drm_bo_info_req *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- int ret;
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_bo_handle_wait(file_priv, req->handle,
- req->hint, rep);
- if (ret)
- return ret;
-
- return 0;
-}
-
static int drm_bo_leave_list(struct drm_buffer_object *bo,
uint32_t mem_type,
int free_pinned,
@@ -2435,191 +1907,6 @@ out_unlock:
}
EXPORT_SYMBOL(drm_bo_driver_init);
-int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_mm_init_arg *arg = data;
- struct drm_buffer_manager *bm = &dev->bm;
- struct drm_bo_driver *driver = dev->driver->bo_driver;
- int ret;
-
- if (!driver) {
- DRM_ERROR("Buffer objects are not supported by this driver\n");
- return -EINVAL;
- }
-
- ret = drm_bo_write_lock(&bm->bm_lock, 1, file_priv);
- if (ret)
- return ret;
-
- ret = -EINVAL;
- if (arg->magic != DRM_BO_INIT_MAGIC) {
- DRM_ERROR("You are using an old libdrm that is not compatible with\n"
- "\tthe kernel DRM module. Please upgrade your libdrm.\n");
- return -EINVAL;
- }
- if (arg->major != DRM_BO_INIT_MAJOR) {
- DRM_ERROR("libdrm and kernel DRM buffer object interface major\n"
- "\tversion don't match. Got %d, expected %d.\n",
- arg->major, DRM_BO_INIT_MAJOR);
- return -EINVAL;
- }
-
- mutex_lock(&dev->struct_mutex);
- if (!bm->initialized) {
- DRM_ERROR("DRM memory manager was not initialized.\n");
- goto out;
- }
- if (arg->mem_type == 0) {
- DRM_ERROR("System memory buffers already initialized.\n");
- goto out;
- }
- ret = drm_bo_init_mm(dev, arg->mem_type,
- arg->p_offset, arg->p_size, 0);
-
-out:
- mutex_unlock(&dev->struct_mutex);
- (void) drm_bo_write_unlock(&bm->bm_lock, file_priv);
-
- if (ret)
- return ret;
-
- return 0;
-}
-
-int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_mm_type_arg *arg = data;
- struct drm_buffer_manager *bm = &dev->bm;
- struct drm_bo_driver *driver = dev->driver->bo_driver;
- int ret;
-
- if (!driver) {
- DRM_ERROR("Buffer objects are not supported by this driver\n");
- return -EINVAL;
- }
-
- ret = drm_bo_write_lock(&bm->bm_lock, 0, file_priv);
- if (ret)
- return ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = -EINVAL;
- if (!bm->initialized) {
- DRM_ERROR("DRM memory manager was not initialized\n");
- goto out;
- }
- if (arg->mem_type == 0) {
- DRM_ERROR("No takedown for System memory buffers.\n");
- goto out;
- }
- ret = 0;
- if ((ret = drm_bo_clean_mm(dev, arg->mem_type, 0))) {
- if (ret == -EINVAL)
- DRM_ERROR("Memory manager type %d not clean. "
- "Delaying takedown\n", arg->mem_type);
- ret = 0;
- }
-out:
- mutex_unlock(&dev->struct_mutex);
- (void) drm_bo_write_unlock(&bm->bm_lock, file_priv);
-
- if (ret)
- return ret;
-
- return 0;
-}
-
-int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_mm_type_arg *arg = data;
- struct drm_bo_driver *driver = dev->driver->bo_driver;
- int ret;
-
- if (!driver) {
- DRM_ERROR("Buffer objects are not supported by this driver\n");
- return -EINVAL;
- }
-
- if (arg->lock_flags & DRM_BO_LOCK_IGNORE_NO_EVICT) {
- DRM_ERROR("Lock flag DRM_BO_LOCK_IGNORE_NO_EVICT not supported yet.\n");
- return -EINVAL;
- }
-
- if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) {
- ret = drm_bo_write_lock(&dev->bm.bm_lock, 1, file_priv);
- if (ret)
- return ret;
- }
-
- mutex_lock(&dev->struct_mutex);
- ret = drm_bo_lock_mm(dev, arg->mem_type);
- mutex_unlock(&dev->struct_mutex);
- if (ret) {
- (void) drm_bo_write_unlock(&dev->bm.bm_lock, file_priv);
- return ret;
- }
-
- return 0;
-}
-
-int drm_mm_unlock_ioctl(struct drm_device *dev,
- void *data,
- struct drm_file *file_priv)
-{
- struct drm_mm_type_arg *arg = data;
- struct drm_bo_driver *driver = dev->driver->bo_driver;
- int ret;
-
- if (!driver) {
- DRM_ERROR("Buffer objects are not supported by this driver\n");
- return -EINVAL;
- }
-
- if (arg->lock_flags & DRM_BO_LOCK_UNLOCK_BM) {
- ret = drm_bo_write_unlock(&dev->bm.bm_lock, file_priv);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-int drm_mm_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_mm_info_arg *arg = data;
- struct drm_buffer_manager *bm = &dev->bm;
- struct drm_bo_driver *driver = dev->driver->bo_driver;
- struct drm_mem_type_manager *man;
- int ret = 0;
- int mem_type = arg->mem_type;
-
- if (!driver) {
- DRM_ERROR("Buffer objects are not supported by this driver\n");
- return -EINVAL;
- }
-
- if (mem_type >= DRM_BO_MEM_TYPES) {
- DRM_ERROR("Illegal memory type %d\n", arg->mem_type);
- return -EINVAL;
- }
-
- mutex_lock(&dev->struct_mutex);
- if (!bm->initialized) {
- DRM_ERROR("DRM memory manager was not initialized\n");
- ret = -EINVAL;
- goto out;
- }
-
-
- man = &bm->man[arg->mem_type];
-
- arg->p_size = man->size;
-
-out:
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
-}
/*
* buffer object vm functions.
*/
@@ -2792,15 +2079,3 @@ static int drm_bo_setup_vm_locked(struct drm_buffer_object *bo)
return 0;
}
-
-int drm_bo_version_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_bo_version_arg *arg = (struct drm_bo_version_arg *)data;
-
- arg->major = DRM_BO_INIT_MAJOR;
- arg->minor = DRM_BO_INIT_MINOR;
- arg->patchlevel = DRM_BO_INIT_PATCH;
-
- return 0;
-}
diff --git a/linux-core/drm_bo_lock.c b/linux-core/drm_bo_lock.c
deleted file mode 100644
index 08b1c6be..00000000
--- a/linux-core/drm_bo_lock.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-/*
- * This file implements a simple replacement for the buffer manager use
- * of the heavyweight hardware lock.
- * The lock is a read-write lock. Taking it in read mode is fast, and
- * intended for in-kernel use only.
- * Taking it in write mode is slow.
- *
- * The write mode is used only when there is a need to block all
- * user-space processes from allocating a
- * new memory area.
- * Typical use in write mode is X server VT switching, and it's allowed
- * to leave kernel space with the write lock held. If a user-space process
- * dies while having the write-lock, it will be released during the file
- * descriptor release.
- *
- * The read lock is typically placed at the start of an IOCTL- or
- * user-space callable function that may end up allocating a memory area.
- * This includes setstatus, super-ioctls and no_pfn; the latter may move
- * unmappable regions to mappable. It's a bug to leave kernel space with the
- * read lock held.
- *
- * Both read- and write lock taking may be interruptible for low signal-delivery
- * latency. The locking functions will return -EAGAIN if interrupted by a
- * signal.
- *
- * Locking order: The lock should be taken BEFORE any kernel mutexes
- * or spinlocks.
- */
-
-#include "drmP.h"
-
-void drm_bo_init_lock(struct drm_bo_lock *lock)
-{
- DRM_INIT_WAITQUEUE(&lock->queue);
- atomic_set(&lock->write_lock_pending, 0);
- atomic_set(&lock->readers, 0);
-}
-
-void drm_bo_read_unlock(struct drm_bo_lock *lock)
-{
- if (atomic_dec_and_test(&lock->readers))
- wake_up_all(&lock->queue);
-}
-EXPORT_SYMBOL(drm_bo_read_unlock);
-
-int drm_bo_read_lock(struct drm_bo_lock *lock, int interruptible)
-{
- while (unlikely(atomic_read(&lock->write_lock_pending) != 0)) {
- int ret;
-
- if (!interruptible) {
- wait_event(lock->queue,
- atomic_read(&lock->write_lock_pending) == 0);
- continue;
- }
- ret = wait_event_interruptible
- (lock->queue, atomic_read(&lock->write_lock_pending) == 0);
- if (ret)
- return -EAGAIN;
- }
-
- while (unlikely(!atomic_add_unless(&lock->readers, 1, -1))) {
- int ret;
- if (!interruptible) {
- wait_event(lock->queue,
- atomic_read(&lock->readers) != -1);
- continue;
- }
- ret = wait_event_interruptible
- (lock->queue, atomic_read(&lock->readers) != -1);
- if (ret)
- return -EAGAIN;
- }
- return 0;
-}
-EXPORT_SYMBOL(drm_bo_read_lock);
-
-static int __drm_bo_write_unlock(struct drm_bo_lock *lock)
-{
- if (unlikely(atomic_cmpxchg(&lock->readers, -1, 0) != -1))
- return -EINVAL;
- wake_up_all(&lock->queue);
- return 0;
-}
-
-static void drm_bo_write_lock_remove(struct drm_file *file_priv,
- struct drm_user_object *item)
-{
- struct drm_bo_lock *lock = container_of(item, struct drm_bo_lock, base);
- int ret;
-
- ret = __drm_bo_write_unlock(lock);
- BUG_ON(ret);
-}
-
-int drm_bo_write_lock(struct drm_bo_lock *lock, int interruptible,
- struct drm_file *file_priv)
-{
- int ret = 0;
- struct drm_device *dev;
-
- atomic_inc(&lock->write_lock_pending);
-
- while (unlikely(atomic_cmpxchg(&lock->readers, 0, -1) != 0)) {
- if (!interruptible) {
- wait_event(lock->queue,
- atomic_read(&lock->readers) == 0);
- continue;
- }
- ret = wait_event_interruptible
- (lock->queue, atomic_read(&lock->readers) == 0);
-
- if (ret) {
- atomic_dec(&lock->write_lock_pending);
- wake_up_all(&lock->queue);
- return -EAGAIN;
- }
- }
-
- /*
- * Add a dummy user-object, the destructor of which will
- * make sure the lock is released if the client dies
- * while holding it.
- */
-
- if (atomic_dec_and_test(&lock->write_lock_pending))
- wake_up_all(&lock->queue);
- dev = file_priv->minor->dev;
- mutex_lock(&dev->struct_mutex);
- ret = drm_add_user_object(file_priv, &lock->base, 0);
- lock->base.remove = &drm_bo_write_lock_remove;
- lock->base.type = drm_lock_type;
- if (ret)
- (void)__drm_bo_write_unlock(lock);
-
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
-}
-
-int drm_bo_write_unlock(struct drm_bo_lock *lock, struct drm_file *file_priv)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_ref_object *ro;
-
- mutex_lock(&dev->struct_mutex);
-
- if (lock->base.owner != file_priv) {
- mutex_unlock(&dev->struct_mutex);
- return -EINVAL;
- }
- ro = drm_lookup_ref_object(file_priv, &lock->base, _DRM_REF_USE);
- BUG_ON(!ro);
- drm_remove_ref_object(file_priv, ro);
- lock->base.owner = NULL;
-
- mutex_unlock(&dev->struct_mutex);
- return 0;
-}
diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c
index e0d93606..ee1dc258 100644
--- a/linux-core/drm_crtc_helper.c
+++ b/linux-core/drm_crtc_helper.c
@@ -715,48 +715,4 @@ int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
}
EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
-/**
- * drm_get_buffer_object - find the buffer object for a given handle
- * @dev: DRM device
- * @bo: pointer to caller's buffer_object pointer
- * @handle: handle to lookup
- *
- * LOCKING:
- * Must take @dev's struct_mutex to protect buffer object lookup.
- *
- * Given @handle, lookup the buffer object in @dev and put it in the caller's
- * @bo pointer.
- *
- * RETURNS:
- * Zero on success, -EINVAL if the handle couldn't be found.
- */
-int drm_get_buffer_object(struct drm_device *dev, struct drm_buffer_object **bo, unsigned long handle)
-{
- struct drm_user_object *uo;
- struct drm_hash_item *hash;
- int ret;
-
- *bo = NULL;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm_ht_find_item(&dev->object_hash, handle, &hash);
- if (ret) {
- DRM_ERROR("Couldn't find handle.\n");
- ret = -EINVAL;
- goto out_err;
- }
-
- uo = drm_hash_entry(hash, struct drm_user_object, hash);
- if (uo->type != drm_buffer_type) {
- ret = -EINVAL;
- goto out_err;
- }
-
- *bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
- ret = 0;
-out_err:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-EXPORT_SYMBOL(drm_get_buffer_object);
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 9113fa54..2c3e29f0 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -146,36 +146,6 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER),
- DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
- DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl,
- DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_MM_LOCK, drm_mm_lock_ioctl,
- DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_MM_UNLOCK, drm_mm_unlock_ioctl,
- DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-
- DRM_IOCTL_DEF(DRM_IOCTL_FENCE_CREATE, drm_fence_create_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_FENCE_REFERENCE, drm_fence_reference_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_FENCE_UNREFERENCE, drm_fence_unreference_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_FENCE_SIGNALED, drm_fence_signaled_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_FENCE_FLUSH, drm_fence_flush_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_FENCE_WAIT, drm_fence_wait_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_FENCE_EMIT, drm_fence_emit_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_FENCE_BUFFERS, drm_fence_buffers_ioctl, DRM_AUTH),
-
- DRM_IOCTL_DEF(DRM_IOCTL_BO_CREATE, drm_bo_create_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_MAP, drm_bo_map_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_UNMAP, drm_bo_unmap_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_REFERENCE, drm_bo_reference_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_UNREFERENCE, drm_bo_unreference_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_SETSTATUS, drm_bo_setstatus_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_BO_VERSION, drm_bo_version_ioctl, 0),
-
- DRM_IOCTL_DEF(DRM_IOCTL_MM_INFO, drm_mm_info_ioctl, 0),
-
DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c
index 7c78e09f..7130d1b0 100644
--- a/linux-core/drm_fence.c
+++ b/linux-core/drm_fence.c
@@ -134,8 +134,8 @@ void drm_fence_handler(struct drm_device *dev, uint32_t fence_class,
if (new_type) {
fence->signaled_types |= new_type;
- DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n",
- fence->base.hash.key, fence->signaled_types);
+ DRM_DEBUG("Fence %p signaled 0x%08x\n",
+ fence, fence->signaled_types);
if (driver->needed_flush)
fc->pending_flush |= driver->needed_flush(fence);
@@ -147,8 +147,8 @@ void drm_fence_handler(struct drm_device *dev, uint32_t fence_class,
fc->waiting_types |= fence->waiting_types & ~fence->signaled_types;
if (!(fence->type & ~fence->signaled_types)) {
- DRM_DEBUG("Fence completely signaled 0x%08lx\n",
- fence->base.hash.key);
+ DRM_DEBUG("Fence completely signaled %p\n",
+ fence);
list_del_init(&fence->ring);
}
}
@@ -196,10 +196,9 @@ void drm_fence_usage_deref_locked(struct drm_fence_object **fence)
*fence = NULL;
if (atomic_dec_and_test(&tmp_fence->usage)) {
drm_fence_unring(dev, &tmp_fence->ring);
- DRM_DEBUG("Destroyed a fence object 0x%08lx\n",
- tmp_fence->base.hash.key);
+ DRM_DEBUG("Destroyed a fence object %p\n",
+ tmp_fence);
atomic_dec(&fm->count);
- BUG_ON(!list_empty(&tmp_fence->base.list));
drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
}
}
@@ -217,7 +216,6 @@ void drm_fence_usage_deref_unlocked(struct drm_fence_object **fence)
if (atomic_read(&tmp_fence->usage) == 0) {
drm_fence_unring(dev, &tmp_fence->ring);
atomic_dec(&fm->count);
- BUG_ON(!list_empty(&tmp_fence->base.list));
drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
}
mutex_unlock(&dev->struct_mutex);
@@ -244,15 +242,6 @@ void drm_fence_reference_unlocked(struct drm_fence_object **dst,
}
EXPORT_SYMBOL(drm_fence_reference_unlocked);
-static void drm_fence_object_destroy(struct drm_file *priv,
- struct drm_user_object *base)
-{
- struct drm_fence_object *fence =
- drm_user_object_entry(base, struct drm_fence_object, base);
-
- drm_fence_usage_deref_locked(&fence);
-}
-
int drm_fence_object_signaled(struct drm_fence_object *fence, uint32_t mask)
{
unsigned long flags;
@@ -477,7 +466,6 @@ static int drm_fence_object_init(struct drm_device *dev, uint32_t fence_class,
* Avoid hitting BUG() for kernel-only fence objects.
*/
- INIT_LIST_HEAD(&fence->base.list);
fence->fence_class = fence_class;
fence->type = type;
fence->signaled_types = 0;
@@ -493,26 +481,6 @@ static int drm_fence_object_init(struct drm_device *dev, uint32_t fence_class,
return ret;
}
-int drm_fence_add_user_object(struct drm_file *priv,
- struct drm_fence_object *fence, int shareable)
-{
- struct drm_device *dev = priv->minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm_add_user_object(priv, &fence->base, shareable);
- if (ret)
- goto out;
- atomic_inc(&fence->usage);
- fence->base.type = drm_fence_type;
- fence->base.remove = &drm_fence_object_destroy;
- DRM_DEBUG("Fence 0x%08lx created\n", fence->base.hash.key);
-out:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-EXPORT_SYMBOL(drm_fence_add_user_object);
-
int drm_fence_object_create(struct drm_device *dev, uint32_t fence_class,
uint32_t type, unsigned flags,
struct drm_fence_object **c_fence)
@@ -569,261 +537,7 @@ void drm_fence_manager_init(struct drm_device *dev)
write_unlock_irqrestore(&fm->lock, flags);
}
-void drm_fence_fill_arg(struct drm_fence_object *fence,
- struct drm_fence_arg *arg)
-{
- struct drm_device *dev = fence->dev;
- struct drm_fence_manager *fm = &dev->fm;
- unsigned long irq_flags;
-
- read_lock_irqsave(&fm->lock, irq_flags);
- arg->handle = fence->base.hash.key;
- arg->fence_class = fence->fence_class;
- arg->type = fence->type;
- arg->signaled = fence->signaled_types;
- arg->error = fence->error;
- arg->sequence = fence->sequence;
- read_unlock_irqrestore(&fm->lock, irq_flags);
-}
-EXPORT_SYMBOL(drm_fence_fill_arg);
-
void drm_fence_manager_takedown(struct drm_device *dev)
{
}
-struct drm_fence_object *drm_lookup_fence_object(struct drm_file *priv,
- uint32_t handle)
-{
- struct drm_device *dev = priv->minor->dev;
- struct drm_user_object *uo;
- struct drm_fence_object *fence;
-
- mutex_lock(&dev->struct_mutex);
- uo = drm_lookup_user_object(priv, handle);
- if (!uo || (uo->type != drm_fence_type)) {
- mutex_unlock(&dev->struct_mutex);
- return NULL;
- }
- fence = drm_fence_reference_locked(drm_user_object_entry(uo, struct drm_fence_object, base));
- mutex_unlock(&dev->struct_mutex);
- return fence;
-}
-
-int drm_fence_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- int ret;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_arg *arg = data;
- struct drm_fence_object *fence;
- ret = 0;
-
- if (!fm->initialized) {
- DRM_ERROR("The DRM driver does not support fencing.\n");
- return -EINVAL;
- }
-
- if (arg->flags & DRM_FENCE_FLAG_EMIT)
- LOCK_TEST_WITH_RETURN(dev, file_priv);
- ret = drm_fence_object_create(dev, arg->fence_class,
- arg->type, arg->flags, &fence);
- if (ret)
- return ret;
- ret = drm_fence_add_user_object(file_priv, fence,
- arg->flags &
- DRM_FENCE_FLAG_SHAREABLE);
- if (ret) {
- drm_fence_usage_deref_unlocked(&fence);
- return ret;
- }
-
- /*
- * usage > 0. No need to lock dev->struct_mutex;
- */
-
- arg->handle = fence->base.hash.key;
-
- drm_fence_fill_arg(fence, arg);
- drm_fence_usage_deref_unlocked(&fence);
-
- return ret;
-}
-
-int drm_fence_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- int ret;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_arg *arg = data;
- struct drm_fence_object *fence;
- struct drm_user_object *uo;
- ret = 0;
-
- if (!fm->initialized) {
- DRM_ERROR("The DRM driver does not support fencing.\n");
- return -EINVAL;
- }
-
- ret = drm_user_object_ref(file_priv, arg->handle, drm_fence_type, &uo);
- if (ret)
- return ret;
- fence = drm_lookup_fence_object(file_priv, arg->handle);
- drm_fence_fill_arg(fence, arg);
- drm_fence_usage_deref_unlocked(&fence);
-
- return ret;
-}
-
-
-int drm_fence_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- int ret;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_arg *arg = data;
- ret = 0;
-
- if (!fm->initialized) {
- DRM_ERROR("The DRM driver does not support fencing.\n");
- return -EINVAL;
- }
-
- return drm_user_object_unref(file_priv, arg->handle, drm_fence_type);
-}
-
-int drm_fence_signaled_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- int ret;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_arg *arg = data;
- struct drm_fence_object *fence;
- ret = 0;
-
- if (!fm->initialized) {
- DRM_ERROR("The DRM driver does not support fencing.\n");
- return -EINVAL;
- }
-
- fence = drm_lookup_fence_object(file_priv, arg->handle);
- if (!fence)
- return -EINVAL;
-
- drm_fence_fill_arg(fence, arg);
- drm_fence_usage_deref_unlocked(&fence);
-
- return ret;
-}
-
-int drm_fence_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- int ret;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_arg *arg = data;
- struct drm_fence_object *fence;
- ret = 0;
-
- if (!fm->initialized) {
- DRM_ERROR("The DRM driver does not support fencing.\n");
- return -EINVAL;
- }
-
- fence = drm_lookup_fence_object(file_priv, arg->handle);
- if (!fence)
- return -EINVAL;
- ret = drm_fence_object_flush(fence, arg->type);
-
- drm_fence_fill_arg(fence, arg);
- drm_fence_usage_deref_unlocked(&fence);
-
- return ret;
-}
-
-
-int drm_fence_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- int ret;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_arg *arg = data;
- struct drm_fence_object *fence;
- ret = 0;
-
- if (!fm->initialized) {
- DRM_ERROR("The DRM driver does not support fencing.\n");
- return -EINVAL;
- }
-
- fence = drm_lookup_fence_object(file_priv, arg->handle);
- if (!fence)
- return -EINVAL;
- ret = drm_fence_object_wait(fence,
- arg->flags & DRM_FENCE_FLAG_WAIT_LAZY,
- 0, arg->type);
-
- drm_fence_fill_arg(fence, arg);
- drm_fence_usage_deref_unlocked(&fence);
-
- return ret;
-}
-
-
-int drm_fence_emit_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- int ret;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_arg *arg = data;
- struct drm_fence_object *fence;
- ret = 0;
-
- if (!fm->initialized) {
- DRM_ERROR("The DRM driver does not support fencing.\n");
- return -EINVAL;
- }
-
- LOCK_TEST_WITH_RETURN(dev, file_priv);
- fence = drm_lookup_fence_object(file_priv, arg->handle);
- if (!fence)
- return -EINVAL;
- ret = drm_fence_object_emit(fence, arg->flags, arg->fence_class,
- arg->type);
-
- drm_fence_fill_arg(fence, arg);
- drm_fence_usage_deref_unlocked(&fence);
-
- return ret;
-}
-
-int drm_fence_buffers_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- int ret;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_arg *arg = data;
- struct drm_fence_object *fence;
- ret = 0;
-
- if (!fm->initialized) {
- DRM_ERROR("The DRM driver does not support fencing.\n");
- return -EINVAL;
- }
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized\n");
- return -EINVAL;
- }
- LOCK_TEST_WITH_RETURN(dev, file_priv);
- ret = drm_fence_buffer_objects(dev, NULL, arg->flags,
- NULL, &fence);
- if (ret)
- return ret;
-
- if (!(arg->flags & DRM_FENCE_FLAG_NO_USER)) {
- ret = drm_fence_add_user_object(file_priv, fence,
- arg->flags &
- DRM_FENCE_FLAG_SHAREABLE);
- if (ret)
- return ret;
- }
-
- arg->handle = fence->base.hash.key;
-
- drm_fence_fill_arg(fence, arg);
- drm_fence_usage_deref_unlocked(&fence);
-
- return ret;
-}
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
index 3b3a0a3c..8eb20b47 100644
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -221,7 +221,6 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
int minor_id = iminor(inode);
struct drm_file *priv;
int ret;
- int i, j;
if (filp->f_flags & O_EXCL)
return -EBUSY; /* No exclusive opens */
@@ -246,22 +245,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
priv->lock_count = 0;
INIT_LIST_HEAD(&priv->lhead);
- INIT_LIST_HEAD(&priv->refd_objects);
INIT_LIST_HEAD(&priv->fbs);
- for (i = 0; i < _DRM_NO_REF_TYPES; ++i) {
- ret = drm_ht_create(&priv->refd_object_hash[i],
- DRM_FILE_HASH_ORDER);
- if (ret)
- break;
- }
-
- if (ret) {
- for (j = 0; j < i; ++j)
- drm_ht_remove(&priv->refd_object_hash[j]);
- goto out_free;
- }
-
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_open(dev, priv);
@@ -346,33 +331,6 @@ int drm_fasync(int fd, struct file *filp, int on)
}
EXPORT_SYMBOL(drm_fasync);
-static void drm_object_release(struct file *filp)
-{
- struct drm_file *priv = filp->private_data;
- struct list_head *head;
- struct drm_ref_object *ref_object;
- int i;
-
- /*
- * Free leftover ref objects created by me. Note that we cannot use
- * list_for_each() here, as the struct_mutex may be temporarily
- * released by the remove_() functions, and thus the lists may be
- * altered.
- * Also, a drm_remove_ref_object() will not remove it
- * from the list unless its refcount is 1.
- */
-
- head = &priv->refd_objects;
- while (head->next != head) {
- ref_object = list_entry(head->next, struct drm_ref_object, list);
- drm_remove_ref_object(priv, ref_object);
- head = &priv->refd_objects;
- }
-
- for (i = 0; i < _DRM_NO_REF_TYPES; ++i)
- drm_ht_remove(&priv->refd_object_hash[i]);
-}
-
/**
* Release file.
*
@@ -512,7 +470,6 @@ int drm_release(struct inode *inode, struct file *filp)
file_priv->is_master = 0;
mutex_lock(&dev->struct_mutex);
- drm_object_release(filp);
list_del(&file_priv->lhead);
diff --git a/linux-core/drm_object.c b/linux-core/drm_object.c
deleted file mode 100644
index 2994b716..00000000
--- a/linux-core/drm_object.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-#include "drmP.h"
-
-int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item,
- int shareable)
-{
- struct drm_device *dev = priv->minor->dev;
- int ret;
-
- DRM_ASSERT_LOCKED(&dev->struct_mutex);
-
- /* The refcount will be bumped to 1 when we add the ref object below. */
- atomic_set(&item->refcount, 0);
- item->shareable = shareable;
- item->owner = priv;
-
- ret = drm_ht_just_insert_please(&dev->object_hash, &item->hash,
- (unsigned long)item, 31, 0, 0);
- if (ret)
- return ret;
-
- ret = drm_add_ref_object(priv, item, _DRM_REF_USE);
- if (ret)
- ret = drm_ht_remove_item(&dev->object_hash, &item->hash);
-
- return ret;
-}
-EXPORT_SYMBOL(drm_add_user_object);
-
-struct drm_user_object *drm_lookup_user_object(struct drm_file *priv, uint32_t key)
-{
- struct drm_device *dev = priv->minor->dev;
- struct drm_hash_item *hash;
- int ret;
- struct drm_user_object *item;
-
- DRM_ASSERT_LOCKED(&dev->struct_mutex);
-
- ret = drm_ht_find_item(&dev->object_hash, key, &hash);
- if (ret)
- return NULL;
-
- item = drm_hash_entry(hash, struct drm_user_object, hash);
-
- if (priv != item->owner) {
- struct drm_open_hash *ht = &priv->refd_object_hash[_DRM_REF_USE];
- ret = drm_ht_find_item(ht, (unsigned long)item, &hash);
- if (ret) {
- DRM_ERROR("Object not registered for usage\n");
- return NULL;
- }
- }
- return item;
-}
-EXPORT_SYMBOL(drm_lookup_user_object);
-
-static void drm_deref_user_object(struct drm_file *priv, struct drm_user_object *item)
-{
- struct drm_device *dev = priv->minor->dev;
- int ret;
-
- if (atomic_dec_and_test(&item->refcount)) {
- ret = drm_ht_remove_item(&dev->object_hash, &item->hash);
- BUG_ON(ret);
- item->remove(priv, item);
- }
-}
-
-static int drm_object_ref_action(struct drm_file *priv, struct drm_user_object *ro,
- enum drm_ref_type action)
-{
- int ret = 0;
-
- switch (action) {
- case _DRM_REF_USE:
- atomic_inc(&ro->refcount);
- break;
- default:
- if (!ro->ref_struct_locked) {
- break;
- } else {
- ro->ref_struct_locked(priv, ro, action);
- }
- }
- return ret;
-}
-
-int drm_add_ref_object(struct drm_file *priv, struct drm_user_object *referenced_object,
- enum drm_ref_type ref_action)
-{
- int ret = 0;
- struct drm_ref_object *item;
- struct drm_open_hash *ht = &priv->refd_object_hash[ref_action];
-
- DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
- if (!referenced_object->shareable && priv != referenced_object->owner) {
- DRM_ERROR("Not allowed to reference this object\n");
- return -EINVAL;
- }
-
- /*
- * If this is not a usage reference, Check that usage has been registered
- * first. Otherwise strange things may happen on destruction.
- */
-
- if ((ref_action != _DRM_REF_USE) && priv != referenced_object->owner) {
- item =
- drm_lookup_ref_object(priv, referenced_object,
- _DRM_REF_USE);
- if (!item) {
- DRM_ERROR
- ("Object not registered for usage by this client\n");
- return -EINVAL;
- }
- }
-
- if (NULL !=
- (item =
- drm_lookup_ref_object(priv, referenced_object, ref_action))) {
- atomic_inc(&item->refcount);
- return drm_object_ref_action(priv, referenced_object,
- ref_action);
- }
-
- item = drm_ctl_calloc(1, sizeof(*item), DRM_MEM_OBJECTS);
- if (item == NULL) {
- DRM_ERROR("Could not allocate reference object\n");
- return -ENOMEM;
- }
-
- atomic_set(&item->refcount, 1);
- item->hash.key = (unsigned long)referenced_object;
- ret = drm_ht_insert_item(ht, &item->hash);
- item->unref_action = ref_action;
-
- if (ret)
- goto out;
-
- list_add(&item->list, &priv->refd_objects);
- ret = drm_object_ref_action(priv, referenced_object, ref_action);
-out:
- return ret;
-}
-
-struct drm_ref_object *drm_lookup_ref_object(struct drm_file *priv,
- struct drm_user_object *referenced_object,
- enum drm_ref_type ref_action)
-{
- struct drm_hash_item *hash;
- int ret;
-
- DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
- ret = drm_ht_find_item(&priv->refd_object_hash[ref_action],
- (unsigned long)referenced_object, &hash);
- if (ret)
- return NULL;
-
- return drm_hash_entry(hash, struct drm_ref_object, hash);
-}
-EXPORT_SYMBOL(drm_lookup_ref_object);
-
-static void drm_remove_other_references(struct drm_file *priv,
- struct drm_user_object *ro)
-{
- int i;
- struct drm_open_hash *ht;
- struct drm_hash_item *hash;
- struct drm_ref_object *item;
-
- for (i = _DRM_REF_USE + 1; i < _DRM_NO_REF_TYPES; ++i) {
- ht = &priv->refd_object_hash[i];
- while (!drm_ht_find_item(ht, (unsigned long)ro, &hash)) {
- item = drm_hash_entry(hash, struct drm_ref_object, hash);
- drm_remove_ref_object(priv, item);
- }
- }
-}
-
-void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item)
-{
- int ret;
- struct drm_user_object *user_object = (struct drm_user_object *) item->hash.key;
- struct drm_open_hash *ht = &priv->refd_object_hash[item->unref_action];
- enum drm_ref_type unref_action;
-
- DRM_ASSERT_LOCKED(&priv->minor->dev->struct_mutex);
- unref_action = item->unref_action;
- if (atomic_dec_and_test(&item->refcount)) {
- ret = drm_ht_remove_item(ht, &item->hash);
- BUG_ON(ret);
- list_del_init(&item->list);
- if (unref_action == _DRM_REF_USE)
- drm_remove_other_references(priv, user_object);
- drm_ctl_free(item, sizeof(*item), DRM_MEM_OBJECTS);
- }
-
- switch (unref_action) {
- case _DRM_REF_USE:
- drm_deref_user_object(priv, user_object);
- break;
- default:
- BUG_ON(!user_object->unref);
- user_object->unref(priv, user_object, unref_action);
- break;
- }
-
-}
-EXPORT_SYMBOL(drm_remove_ref_object);
-
-int drm_user_object_ref(struct drm_file *priv, uint32_t user_token,
- enum drm_object_type type, struct drm_user_object **object)
-{
- struct drm_device *dev = priv->minor->dev;
- struct drm_user_object *uo;
- struct drm_hash_item *hash;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm_ht_find_item(&dev->object_hash, user_token, &hash);
- if (ret) {
- DRM_ERROR("Could not find user object to reference.\n");
- goto out_err;
- }
- uo = drm_hash_entry(hash, struct drm_user_object, hash);
- if (uo->type != type) {
- ret = -EINVAL;
- goto out_err;
- }
- ret = drm_add_ref_object(priv, uo, _DRM_REF_USE);
- if (ret)
- goto out_err;
- mutex_unlock(&dev->struct_mutex);
- *object = uo;
- return 0;
-out_err:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-int drm_user_object_unref(struct drm_file *priv, uint32_t user_token,
- enum drm_object_type type)
-{
- struct drm_device *dev = priv->minor->dev;
- struct drm_user_object *uo;
- struct drm_ref_object *ro;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- uo = drm_lookup_user_object(priv, user_token);
- if (!uo || (uo->type != type)) {
- ret = -EINVAL;
- goto out_err;
- }
- ro = drm_lookup_ref_object(priv, uo, _DRM_REF_USE);
- if (!ro) {
- ret = -EINVAL;
- goto out_err;
- }
- drm_remove_ref_object(priv, ro);
- mutex_unlock(&dev->struct_mutex);
- return 0;
-out_err:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h
index 96cfc113..032687f7 100644
--- a/linux-core/drm_objects.h
+++ b/linux-core/drm_objects.h
@@ -34,110 +34,201 @@
struct drm_device;
struct drm_bo_mem_reg;
-/***************************************************
- * User space objects. (drm_object.c)
- */
-
-#define drm_user_object_entry(_ptr, _type, _member) container_of(_ptr, _type, _member)
-
-enum drm_object_type {
- drm_fence_type,
- drm_buffer_type,
- drm_lock_type,
- /*
- * Add other user space object types here.
- */
- drm_driver_type0 = 256,
- drm_driver_type1,
- drm_driver_type2,
- drm_driver_type3,
- drm_driver_type4
+#define DRM_FENCE_FLAG_EMIT 0x00000001
+#define DRM_FENCE_FLAG_SHAREABLE 0x00000002
+/**
+ * On hardware with no interrupt events for operation completion,
+ * indicates that the kernel should sleep while waiting for any blocking
+ * operation to complete rather than spinning.
+ *
+ * Has no effect otherwise.
+ */
+#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004
+#define DRM_FENCE_FLAG_NO_USER 0x00000010
+
+/* Reserved for driver use */
+#define DRM_FENCE_MASK_DRIVER 0xFF000000
+
+#define DRM_FENCE_TYPE_EXE 0x00000001
+
+struct drm_fence_arg {
+ unsigned int handle;
+ unsigned int fence_class;
+ unsigned int type;
+ unsigned int flags;
+ unsigned int signaled;
+ unsigned int error;
+ unsigned int sequence;
+ unsigned int pad64;
+ uint64_t expand_pad[2]; /*Future expansion */
};
+/* Buffer permissions, referring to how the GPU uses the buffers.
+ * these translate to fence types used for the buffers.
+ * Typically a texture buffer is read, A destination buffer is write and
+ * a command (batch-) buffer is exe. Can be or-ed together.
+ */
+
+#define DRM_BO_FLAG_READ (1ULL << 0)
+#define DRM_BO_FLAG_WRITE (1ULL << 1)
+#define DRM_BO_FLAG_EXE (1ULL << 2)
+
/*
- * A user object is a structure that helps the drm give out user handles
- * to kernel internal objects and to keep track of these objects so that
- * they can be destroyed, for example when the user space process exits.
- * Designed to be accessible using a user space 32-bit handle.
- */
-
-struct drm_user_object {
- struct drm_hash_item hash;
- struct list_head list;
- enum drm_object_type type;
- atomic_t refcount;
- int shareable;
- struct drm_file *owner;
- void (*ref_struct_locked) (struct drm_file *priv,
- struct drm_user_object *obj,
- enum drm_ref_type ref_action);
- void (*unref) (struct drm_file *priv, struct drm_user_object *obj,
- enum drm_ref_type unref_action);
- void (*remove) (struct drm_file *priv, struct drm_user_object *obj);
-};
+ * All of the bits related to access mode
+ */
+#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE)
+/*
+ * Status flags. Can be read to determine the actual state of a buffer.
+ * Can also be set in the buffer mask before validation.
+ */
/*
- * A ref object is a structure which is used to
- * keep track of references to user objects and to keep track of these
- * references so that they can be destroyed for example when the user space
- * process exits. Designed to be accessible using a pointer to the _user_ object.
+ * Mask: Never evict this buffer. Not even with force. This type of buffer is only
+ * available to root and must be manually removed before buffer manager shutdown
+ * or lock.
+ * Flags: Acknowledge
*/
+#define DRM_BO_FLAG_NO_EVICT (1ULL << 4)
-struct drm_ref_object {
- struct drm_hash_item hash;
- struct list_head list;
- atomic_t refcount;
- enum drm_ref_type unref_action;
-};
+/*
+ * Mask: Require that the buffer is placed in mappable memory when validated.
+ * If not set the buffer may or may not be in mappable memory when validated.
+ * Flags: If set, the buffer is in mappable memory.
+ */
+#define DRM_BO_FLAG_MAPPABLE (1ULL << 5)
-/**
- * Must be called with the struct_mutex held.
+/* Mask: The buffer should be shareable with other processes.
+ * Flags: The buffer is shareable with other processes.
*/
+#define DRM_BO_FLAG_SHAREABLE (1ULL << 6)
-extern int drm_add_user_object(struct drm_file *priv, struct drm_user_object *item,
- int shareable);
-/**
- * Must be called with the struct_mutex held.
+/* Mask: If set, place the buffer in cache-coherent memory if available.
+ * If clear, never place the buffer in cache coherent memory if validated.
+ * Flags: The buffer is currently in cache-coherent memory.
+ */
+#define DRM_BO_FLAG_CACHED (1ULL << 7)
+
+/* Mask: Make sure that every time this buffer is validated,
+ * it ends up on the same location provided that the memory mask is the same.
+ * The buffer will also not be evicted when claiming space for
+ * other buffers. Basically a pinned buffer but it may be thrown out as
+ * part of buffer manager shutdown or locking.
+ * Flags: Acknowledge.
+ */
+#define DRM_BO_FLAG_NO_MOVE (1ULL << 8)
+
+/* Mask: Make sure the buffer is in cached memory when mapped. In conjunction
+ * with DRM_BO_FLAG_CACHED it also allows the buffer to be bound into the GART
+ * with unsnooped PTEs instead of snooped, by using chipset-specific cache
+ * flushing at bind time. A better name might be DRM_BO_FLAG_TT_UNSNOOPED,
+ * as the eviction to local memory (TTM unbind) on map is just a side effect
+ * to prevent aggressive cache prefetch from the GPU disturbing the cache
+ * management that the DRM is doing.
+ *
+ * Flags: Acknowledge.
+ * Buffers allocated with this flag should not be used for suballocators
+ * This type may have issues on CPUs with over-aggressive caching
+ * http://marc.info/?l=linux-kernel&m=102376926732464&w=2
*/
+#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19)
-extern struct drm_user_object *drm_lookup_user_object(struct drm_file *priv,
- uint32_t key);
+
+/* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set.
+ * Flags: Acknowledge.
+ */
+#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13)
+
+/*
+ * Mask: Force DRM_BO_FLAG_MAPPABLE flag strictly also if it is clear.
+ * Flags: Acknowledge.
+ */
+#define DRM_BO_FLAG_FORCE_MAPPABLE (1ULL << 14)
+#define DRM_BO_FLAG_TILE (1ULL << 15)
/*
- * Must be called with the struct_mutex held. May temporarily release it.
+ * Memory type flags that can be or'ed together in the mask, but only
+ * one appears in flags.
*/
-extern int drm_add_ref_object(struct drm_file *priv,
- struct drm_user_object *referenced_object,
- enum drm_ref_type ref_action);
+/* System memory */
+#define DRM_BO_FLAG_MEM_LOCAL (1ULL << 24)
+/* Translation table memory */
+#define DRM_BO_FLAG_MEM_TT (1ULL << 25)
+/* Vram memory */
+#define DRM_BO_FLAG_MEM_VRAM (1ULL << 26)
+/* Up to the driver to define. */
+#define DRM_BO_FLAG_MEM_PRIV0 (1ULL << 27)
+#define DRM_BO_FLAG_MEM_PRIV1 (1ULL << 28)
+#define DRM_BO_FLAG_MEM_PRIV2 (1ULL << 29)
+#define DRM_BO_FLAG_MEM_PRIV3 (1ULL << 30)
+#define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31)
+/* We can add more of these now with a 64-bit flag type */
/*
- * Must be called with the struct_mutex held.
+ * This is a mask covering all of the memory type flags; easier to just
+ * use a single constant than a bunch of | values. It covers
+ * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4
*/
+#define DRM_BO_MASK_MEM 0x00000000FF000000ULL
+/*
+ * This adds all of the CPU-mapping options in with the memory
+ * type to label all bits which change how the page gets mapped
+ */
+#define DRM_BO_MASK_MEMTYPE (DRM_BO_MASK_MEM | \
+ DRM_BO_FLAG_CACHED_MAPPED | \
+ DRM_BO_FLAG_CACHED | \
+ DRM_BO_FLAG_MAPPABLE)
+
+/* Driver-private flags */
+#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL
-struct drm_ref_object *drm_lookup_ref_object(struct drm_file *priv,
- struct drm_user_object *referenced_object,
- enum drm_ref_type ref_action);
/*
- * Must be called with the struct_mutex held.
- * If "item" has been obtained by a call to drm_lookup_ref_object. You may not
- * release the struct_mutex before calling drm_remove_ref_object.
- * This function may temporarily release the struct_mutex.
+ * Don't block on validate and map. Instead, return EBUSY.
+ */
+#define DRM_BO_HINT_DONT_BLOCK 0x00000002
+/*
+ * Don't place this buffer on the unfenced list. This means
+ * that the buffer will not end up having a fence associated
+ * with it as a result of this operation
*/
+#define DRM_BO_HINT_DONT_FENCE 0x00000004
+/**
+ * On hardware with no interrupt events for operation completion,
+ * indicates that the kernel should sleep while waiting for any blocking
+ * operation to complete rather than spinning.
+ *
+ * Has no effect otherwise.
+ */
+#define DRM_BO_HINT_WAIT_LAZY 0x00000008
+/*
+ * The client has compute relocations refering to this buffer using the
+ * offset in the presumed_offset field. If that offset ends up matching
+ * where this buffer lands, the kernel is free to skip executing those
+ * relocations
+ */
+#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010
+
+
+#define DRM_BO_MEM_LOCAL 0
+#define DRM_BO_MEM_TT 1
+#define DRM_BO_MEM_VRAM 2
+#define DRM_BO_MEM_PRIV0 3
+#define DRM_BO_MEM_PRIV1 4
+#define DRM_BO_MEM_PRIV2 5
+#define DRM_BO_MEM_PRIV3 6
+#define DRM_BO_MEM_PRIV4 7
+
+#define DRM_BO_MEM_TYPES 8 /* For now. */
+
+#define DRM_BO_LOCK_UNLOCK_BM (1 << 0)
+#define DRM_BO_LOCK_IGNORE_NO_EVICT (1 << 1)
-extern void drm_remove_ref_object(struct drm_file *priv, struct drm_ref_object *item);
-extern int drm_user_object_ref(struct drm_file *priv, uint32_t user_token,
- enum drm_object_type type,
- struct drm_user_object **object);
-extern int drm_user_object_unref(struct drm_file *priv, uint32_t user_token,
- enum drm_object_type type);
/***************************************************
* Fence objects. (drm_fence.c)
*/
struct drm_fence_object {
- struct drm_user_object base;
struct drm_device *dev;
atomic_t usage;
@@ -470,7 +561,6 @@ enum drm_bo_type {
struct drm_buffer_object {
struct drm_device *dev;
- struct drm_user_object base;
/*
* If there is a possibility that the usage variable is zero,
@@ -546,7 +636,7 @@ struct drm_mem_type_manager {
};
struct drm_bo_lock {
- struct drm_user_object base;
+ // struct drm_user_object base;
wait_queue_head_t queue;
atomic_t write_lock_pending;
atomic_t readers;
@@ -655,22 +745,10 @@ struct drm_bo_driver {
/*
* buffer objects (drm_bo.c)
*/
-extern int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+int drm_bo_do_validate(struct drm_buffer_object *bo,
+ uint64_t flags, uint64_t mask, uint32_t hint,
+ uint32_t fence_class);
extern int drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo, int pin);
-extern int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_setstatus_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_mm_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int drm_bo_version_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int drm_bo_driver_finish(struct drm_device *dev);
extern int drm_bo_driver_init(struct drm_device *dev);
extern int drm_bo_pci_offset(struct drm_device *dev,
@@ -707,18 +785,9 @@ extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type, int kern_c
extern int drm_bo_init_mm(struct drm_device *dev, unsigned type,
unsigned long p_offset, unsigned long p_size,
int kern_init);
-extern int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle,
- uint64_t flags, uint64_t mask, uint32_t hint,
- uint32_t fence_class,
- struct drm_bo_info_rep *rep,
- struct drm_buffer_object **bo_rep);
extern struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file *file_priv,
uint32_t handle,
int check_owner);
-extern int drm_bo_do_validate(struct drm_buffer_object *bo,
- uint64_t flags, uint64_t mask, uint32_t hint,
- uint32_t fence_class,
- struct drm_bo_info_rep *rep);
extern int drm_bo_evict_cached(struct drm_buffer_object *bo);
extern void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo);
@@ -766,8 +835,6 @@ extern int drm_bo_pfn_prot(struct drm_buffer_object *bo,
unsigned long dst_offset,
unsigned long *pfn,
pgprot_t *prot);
-extern void drm_bo_fill_rep_arg(struct drm_buffer_object *bo,
- struct drm_bo_info_rep *rep);
/*
diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c
index 80a8ff5d..b58a1ada 100644
--- a/linux-core/drm_ttm.c
+++ b/linux-core/drm_ttm.c
@@ -72,7 +72,7 @@ void drm_ttm_cache_flush(struct page *pages[], unsigned long num_pages)
return;
}
#endif
- if (on_each_cpu(drm_ttm_ipi_handler, NULL, 1, 1) != 0)
+ if (on_each_cpu(drm_ttm_ipi_handler, NULL,1) != 0)
DRM_ERROR("Timed out waiting for drm cache flush.\n");
}
EXPORT_SYMBOL(drm_ttm_cache_flush);
diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c
deleted file mode 100644
index 4224b737..00000000
--- a/linux-core/i915_buffer.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-#include "drmP.h"
-#include "i915_drm.h"
-#include "i915_drv.h"
-
-struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev)
-{
- return drm_agp_init_ttm(dev);
-}
-
-int i915_fence_type(struct drm_buffer_object *bo,
- uint32_t *fclass,
- uint32_t *type)
-{
- if (bo->mem.proposed_flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE))
- *type = 3;
- else
- *type = 1;
- return 0;
-}
-
-int i915_invalidate_caches(struct drm_device *dev, uint64_t flags)
-{
- /*
- * FIXME: Only emit once per batchbuffer submission.
- */
-
- uint32_t flush_cmd = MI_NO_WRITE_FLUSH;
-
- if (flags & DRM_BO_FLAG_READ)
- flush_cmd |= MI_READ_FLUSH;
- if (flags & DRM_BO_FLAG_EXE)
- flush_cmd |= MI_EXE_FLUSH;
-
- return i915_emit_mi_flush(dev, flush_cmd);
-}
-
-int i915_init_mem_type(struct drm_device *dev, uint32_t type,
- struct drm_mem_type_manager *man)
-{
- switch (type) {
- case DRM_BO_MEM_LOCAL:
- man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
- _DRM_FLAG_MEMTYPE_CACHED;
- man->drm_bus_maptype = 0;
- man->gpu_offset = 0;
- break;
- case DRM_BO_MEM_TT:
- if (!(drm_core_has_AGP(dev) && dev->agp)) {
- DRM_ERROR("AGP is not enabled for memory type %u\n",
- (unsigned)type);
- return -EINVAL;
- }
- man->io_offset = dev->agp->agp_info.aper_base;
- man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024;
- man->io_addr = NULL;
- man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
- _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP;
- man->drm_bus_maptype = _DRM_AGP;
- man->gpu_offset = 0;
- break;
- case DRM_BO_MEM_VRAM:
- if (!(drm_core_has_AGP(dev) && dev->agp)) {
- DRM_ERROR("AGP is not enabled for memory type %u\n",
- (unsigned)type);
- return -EINVAL;
- }
- man->io_offset = dev->agp->agp_info.aper_base;
- man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024;
- man->io_addr = NULL;
- man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE |
- _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_NEEDS_IOREMAP;
- man->drm_bus_maptype = _DRM_AGP;
- man->gpu_offset = 0;
- break;
- case DRM_BO_MEM_PRIV0: /* for OS preallocated space */
- DRM_ERROR("PRIV0 not used yet.\n");
- break;
- default:
- DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * i915_evict_flags:
- *
- * @bo: the buffer object to be evicted
- *
- * Return the bo flags for a buffer which is not mapped to the hardware.
- * These will be placed in proposed_flags so that when the move is
- * finished, they'll end up in bo->mem.flags
- */
-uint64_t i915_evict_flags(struct drm_buffer_object *bo)
-{
- switch (bo->mem.mem_type) {
- case DRM_BO_MEM_LOCAL:
- case DRM_BO_MEM_TT:
- return DRM_BO_FLAG_MEM_LOCAL;
- default:
- return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED;
- }
-}
-
-#if 0 /* See comment below */
-
-static void i915_emit_copy_blit(struct drm_device * dev,
- uint32_t src_offset,
- uint32_t dst_offset,
- uint32_t pages, int direction)
-{
- uint32_t cur_pages;
- uint32_t stride = PAGE_SIZE;
- struct drm_i915_private *dev_priv = dev->dev_private;
- RING_LOCALS;
-
- if (!dev_priv)
- return;
-
- i915_kernel_lost_context(dev);
- while (pages > 0) {
- cur_pages = pages;
- if (cur_pages > 2048)
- cur_pages = 2048;
- pages -= cur_pages;
-
- BEGIN_LP_RING(6);
- OUT_RING(SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
- OUT_RING((stride & 0xffff) | (0xcc << 16) | (1 << 24) |
- (1 << 25) | (direction ? (1 << 30) : 0));
- OUT_RING((cur_pages << 16) | PAGE_SIZE);
- OUT_RING(dst_offset);
- OUT_RING(stride & 0xffff);
- OUT_RING(src_offset);
- ADVANCE_LP_RING();
- }
- return;
-}
-
-static int i915_move_blit(struct drm_buffer_object * bo,
- int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
-{
- struct drm_bo_mem_reg *old_mem = &bo->mem;
- int dir = 0;
-
- if ((old_mem->mem_type == new_mem->mem_type) &&
- (new_mem->mm_node->start <
- old_mem->mm_node->start + old_mem->mm_node->size)) {
- dir = 1;
- }
-
- i915_emit_copy_blit(bo->dev,
- old_mem->mm_node->start << PAGE_SHIFT,
- new_mem->mm_node->start << PAGE_SHIFT,
- new_mem->num_pages, dir);
-
- i915_emit_mi_flush(bo->dev, MI_READ_FLUSH | MI_EXE_FLUSH);
-
- return drm_bo_move_accel_cleanup(bo, evict, no_wait, 0,
- DRM_FENCE_TYPE_EXE |
- DRM_I915_FENCE_TYPE_RW,
- DRM_I915_FENCE_FLAG_FLUSHED, new_mem);
-}
-
-/*
- * Flip destination ttm into cached-coherent AGP,
- * then blit and subsequently move out again.
- */
-
-static int i915_move_flip(struct drm_buffer_object * bo,
- int evict, int no_wait, struct drm_bo_mem_reg * new_mem)
-{
- struct drm_device *dev = bo->dev;
- struct drm_bo_mem_reg tmp_mem;
- int ret;
-
- tmp_mem = *new_mem;
- tmp_mem.mm_node = NULL;
- tmp_mem.mask = DRM_BO_FLAG_MEM_TT |
- DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING;
-
- ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
- if (ret)
- return ret;
-
- ret = drm_bind_ttm(bo->ttm, &tmp_mem);
- if (ret)
- goto out_cleanup;
-
- ret = i915_move_blit(bo, 1, no_wait, &tmp_mem);
- if (ret)
- goto out_cleanup;
-
- ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem);
-out_cleanup:
- if (tmp_mem.mm_node) {
- mutex_lock(&dev->struct_mutex);
- if (tmp_mem.mm_node != bo->pinned_node)
- drm_mm_put_block(tmp_mem.mm_node);
- tmp_mem.mm_node = NULL;
- mutex_unlock(&dev->struct_mutex);
- }
- return ret;
-}
-
-#endif
-
-/*
- * Disable i915_move_flip for now, since we can't guarantee that the hardware
- * lock is held here. To re-enable we need to make sure either
- * a) The X server is using DRM to submit commands to the ring, or
- * b) DRM can use the HP ring for these blits. This means i915 needs to
- * implement a new ring submission mechanism and fence class.
- */
-int i915_move(struct drm_buffer_object *bo,
- int evict, int no_wait, struct drm_bo_mem_reg *new_mem)
-{
- struct drm_bo_mem_reg *old_mem = &bo->mem;
-
- if (old_mem->mem_type == DRM_BO_MEM_LOCAL) {
- return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
- } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) {
- if (1) /*i915_move_flip(bo, evict, no_wait, new_mem)*/
- return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
- } else {
- if (1) /*i915_move_blit(bo, evict, no_wait, new_mem)*/
- return drm_bo_move_memcpy(bo, evict, no_wait, new_mem);
- }
- return 0;
-}
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-static inline void clflush(volatile void *__p)
-{
- asm volatile("clflush %0" : "+m" (*(char __force *)__p));
-}
-#endif
-
-static inline void drm_cache_flush_addr(void *virt)
-{
-#ifdef cpu_has_clflush
- int i;
-
- for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
- clflush(virt+i);
-#endif
-}
-
-static inline void drm_cache_flush_page(struct page *p)
-{
- drm_cache_flush_addr(page_address(p));
-}
-
-void i915_flush_ttm(struct drm_ttm *ttm)
-{
- int i;
-
- if (!ttm)
- return;
-
- DRM_MEMORYBARRIER();
-
-#ifdef CONFIG_X86_32
-#ifndef cpu_has_clflush
-#define cpu_has_clflush 0
-#endif
- /* Hopefully nobody has built an x86-64 processor without clflush */
- if (!cpu_has_clflush) {
- wbinvd();
- DRM_MEMORYBARRIER();
- return;
- }
-#endif
-
- for (i = ttm->num_pages - 1; i >= 0; i--)
- drm_cache_flush_page(drm_ttm_get_page(ttm, i));
-
- DRM_MEMORYBARRIER();
-}
diff --git a/linux-core/i915_execbuf.c b/linux-core/i915_execbuf.c
deleted file mode 100644
index 932882dd..00000000
--- a/linux-core/i915_execbuf.c
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- * Copyright 2003-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- * Dave Airlie
- * Keith Packard
- * ... ?
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
-#include "i915_drv.h"
-
-#if DRM_DEBUG_CODE
-#define DRM_DEBUG_RELOCATION (drm_debug != 0)
-#else
-#define DRM_DEBUG_RELOCATION 0
-#endif
-
-enum i915_buf_idle {
- I915_RELOC_UNCHECKED,
- I915_RELOC_IDLE,
- I915_RELOC_BUSY
-};
-
-struct i915_relocatee_info {
- struct drm_buffer_object *buf;
- unsigned long offset;
- uint32_t *data_page;
- unsigned page_offset;
- struct drm_bo_kmap_obj kmap;
- int is_iomem;
- int dst;
- int idle;
- int performed_ring_relocs;
-#ifdef DRM_KMAP_ATOMIC_PROT_PFN
- unsigned long pfn;
- pgprot_t pg_prot;
-#endif
-};
-
-struct drm_i915_validate_buffer {
- struct drm_buffer_object *buffer;
- int presumed_offset_correct;
- void __user *data;
- int ret;
- enum i915_buf_idle idle;
-};
-
-/*
- * I'd like to use MI_STORE_DATA_IMM here, but I can't make
- * it work. Seems like GART writes are broken with that
- * instruction. Also I'm not sure that MI_FLUSH will
- * act as a memory barrier for that instruction. It will
- * for this single dword 2D blit.
- */
-
-static void i915_emit_ring_reloc(struct drm_device *dev, uint32_t offset,
- uint32_t value)
-{
- struct drm_i915_private *dev_priv =
- (struct drm_i915_private *)dev->dev_private;
-
- RING_LOCALS;
- i915_kernel_lost_context(dev);
- BEGIN_LP_RING(6);
- OUT_RING((0x02 << 29) | (0x40 << 22) | (0x3 << 20) | (0x3));
- OUT_RING((0x3 << 24) | (0xF0 << 16) | (0x40));
- OUT_RING((0x1 << 16) | (0x4));
- OUT_RING(offset);
- OUT_RING(value);
- OUT_RING(0);
- ADVANCE_LP_RING();
-}
-
-static void i915_dereference_buffers_locked(struct drm_i915_validate_buffer
- *buffers, unsigned num_buffers)
-{
- while (num_buffers--)
- drm_bo_usage_deref_locked(&buffers[num_buffers].buffer);
-}
-
-int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
- struct drm_i915_validate_buffer *buffers,
- struct i915_relocatee_info *relocatee, uint32_t * reloc)
-{
- unsigned index;
- unsigned long new_cmd_offset;
- u32 val;
- int ret, i;
- int buf_index = -1;
-
- /*
- * FIXME: O(relocs * buffers) complexity.
- */
-
- for (i = 0; i <= num_buffers; i++)
- if (buffers[i].buffer)
- if (reloc[2] == buffers[i].buffer->base.hash.key)
- buf_index = i;
-
- if (buf_index == -1) {
- DRM_ERROR("Illegal relocation buffer %08X\n", reloc[2]);
- return -EINVAL;
- }
-
- /*
- * Short-circuit relocations that were correctly
- * guessed by the client
- */
- if (buffers[buf_index].presumed_offset_correct && !DRM_DEBUG_RELOCATION)
- return 0;
-
- new_cmd_offset = reloc[0];
- if (!relocatee->data_page ||
- !drm_bo_same_page(relocatee->offset, new_cmd_offset)) {
- struct drm_bo_mem_reg *mem = &relocatee->buf->mem;
-
- drm_bo_kunmap(&relocatee->kmap);
- relocatee->data_page = NULL;
- relocatee->offset = new_cmd_offset;
-
- if (unlikely(relocatee->idle == I915_RELOC_UNCHECKED)) {
- ret = drm_bo_wait(relocatee->buf, 0, 1, 0, 0);
- if (ret)
- return ret;
- relocatee->idle = I915_RELOC_IDLE;
- }
-
- if (unlikely((mem->mem_type != DRM_BO_MEM_LOCAL) &&
- (mem->flags & DRM_BO_FLAG_CACHED_MAPPED)))
- drm_bo_evict_cached(relocatee->buf);
-
- ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT,
- 1, &relocatee->kmap);
- if (ret) {
- DRM_ERROR
- ("Could not map command buffer to apply relocs\n %08lx",
- new_cmd_offset);
- return ret;
- }
- relocatee->data_page = drm_bmo_virtual(&relocatee->kmap,
- &relocatee->is_iomem);
- relocatee->page_offset = (relocatee->offset & PAGE_MASK);
- }
-
- val = buffers[buf_index].buffer->offset;
- index = (reloc[0] - relocatee->page_offset) >> 2;
-
- /* add in validate */
- val = val + reloc[1];
-
- if (DRM_DEBUG_RELOCATION) {
- if (buffers[buf_index].presumed_offset_correct &&
- relocatee->data_page[index] != val) {
- DRM_DEBUG
- ("Relocation mismatch source %d target %d buffer %d user %08x kernel %08x\n",
- reloc[0], reloc[1], buf_index,
- relocatee->data_page[index], val);
- }
- }
-
- if (relocatee->is_iomem)
- iowrite32(val, relocatee->data_page + index);
- else
- relocatee->data_page[index] = val;
- return 0;
-}
-
-int i915_process_relocs(struct drm_file *file_priv,
- uint32_t buf_handle,
- uint32_t __user ** reloc_user_ptr,
- struct i915_relocatee_info *relocatee,
- struct drm_i915_validate_buffer *buffers,
- uint32_t num_buffers)
-{
- int ret, reloc_stride;
- uint32_t cur_offset;
- uint32_t reloc_count;
- uint32_t reloc_type;
- uint32_t reloc_buf_size;
- uint32_t *reloc_buf = NULL;
- int i;
-
- /* do a copy from user from the user ptr */
- ret = get_user(reloc_count, *reloc_user_ptr);
- if (ret) {
- DRM_ERROR("Could not map relocation buffer.\n");
- goto out;
- }
-
- ret = get_user(reloc_type, (*reloc_user_ptr) + 1);
- if (ret) {
- DRM_ERROR("Could not map relocation buffer.\n");
- goto out;
- }
-
- if (reloc_type != 0) {
- DRM_ERROR("Unsupported relocation type requested\n");
- ret = -EINVAL;
- goto out;
- }
-
- reloc_buf_size =
- (I915_RELOC_HEADER +
- (reloc_count * I915_RELOC0_STRIDE)) * sizeof(uint32_t);
- reloc_buf = kmalloc(reloc_buf_size, GFP_KERNEL);
- if (!reloc_buf) {
- DRM_ERROR("Out of memory for reloc buffer\n");
- ret = -ENOMEM;
- goto out;
- }
-
- if (copy_from_user(reloc_buf, *reloc_user_ptr, reloc_buf_size)) {
- ret = -EFAULT;
- goto out;
- }
-
- /* get next relocate buffer handle */
- *reloc_user_ptr = (uint32_t *) * (unsigned long *)&reloc_buf[2];
-
- reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t); /* may be different for other types of relocs */
-
- DRM_DEBUG("num relocs is %d, next is %p\n", reloc_count,
- *reloc_user_ptr);
-
- for (i = 0; i < reloc_count; i++) {
- cur_offset = I915_RELOC_HEADER + (i * I915_RELOC0_STRIDE);
-
- ret = i915_apply_reloc(file_priv, num_buffers, buffers,
- relocatee, reloc_buf + cur_offset);
- if (ret)
- goto out;
- }
-
- out:
- if (reloc_buf)
- kfree(reloc_buf);
-
- if (relocatee->data_page) {
- drm_bo_kunmap(&relocatee->kmap);
- relocatee->data_page = NULL;
- }
-
- return ret;
-}
-
-static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
- uint32_t __user * reloc_user_ptr,
- struct drm_i915_validate_buffer *buffers,
- uint32_t buf_count)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct i915_relocatee_info relocatee;
- int ret = 0;
- int b;
-
- /*
- * Short circuit relocations when all previous
- * buffers offsets were correctly guessed by
- * the client
- */
- if (!DRM_DEBUG_RELOCATION) {
- for (b = 0; b < buf_count; b++)
- if (!buffers[b].presumed_offset_correct)
- break;
-
- if (b == buf_count)
- return 0;
- }
-
- memset(&relocatee, 0, sizeof(relocatee));
- relocatee.idle = I915_RELOC_UNCHECKED;
-
- mutex_lock(&dev->struct_mutex);
- relocatee.buf = drm_lookup_buffer_object(file_priv, buf_handle, 1);
- mutex_unlock(&dev->struct_mutex);
- if (!relocatee.buf) {
- DRM_DEBUG("relocatee buffer invalid %08x\n", buf_handle);
- ret = -EINVAL;
- goto out_err;
- }
-
- mutex_lock(&relocatee.buf->mutex);
- while (reloc_user_ptr) {
- ret =
- i915_process_relocs(file_priv, buf_handle, &reloc_user_ptr,
- &relocatee, buffers, buf_count);
- if (ret) {
- DRM_ERROR("process relocs failed\n");
- goto out_err1;
- }
- }
-
- out_err1:
- mutex_unlock(&relocatee.buf->mutex);
- drm_bo_usage_deref_unlocked(&relocatee.buf);
- out_err:
- return ret;
-}
-
-static void i915_clear_relocatee(struct i915_relocatee_info *relocatee)
-{
- if (relocatee->data_page) {
-#ifndef DRM_KMAP_ATOMIC_PROT_PFN
- drm_bo_kunmap(&relocatee->kmap);
-#else
- kunmap_atomic(relocatee->data_page, KM_USER0);
-#endif
- relocatee->data_page = NULL;
- }
- relocatee->buf = NULL;
- relocatee->dst = ~0;
-}
-
-static int i915_update_relocatee(struct i915_relocatee_info *relocatee,
- struct drm_i915_validate_buffer *buffers,
- unsigned int dst, unsigned long dst_offset)
-{
- int ret;
-
- if (unlikely(dst != relocatee->dst || NULL == relocatee->buf)) {
- i915_clear_relocatee(relocatee);
- relocatee->dst = dst;
- relocatee->buf = buffers[dst].buffer;
- relocatee->idle = buffers[dst].idle;
-
- /*
- * Check for buffer idle. If the buffer is busy, revert to
- * ring relocations.
- */
-
- if (relocatee->idle == I915_RELOC_UNCHECKED) {
- preempt_enable();
- mutex_lock(&relocatee->buf->mutex);
-
- ret = drm_bo_wait(relocatee->buf, 0, 1, 1, 0);
- if (ret == 0)
- relocatee->idle = I915_RELOC_IDLE;
- else {
- relocatee->idle = I915_RELOC_BUSY;
- relocatee->performed_ring_relocs = 1;
- }
- mutex_unlock(&relocatee->buf->mutex);
- preempt_disable();
- buffers[dst].idle = relocatee->idle;
- }
- }
-
- if (relocatee->idle == I915_RELOC_BUSY)
- return 0;
-
- if (unlikely(dst_offset > relocatee->buf->num_pages * PAGE_SIZE)) {
- DRM_ERROR("Relocation destination out of bounds.\n");
- return -EINVAL;
- }
- if (unlikely(!drm_bo_same_page(relocatee->page_offset, dst_offset) ||
- NULL == relocatee->data_page)) {
-#ifdef DRM_KMAP_ATOMIC_PROT_PFN
- if (NULL != relocatee->data_page) {
- kunmap_atomic(relocatee->data_page, KM_USER0);
- relocatee->data_page = NULL;
- }
- ret = drm_bo_pfn_prot(relocatee->buf, dst_offset,
- &relocatee->pfn, &relocatee->pg_prot);
- if (ret) {
- DRM_ERROR("Can't map relocation destination.\n");
- return -EINVAL;
- }
- relocatee->data_page =
- kmap_atomic_prot_pfn(relocatee->pfn, KM_USER0,
- relocatee->pg_prot);
-#else
- if (NULL != relocatee->data_page) {
- drm_bo_kunmap(&relocatee->kmap);
- relocatee->data_page = NULL;
- }
-
- ret = drm_bo_kmap(relocatee->buf, dst_offset >> PAGE_SHIFT,
- 1, &relocatee->kmap);
- if (ret) {
- DRM_ERROR("Can't map relocation destination.\n");
- return ret;
- }
-
- relocatee->data_page = drm_bmo_virtual(&relocatee->kmap,
- &relocatee->is_iomem);
-#endif
- relocatee->page_offset = dst_offset & PAGE_MASK;
- }
- return 0;
-}
-
-static int i915_apply_post_reloc(uint32_t reloc[],
- struct drm_i915_validate_buffer *buffers,
- uint32_t num_buffers,
- struct i915_relocatee_info *relocatee)
-{
- uint32_t reloc_buffer = reloc[2];
- uint32_t dst_buffer = reloc[3];
- uint32_t val;
- uint32_t index;
- int ret;
-
- if (likely(buffers[reloc_buffer].presumed_offset_correct))
- return 0;
- if (unlikely(reloc_buffer >= num_buffers)) {
- DRM_ERROR("Invalid reloc buffer index.\n");
- return -EINVAL;
- }
- if (unlikely(dst_buffer >= num_buffers)) {
- DRM_ERROR("Invalid dest buffer index.\n");
- return -EINVAL;
- }
-
- ret = i915_update_relocatee(relocatee, buffers, dst_buffer, reloc[0]);
- if (unlikely(ret))
- return ret;
-
- val = buffers[reloc_buffer].buffer->offset;
- index = (reloc[0] - relocatee->page_offset) >> 2;
- val = val + reloc[1];
-
- if (relocatee->idle == I915_RELOC_BUSY) {
- i915_emit_ring_reloc(relocatee->buf->dev,
- relocatee->buf->offset + reloc[0], val);
- return 0;
- }
-#ifdef DRM_KMAP_ATOMIC_PROT_PFN
- relocatee->data_page[index] = val;
-#else
- if (likely(relocatee->is_iomem))
- iowrite32(val, relocatee->data_page + index);
- else
- relocatee->data_page[index] = val;
-#endif
-
- return 0;
-}
-
-static int i915_post_relocs(struct drm_file *file_priv,
- uint32_t __user * new_reloc_ptr,
- struct drm_i915_validate_buffer *buffers,
- unsigned int num_buffers)
-{
- uint32_t *reloc;
- uint32_t reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t);
- uint32_t header_size = I915_RELOC_HEADER * sizeof(uint32_t);
- struct i915_relocatee_info relocatee;
- uint32_t reloc_type;
- uint32_t num_relocs;
- uint32_t count;
- int ret = 0;
- int i;
- int short_circuit = 1;
- uint32_t __user *reloc_ptr;
- uint64_t new_reloc_data;
- uint32_t reloc_buf_size;
- uint32_t *reloc_buf;
-
- for (i = 0; i < num_buffers; ++i) {
- if (unlikely(!buffers[i].presumed_offset_correct)) {
- short_circuit = 0;
- break;
- }
- }
-
- if (likely(short_circuit))
- return 0;
-
- memset(&relocatee, 0, sizeof(relocatee));
-
- while (new_reloc_ptr) {
- reloc_ptr = new_reloc_ptr;
-
- ret = get_user(num_relocs, reloc_ptr);
- if (unlikely(ret))
- goto out;
- if (unlikely(!access_ok(VERIFY_READ, reloc_ptr,
- header_size +
- num_relocs * reloc_stride)))
- return -EFAULT;
-
- ret = __get_user(reloc_type, reloc_ptr + 1);
- if (unlikely(ret))
- goto out;
-
- if (unlikely(reloc_type != 1)) {
- DRM_ERROR("Unsupported relocation type requested.\n");
- ret = -EINVAL;
- goto out;
- }
-
- ret = __get_user(new_reloc_data, reloc_ptr + 2);
- new_reloc_ptr = (uint32_t __user *) (unsigned long)
- new_reloc_data;
-
- reloc_ptr += I915_RELOC_HEADER;
-
- if (num_relocs == 0)
- goto out;
-
- reloc_buf_size =
- (num_relocs * I915_RELOC0_STRIDE) * sizeof(uint32_t);
- reloc_buf = kmalloc(reloc_buf_size, GFP_KERNEL);
- if (!reloc_buf) {
- DRM_ERROR("Out of memory for reloc buffer\n");
- ret = -ENOMEM;
- goto out;
- }
-
- if (__copy_from_user(reloc_buf, reloc_ptr, reloc_buf_size)) {
- ret = -EFAULT;
- goto out;
- }
- reloc = reloc_buf;
- preempt_disable();
- for (count = 0; count < num_relocs; ++count) {
- ret = i915_apply_post_reloc(reloc, buffers,
- num_buffers, &relocatee);
- if (unlikely(ret)) {
- preempt_enable();
- goto out;
- }
- reloc += I915_RELOC0_STRIDE;
- }
- preempt_enable();
-
- if (reloc_buf) {
- kfree(reloc_buf);
- reloc_buf = NULL;
- }
- i915_clear_relocatee(&relocatee);
- }
-
- out:
- /*
- * Flush ring relocs so the command parser will pick them up.
- */
-
- if (relocatee.performed_ring_relocs)
- (void)i915_emit_mi_flush(file_priv->minor->dev, 0);
-
- i915_clear_relocatee(&relocatee);
- if (reloc_buf) {
- kfree(reloc_buf);
- reloc_buf = NULL;
- }
-
- return ret;
-}
-
-static int i915_check_presumed(struct drm_i915_op_arg *arg,
- struct drm_buffer_object *bo,
- uint32_t __user * data, int *presumed_ok)
-{
- struct drm_bo_op_req *req = &arg->d.req;
- uint32_t hint_offset;
- uint32_t hint = req->bo_req.hint;
-
- *presumed_ok = 0;
-
- if (!(hint & DRM_BO_HINT_PRESUMED_OFFSET))
- return 0;
- if (bo->offset == req->bo_req.presumed_offset) {
- *presumed_ok = 1;
- return 0;
- }
-
- /*
- * We need to turn off the HINT_PRESUMED_OFFSET for this buffer in
- * the user-space IOCTL argument list, since the buffer has moved,
- * we're about to apply relocations and we might subsequently
- * hit an -EAGAIN. In that case the argument list will be reused by
- * user-space, but the presumed offset is no longer valid.
- *
- * Needless to say, this is a bit ugly.
- */
-
- hint_offset = (uint32_t *) & req->bo_req.hint - (uint32_t *) arg;
- hint &= ~DRM_BO_HINT_PRESUMED_OFFSET;
- return __put_user(hint, data + hint_offset);
-}
-
-/*
- * Validate, add fence and relocate a block of bos from a userspace list
- */
-int i915_validate_buffer_list(struct drm_file *file_priv,
- unsigned int fence_class, uint64_t data,
- struct drm_i915_validate_buffer *buffers,
- uint32_t * num_buffers,
- uint32_t __user ** post_relocs)
-{
- struct drm_i915_op_arg arg;
- struct drm_bo_op_req *req = &arg.d.req;
- int ret = 0;
- unsigned buf_count = 0;
- uint32_t buf_handle;
- uint32_t __user *reloc_user_ptr;
- struct drm_i915_validate_buffer *item = buffers;
- *post_relocs = NULL;
-
- do {
- if (buf_count >= *num_buffers) {
- DRM_ERROR("Buffer count exceeded %d\n.", *num_buffers);
- ret = -EINVAL;
- goto out_err;
- }
- item = buffers + buf_count;
- item->buffer = NULL;
- item->presumed_offset_correct = 0;
- item->idle = I915_RELOC_UNCHECKED;
-
- if (copy_from_user
- (&arg, (void __user *)(unsigned long)data, sizeof(arg))) {
- ret = -EFAULT;
- goto out_err;
- }
-
- ret = 0;
- if (req->op != drm_bo_validate) {
- DRM_ERROR
- ("Buffer object operation wasn't \"validate\".\n");
- ret = -EINVAL;
- goto out_err;
- }
- item->ret = 0;
- item->data = (void __user *)(unsigned long)data;
-
- buf_handle = req->bo_req.handle;
- reloc_user_ptr = (uint32_t *) (unsigned long)arg.reloc_ptr;
-
- /*
- * Switch mode to post-validation relocations?
- */
-
- if (unlikely((buf_count == 0) && (*post_relocs == NULL) &&
- (reloc_user_ptr != NULL))) {
- uint32_t reloc_type;
-
- ret = get_user(reloc_type, reloc_user_ptr + 1);
- if (ret)
- goto out_err;
-
- if (reloc_type == 1)
- *post_relocs = reloc_user_ptr;
-
- }
-
- if ((*post_relocs == NULL) && (reloc_user_ptr != NULL)) {
- ret =
- i915_exec_reloc(file_priv, buf_handle,
- reloc_user_ptr, buffers, buf_count);
- if (ret)
- goto out_err;
- DRM_MEMORYBARRIER();
- }
-
- ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
- req->bo_req.flags,
- req->bo_req.mask, req->bo_req.hint,
- req->bo_req.fence_class,
- NULL, &item->buffer);
- if (ret) {
- DRM_ERROR("error on handle validate %d\n", ret);
- goto out_err;
- }
-
- buf_count++;
-
- ret = i915_check_presumed(&arg, item->buffer,
- (uint32_t __user *)
- (unsigned long)data,
- &item->presumed_offset_correct);
- if (ret)
- goto out_err;
-
- data = arg.next;
- } while (data != 0);
- out_err:
- *num_buffers = buf_count;
- item->ret = (ret != -EAGAIN) ? ret : 0;
- return ret;
-}
-
-/*
- * Remove all buffers from the unfenced list.
- * If the execbuffer operation was aborted, for example due to a signal,
- * this also make sure that buffers retain their original state and
- * fence pointers.
- * Copy back buffer information to user-space unless we were interrupted
- * by a signal. In which case the IOCTL must be rerun.
- */
-
-static int i915_handle_copyback(struct drm_device *dev,
- struct drm_i915_validate_buffer *buffers,
- unsigned int num_buffers, int ret)
-{
- int err = ret;
- int i;
- struct drm_i915_op_arg arg;
- struct drm_buffer_object *bo;
-
- if (ret)
- drm_putback_buffer_objects(dev);
-
- if (ret != -EAGAIN) {
- for (i = 0; i < num_buffers; ++i) {
- arg.handled = 1;
- arg.d.rep.ret = buffers->ret;
- bo = buffers->buffer;
- mutex_lock(&bo->mutex);
- drm_bo_fill_rep_arg(bo, &arg.d.rep.bo_info);
- mutex_unlock(&bo->mutex);
- if (__copy_to_user(buffers->data, &arg, sizeof(arg)))
- err = -EFAULT;
- buffers++;
- }
- }
-
- return err;
-}
-
-/*
- * Create a fence object, and if that fails, pretend that everything is
- * OK and just idle the GPU.
- */
-
-void i915_fence_or_sync(struct drm_file *file_priv,
- uint32_t fence_flags,
- struct drm_fence_arg *fence_arg,
- struct drm_fence_object **fence_p)
-{
- struct drm_device *dev = file_priv->minor->dev;
- int ret;
- struct drm_fence_object *fence;
-
- ret = drm_fence_buffer_objects(dev, NULL, fence_flags, NULL, &fence);
-
- if (ret) {
-
- /*
- * Fence creation failed.
- * Fall back to synchronous operation and idle the engine.
- */
-
- (void)i915_emit_mi_flush(dev, MI_READ_FLUSH);
- (void)i915_quiescent(dev);
-
- if (!(fence_flags & DRM_FENCE_FLAG_NO_USER)) {
-
- /*
- * Communicate to user-space that
- * fence creation has failed and that
- * the engine is idle.
- */
-
- fence_arg->handle = ~0;
- fence_arg->error = ret;
- }
- drm_putback_buffer_objects(dev);
- if (fence_p)
- *fence_p = NULL;
- return;
- }
-
- if (!(fence_flags & DRM_FENCE_FLAG_NO_USER)) {
-
- ret = drm_fence_add_user_object(file_priv, fence,
- fence_flags &
- DRM_FENCE_FLAG_SHAREABLE);
- if (!ret)
- drm_fence_fill_arg(fence, fence_arg);
- else {
- /*
- * Fence user object creation failed.
- * We must idle the engine here as well, as user-
- * space expects a fence object to wait on. Since we
- * have a fence object we wait for it to signal
- * to indicate engine "sufficiently" idle.
- */
-
- (void)drm_fence_object_wait(fence, 0, 1, fence->type);
- drm_fence_usage_deref_unlocked(&fence);
- fence_arg->handle = ~0;
- fence_arg->error = ret;
- }
- }
-
- if (fence_p)
- *fence_p = fence;
- else if (fence)
- drm_fence_usage_deref_unlocked(&fence);
-}
-
-int i915_execbuffer(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_i915_private *dev_priv = (struct drm_i915_private *)
- dev->dev_private;
- struct drm_i915_master_private *master_priv =
- (struct drm_i915_master_private *)
- dev->primary->master->driver_priv;
- struct drm_i915_sarea *sarea_priv = (struct drm_i915_sarea *)
- master_priv->sarea_priv;
- struct drm_i915_execbuffer *exec_buf = data;
- struct drm_i915_batchbuffer *batch = &exec_buf->batch;
- struct drm_fence_arg *fence_arg = &exec_buf->fence_arg;
- int num_buffers;
- int ret;
- uint32_t __user *post_relocs;
-
- if (!dev_priv->allow_batchbuffer) {
- DRM_ERROR("Batchbuffer ioctl disabled\n");
- return -EINVAL;
- }
-
- if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
- batch->num_cliprects *
- sizeof(struct
- drm_clip_rect)))
- return -EFAULT;
-
- if (exec_buf->num_buffers > dev_priv->max_validate_buffers)
- return -EINVAL;
-
- ret = drm_bo_read_lock(&dev->bm.bm_lock, 1);
- if (ret)
- return ret;
-
- /*
- * The cmdbuf_mutex makes sure the validate-submit-fence
- * operation is atomic.
- */
-
- ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
- if (ret) {
- drm_bo_read_unlock(&dev->bm.bm_lock);
- return -EAGAIN;
- }
-
- num_buffers = exec_buf->num_buffers;
-
- if (!dev_priv->val_bufs) {
- dev_priv->val_bufs =
- vmalloc(sizeof(struct drm_i915_validate_buffer) *
- dev_priv->max_validate_buffers);
- }
- if (!dev_priv->val_bufs) {
- drm_bo_read_unlock(&dev->bm.bm_lock);
- mutex_unlock(&dev_priv->cmdbuf_mutex);
- return -ENOMEM;
- }
-
- /* validate buffer list + fixup relocations */
- ret = i915_validate_buffer_list(file_priv, 0, exec_buf->ops_list,
- dev_priv->val_bufs, &num_buffers,
- &post_relocs);
- if (ret)
- goto out_err0;
-
- if (post_relocs) {
- ret = i915_post_relocs(file_priv, post_relocs,
- dev_priv->val_bufs, num_buffers);
- if (ret)
- goto out_err0;
- }
-
- /* make sure all previous memory operations have passed */
- DRM_MEMORYBARRIER();
-
- if (!post_relocs) {
- drm_agp_chipset_flush(dev);
- batch->start =
- dev_priv->val_bufs[num_buffers - 1].buffer->offset;
- } else {
- batch->start += dev_priv->val_bufs[0].buffer->offset;
- }
-
- DRM_DEBUG("i915 exec batchbuffer, start %x used %d cliprects %d\n",
- batch->start, batch->used, batch->num_cliprects);
-
- ret = i915_dispatch_batchbuffer(dev, batch);
- if (ret)
- goto out_err0;
- if (sarea_priv)
- sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
- i915_fence_or_sync(file_priv, fence_arg->flags, fence_arg, NULL);
-
- out_err0:
- ret = i915_handle_copyback(dev, dev_priv->val_bufs, num_buffers, ret);
- mutex_lock(&dev->struct_mutex);
- i915_dereference_buffers_locked(dev_priv->val_bufs, num_buffers);
- mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&dev_priv->cmdbuf_mutex);
- drm_bo_read_unlock(&dev->bm.bm_lock);
- return ret;
-}
diff --git a/linux-core/i915_fence.c b/linux-core/i915_fence.c
deleted file mode 100644
index 436b7e1f..00000000
--- a/linux-core/i915_fence.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
-#include "i915_drv.h"
-
-/*
- * Initiate a sync flush if it's not already pending.
- */
-
-static inline void i915_initiate_rwflush(struct drm_i915_private *dev_priv,
- struct drm_fence_class_manager *fc)
-{
- if ((fc->pending_flush & DRM_I915_FENCE_TYPE_RW) &&
- !dev_priv->flush_pending) {
- dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv);
- dev_priv->flush_flags = fc->pending_flush;
- dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0);
- I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
- dev_priv->flush_pending = 1;
- fc->pending_flush &= ~DRM_I915_FENCE_TYPE_RW;
- }
-}
-
-static inline void i915_report_rwflush(struct drm_device *dev,
- struct drm_i915_private *dev_priv)
-{
- if (unlikely(dev_priv->flush_pending)) {
-
- uint32_t flush_flags;
- uint32_t i_status;
- uint32_t flush_sequence;
-
- i_status = READ_HWSP(dev_priv, 0);
- if ((i_status & (1 << 12)) !=
- (dev_priv->saved_flush_status & (1 << 12))) {
- flush_flags = dev_priv->flush_flags;
- flush_sequence = dev_priv->flush_sequence;
- dev_priv->flush_pending = 0;
- drm_fence_handler(dev, 0, flush_sequence,
- flush_flags, 0);
- }
- }
-}
-
-static void i915_fence_flush(struct drm_device *dev,
- uint32_t fence_class)
-{
- struct drm_i915_private *dev_priv =
- (struct drm_i915_private *) dev->dev_private;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_class_manager *fc = &fm->fence_class[0];
- unsigned long irq_flags;
-
- if (unlikely(!dev_priv))
- return;
-
- write_lock_irqsave(&fm->lock, irq_flags);
- i915_initiate_rwflush(dev_priv, fc);
- write_unlock_irqrestore(&fm->lock, irq_flags);
-}
-
-
-static void i915_fence_poll(struct drm_device *dev, uint32_t fence_class,
- uint32_t waiting_types)
-{
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_class_manager *fc = &fm->fence_class[0];
- uint32_t sequence;
-
- if (unlikely(!dev_priv))
- return;
-
- /*
- * First, report any executed sync flush:
- */
-
- i915_report_rwflush(dev, dev_priv);
-
- /*
- * Report A new breadcrumb, and adjust IRQs.
- */
-
- if (waiting_types & DRM_FENCE_TYPE_EXE) {
-
- sequence = READ_BREADCRUMB(dev_priv);
- drm_fence_handler(dev, 0, sequence,
- DRM_FENCE_TYPE_EXE, 0);
-
- if (dev_priv->fence_irq_on &&
- !(fc->waiting_types & DRM_FENCE_TYPE_EXE)) {
- i915_user_irq_off(dev);
- dev_priv->fence_irq_on = 0;
- } else if (!dev_priv->fence_irq_on &&
- (fc->waiting_types & DRM_FENCE_TYPE_EXE)) {
- i915_user_irq_on(dev);
- dev_priv->fence_irq_on = 1;
- }
- }
-
- /*
- * There may be new RW flushes pending. Start them.
- */
-
- i915_initiate_rwflush(dev_priv, fc);
-
- /*
- * And possibly, but unlikely, they finish immediately.
- */
-
- i915_report_rwflush(dev, dev_priv);
-
-}
-
-static int i915_fence_emit_sequence(struct drm_device *dev, uint32_t class,
- uint32_t flags, uint32_t *sequence,
- uint32_t *native_type)
-{
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- if (unlikely(!dev_priv))
- return -EINVAL;
-
- i915_emit_irq(dev);
- *sequence = (uint32_t) dev_priv->counter;
- *native_type = DRM_FENCE_TYPE_EXE;
- if (flags & DRM_I915_FENCE_FLAG_FLUSHED)
- *native_type |= DRM_I915_FENCE_TYPE_RW;
-
- return 0;
-}
-
-void i915_fence_handler(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_class_manager *fc = &fm->fence_class[0];
-
- write_lock(&fm->lock);
- if (likely(dev_priv->fence_irq_on))
- i915_fence_poll(dev, 0, fc->waiting_types);
- write_unlock(&fm->lock);
-}
-
-/*
- * We need a separate wait function since we need to poll for
- * sync flushes.
- */
-
-static int i915_fence_wait(struct drm_fence_object *fence,
- int lazy, int interruptible, uint32_t mask)
-{
- struct drm_device *dev = fence->dev;
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- struct drm_fence_manager *fm = &dev->fm;
- struct drm_fence_class_manager *fc = &fm->fence_class[0];
- int ret;
- unsigned long _end = jiffies + 3 * DRM_HZ;
-
- drm_fence_object_flush(fence, mask);
- if (likely(interruptible))
- ret = wait_event_interruptible_timeout
- (fc->fence_queue, drm_fence_object_signaled(fence, DRM_FENCE_TYPE_EXE),
- 3 * DRM_HZ);
- else
- ret = wait_event_timeout
- (fc->fence_queue, drm_fence_object_signaled(fence, DRM_FENCE_TYPE_EXE),
- 3 * DRM_HZ);
-
- if (unlikely(ret == -ERESTARTSYS))
- return -EAGAIN;
-
- if (unlikely(ret == 0))
- return -EBUSY;
-
- if (likely(mask == DRM_FENCE_TYPE_EXE ||
- drm_fence_object_signaled(fence, mask)))
- return 0;
-
- /*
- * Remove this code snippet when fixed. HWSTAM doesn't let
- * flush info through...
- */
-
- if (unlikely(dev_priv && !dev_priv->irq_enabled)) {
- unsigned long irq_flags;
-
- DRM_ERROR("X server disabled IRQs before releasing frame buffer.\n");
- msleep(100);
- dev_priv->flush_pending = 0;
- write_lock_irqsave(&fm->lock, irq_flags);
- drm_fence_handler(dev, fence->fence_class,
- fence->sequence, fence->type, 0);
- write_unlock_irqrestore(&fm->lock, irq_flags);
- }
-
- /*
- * Poll for sync flush completion.
- */
-
- return drm_fence_wait_polling(fence, lazy, interruptible, mask, _end);
-}
-
-static uint32_t i915_fence_needed_flush(struct drm_fence_object *fence)
-{
- uint32_t flush_flags = fence->waiting_types &
- ~(DRM_FENCE_TYPE_EXE | fence->signaled_types);
-
- if (likely(flush_flags == 0 ||
- ((flush_flags & ~fence->native_types) == 0) ||
- (fence->signaled_types != DRM_FENCE_TYPE_EXE)))
- return 0;
- else {
- struct drm_device *dev = fence->dev;
- struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- struct drm_fence_driver *driver = dev->driver->fence_driver;
-
- if (unlikely(!dev_priv))
- return 0;
-
- if (dev_priv->flush_pending) {
- uint32_t diff = (dev_priv->flush_sequence - fence->sequence) &
- driver->sequence_mask;
-
- if (diff < driver->wrap_diff)
- return 0;
- }
- }
- return flush_flags;
-}
-
-struct drm_fence_driver i915_fence_driver = {
- .num_classes = 1,
- .wrap_diff = (1U << (BREADCRUMB_BITS - 1)),
- .flush_diff = (1U << (BREADCRUMB_BITS - 2)),
- .sequence_mask = BREADCRUMB_MASK,
- .has_irq = NULL,
- .emit = i915_fence_emit_sequence,
- .flush = i915_fence_flush,
- .poll = i915_fence_poll,
- .needed_flush = i915_fence_needed_flush,
- .wait = i915_fence_wait,
-};
diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c
index e06cba5b..1aa3afbf 100644
--- a/linux-core/radeon_gem.c
+++ b/linux-core/radeon_gem.c
@@ -245,8 +245,7 @@ int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
if (!(obj_priv->bo->type != drm_bo_type_kernel && !DRM_SUSER(DRM_CURPROC))) {
ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
- DRM_BO_HINT_DONT_FENCE,
- 0, NULL);
+ DRM_BO_HINT_DONT_FENCE, 0);
} else
ret = 0;
@@ -276,8 +275,7 @@ int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
/* validate into a pin with no fence */
ret = drm_bo_do_validate(obj_priv->bo, DRM_BO_FLAG_NO_EVICT, DRM_BO_FLAG_NO_EVICT,
- DRM_BO_HINT_DONT_FENCE,
- 0, NULL);
+ DRM_BO_HINT_DONT_FENCE, 0);
mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(obj);
@@ -321,7 +319,7 @@ int radeon_gem_indirect_ioctl(struct drm_device *dev, void *data,
//VB_AGE_TEST_WITH_RETURN(dev_priv);
ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
- 0 , 0, NULL);
+ 0 , 0);
if (ret)
return ret;
@@ -693,7 +691,7 @@ int radeon_gem_object_pin(struct drm_gem_object *obj,
obj_priv = obj->driver_private;
ret = drm_bo_do_validate(obj_priv->bo, 0, DRM_BO_FLAG_NO_EVICT,
- DRM_BO_HINT_DONT_FENCE, 0, NULL);
+ DRM_BO_HINT_DONT_FENCE, 0);
return ret;
}
@@ -743,7 +741,7 @@ int radeon_gem_ib_get(struct drm_device *dev, void **ib, uint32_t dwords, uint32
ret = drm_bo_do_validate(dev_priv->ib_objs[index]->bo, 0,
DRM_BO_FLAG_NO_EVICT,
- 0, 0, NULL);
+ 0, 0);
if (ret) {
DRM_ERROR("Failed to validate IB %d\n", index);
return -EINVAL;
@@ -761,7 +759,6 @@ static void radeon_gem_ib_free(struct drm_device *dev, void *ib, uint32_t dwords
struct drm_fence_object *fence;
int ret;
int i;
- RING_LOCALS;
for (i = 0; i < RADEON_NUM_IB; i++) {
@@ -821,7 +818,7 @@ static int radeon_gem_relocate(struct drm_device *dev, struct drm_file *file_pri
flags = DRM_BO_FLAG_MEM_TT;
}
- ret = drm_bo_do_validate(obj_priv->bo, flags, DRM_BO_MASK_MEM, 0, 0, NULL);
+ ret = drm_bo_do_validate(obj_priv->bo, flags, DRM_BO_MASK_MEM, 0, 0);
if (ret)
return ret;