summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/radeon_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gem.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c109
1 files changed, 61 insertions, 48 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index a36a4f2c76b0..18ca1bcfd2f9 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -26,6 +26,8 @@
* Jerome Glisse
*/
+#include <linux/debugfs.h>
+#include <linux/iosys-map.h>
#include <linux/pci.h>
#include <drm/drm_device.h>
@@ -42,8 +44,6 @@ struct sg_table *radeon_gem_prime_get_sg_table(struct drm_gem_object *obj);
int radeon_gem_prime_pin(struct drm_gem_object *obj);
void radeon_gem_prime_unpin(struct drm_gem_object *obj);
-const struct drm_gem_object_funcs radeon_gem_object_funcs;
-
static vm_fault_t radeon_gem_fault(struct vm_fault *vmf)
{
struct ttm_buffer_object *bo = vmf->vma->vm_private_data;
@@ -86,7 +86,7 @@ static void radeon_gem_object_free(struct drm_gem_object *gobj)
if (robj) {
radeon_mn_unregister(robj);
- radeon_bo_unref(&robj);
+ ttm_bo_fini(&robj->tbo);
}
}
@@ -130,7 +130,6 @@ retry:
return r;
}
*obj = &robj->tbo.base;
- (*obj)->funcs = &radeon_gem_object_funcs;
robj->pid = task_pid_nr(current);
mutex_lock(&rdev->gem.mutex);
@@ -161,7 +160,9 @@ static int radeon_gem_set_domain(struct drm_gem_object *gobj,
}
if (domain == RADEON_GEM_DOMAIN_CPU) {
/* Asking for cpu access wait for object idle */
- r = dma_resv_wait_timeout(robj->tbo.base.resv, true, true, 30 * HZ);
+ r = dma_resv_wait_timeout(robj->tbo.base.resv,
+ DMA_RESV_USAGE_BOOKKEEP,
+ true, 30 * HZ);
if (!r)
r = -EBUSY;
@@ -308,22 +309,6 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
return 0;
}
-int radeon_gem_pread_ioctl(struct drm_device *dev, void *data,
- struct drm_file *filp)
-{
- /* TODO: implement */
- DRM_ERROR("unimplemented %s\n", __func__);
- return -ENOSYS;
-}
-
-int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data,
- struct drm_file *filp)
-{
- /* TODO: implement */
- DRM_ERROR("unimplemented %s\n", __func__);
- return -ENOSYS;
-}
-
int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
@@ -456,7 +441,6 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
struct radeon_device *rdev = dev->dev_private;
struct drm_radeon_gem_set_domain *args = data;
struct drm_gem_object *gobj;
- struct radeon_bo *robj;
int r;
/* for now if someone requests domain CPU -
@@ -469,13 +453,12 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
up_read(&rdev->exclusive_lock);
return -ENOENT;
}
- robj = gem_to_radeon_bo(gobj);
r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
drm_gem_object_put(gobj);
up_read(&rdev->exclusive_lock);
- r = radeon_gem_handle_lockup(robj->rdev, r);
+ r = radeon_gem_handle_lockup(rdev, r);
return r;
}
@@ -523,7 +506,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
}
robj = gem_to_radeon_bo(gobj);
- r = dma_resv_test_signaled(robj->tbo.base.resv, true);
+ r = dma_resv_test_signaled(robj->tbo.base.resv, DMA_RESV_USAGE_READ);
if (r == 0)
r = -EBUSY;
else
@@ -552,7 +535,8 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
}
robj = gem_to_radeon_bo(gobj);
- ret = dma_resv_wait_timeout(robj->tbo.base.resv, true, true, 30 * HZ);
+ ret = dma_resv_wait_timeout(robj->tbo.base.resv, DMA_RESV_USAGE_READ,
+ true, 30 * HZ);
if (ret == 0)
r = -EBUSY;
else if (ret < 0)
@@ -621,33 +605,40 @@ out:
static void radeon_gem_va_update_vm(struct radeon_device *rdev,
struct radeon_bo_va *bo_va)
{
- struct ttm_validate_buffer tv, *entry;
- struct radeon_bo_list *vm_bos;
- struct ww_acquire_ctx ticket;
+ struct radeon_bo_list *vm_bos, *entry;
struct list_head list;
+ struct drm_exec exec;
unsigned domain;
int r;
INIT_LIST_HEAD(&list);
- tv.bo = &bo_va->bo->tbo;
- tv.num_shared = 1;
- list_add(&tv.head, &list);
-
vm_bos = radeon_vm_get_bos(rdev, bo_va->vm, &list);
if (!vm_bos)
return;
- r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
- if (r)
- goto error_free;
+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
+ drm_exec_until_all_locked(&exec) {
+ list_for_each_entry(entry, &list, list) {
+ r = drm_exec_prepare_obj(&exec, &entry->robj->tbo.base,
+ 1);
+ drm_exec_retry_on_contention(&exec);
+ if (unlikely(r))
+ goto error_cleanup;
+ }
+
+ r = drm_exec_prepare_obj(&exec, &bo_va->bo->tbo.base, 1);
+ drm_exec_retry_on_contention(&exec);
+ if (unlikely(r))
+ goto error_cleanup;
+ }
- list_for_each_entry(entry, &list, head) {
- domain = radeon_mem_type_to_domain(entry->bo->resource->mem_type);
+ list_for_each_entry(entry, &list, list) {
+ domain = radeon_mem_type_to_domain(entry->robj->tbo.resource->mem_type);
/* if anything is swapped out don't swap it in here,
just abort and wait for the next CS */
if (domain == RADEON_GEM_DOMAIN_CPU)
- goto error_unreserve;
+ goto error_cleanup;
}
mutex_lock(&bo_va->vm->mutex);
@@ -655,16 +646,14 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev,
if (r)
goto error_unlock;
- if (bo_va->it.start)
+ if (bo_va->it.start && bo_va->bo)
r = radeon_vm_bo_update(rdev, bo_va, bo_va->bo->tbo.resource);
error_unlock:
mutex_unlock(&bo_va->vm->mutex);
-error_unreserve:
- ttm_eu_backoff_reservation(&ticket, &list);
-
-error_free:
+error_cleanup:
+ drm_exec_fini(&exec);
kvfree(vm_bos);
if (r && r != -ERESTARTSYS)
@@ -689,7 +678,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
}
/* !! DONT REMOVE !!
- * We don't support vm_id yet, to be sure we don't have have broken
+ * We don't support vm_id yet, to be sure we don't have broken
* userspace, reject anyone trying to use non 0 value thus moving
* forward we can use those fields without breaking existant userspace
*/
@@ -818,6 +807,30 @@ out:
return r;
}
+int radeon_align_pitch(struct radeon_device *rdev, int width, int cpp, bool tiled)
+{
+ int aligned = width;
+ int align_large = (ASIC_IS_AVIVO(rdev)) || tiled;
+ int pitch_mask = 0;
+
+ switch (cpp) {
+ case 1:
+ pitch_mask = align_large ? 255 : 127;
+ break;
+ case 2:
+ pitch_mask = align_large ? 127 : 31;
+ break;
+ case 3:
+ case 4:
+ pitch_mask = align_large ? 63 : 15;
+ break;
+ }
+
+ aligned += pitch_mask;
+ aligned &= ~pitch_mask;
+ return aligned * cpp;
+}
+
int radeon_mode_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args)
@@ -829,7 +842,7 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
args->pitch = radeon_align_pitch(rdev, args->width,
DIV_ROUND_UP(args->bpp, 8), 0);
- args->size = args->pitch * args->height;
+ args->size = (u64)args->pitch * args->height;
args->size = ALIGN(args->size, PAGE_SIZE);
r = radeon_gem_object_create(rdev, args->size, 0,
@@ -851,7 +864,7 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
#if defined(CONFIG_DEBUG_FS)
static int radeon_debugfs_gem_info_show(struct seq_file *m, void *unused)
{
- struct radeon_device *rdev = (struct radeon_device *)m->private;
+ struct radeon_device *rdev = m->private;
struct radeon_bo *rbo;
unsigned i = 0;
@@ -888,7 +901,7 @@ DEFINE_SHOW_ATTRIBUTE(radeon_debugfs_gem_info);
void radeon_gem_debugfs_init(struct radeon_device *rdev)
{
#if defined(CONFIG_DEBUG_FS)
- struct dentry *root = rdev->ddev->primary->debugfs_root;
+ struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
debugfs_create_file("radeon_gem_info", 0444, root, rdev,
&radeon_debugfs_gem_info_fops);