From 490047b7312b798c441e4290a0e1a37bf6519ab3 Mon Sep 17 00:00:00 2001 From: Topi Pohjolainen Date: Fri, 27 Apr 2012 17:24:18 +0300 Subject: [PATCH] staging: imgv: ttm: replace buffer creation with latest UMG logic Part of video hw driver update from UMG. Signed-off-by: Topi Pohjolainen --- drivers/staging/mrst/imgv/psb_ttm_placement_user.c | 348 +++++++++++---------- 1 file changed, 178 insertions(+), 170 deletions(-) diff --git a/drivers/staging/mrst/imgv/psb_ttm_placement_user.c b/drivers/staging/mrst/imgv/psb_ttm_placement_user.c index d50a6f3..8f5a0cf 100644 --- a/drivers/staging/mrst/imgv/psb_ttm_placement_user.c +++ b/drivers/staging/mrst/imgv/psb_ttm_placement_user.c @@ -26,8 +26,6 @@ #include "ttm/ttm_object.h" #include "psb_ttm_userobj_api.h" #include "ttm/ttm_lock.h" -#include "psb_drm.h" -#include "pvr_bridge_km.h" #include #include @@ -39,26 +37,15 @@ struct ttm_bo_user_object { static size_t pl_bo_size; static uint32_t psb_busy_prios[] = { - TTM_PL_TT, - TTM_PL_PRIV0, /* CI */ - TTM_PL_PRIV2, /* RAR */ - TTM_PL_PRIV1, /* DRM_PSB_MEM_MMU */ - TTM_PL_SYSTEM + TTM_PL_FLAG_TT | TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED, + TTM_PL_FLAG_PRIV0, /* CI */ + TTM_PL_FLAG_PRIV2, /* RAR */ + TTM_PL_FLAG_PRIV1, /* DRM_PSB_MEM_MMU */ + TTM_PL_FLAG_SYSTEM }; static const struct ttm_placement default_placement = {0, 0, 0, NULL, 5, psb_busy_prios}; -static uint32_t psb_pvr_busy_prios[] = { - TTM_PL_TT, - TTM_PL_PRIV1, /* DRM_PSB_MEM_MMU */ - TTM_PL_SYSTEM -}; - -static const struct ttm_placement pvr_default_placement = { - .busy_placement = psb_pvr_busy_prios, - .num_busy_placement = ARRAY_SIZE(psb_pvr_busy_prios), -}; - static size_t ttm_pl_size(struct ttm_bo_device *bdev, unsigned long num_pages) { size_t page_array_size = @@ -210,53 +197,30 @@ static int ttm_bo_create_private(struct ttm_bo_device *bdev, return ret; } -static bool fixed_placement_valid(uint32_t pl_flags) -{ - if (!(pl_flags & TTM_PL_FLAG_NO_SWAP)) - return false; - - pl_flags &= TTM_PL_MASK_MEM; - pl_flags &= ~(DRM_PSB_FLAG_MEM_MMU | TTM_PL_FLAG_TT | - TTM_PL_FLAG_SYSTEM); - - return !pl_flags; -} - -static uint32_t normalize_placement_flags(uint32_t flags) +int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo, + struct ttm_placement *placement) { - if ((flags & TTM_PL_MASK_CACHING) == 0) - flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; - if (flags & TTM_PL_FLAG_NO_SWAP) - flags |= TTM_PL_FLAG_NO_EVICT; - - return flags; -} - -static int set_clear_placement_flags(struct ttm_buffer_object *bo, uint32_t set, - uint32_t clear, uint32_t *new_ret) -{ - uint32_t cur = bo->mem.placement; - uint32_t new; - bool is_root; - char *flag_name = "no swap"; - - new = (cur | set) & ~clear; - new = normalize_placement_flags(new); - - flag_name = "no evict"; - is_root = capable(CAP_SYS_ADMIN); - if (!is_root && (cur ^ new) & TTM_PL_FLAG_NO_EVICT) - goto err; - - *new_ret = new; - + int i; + + for (i = 0; i < placement->num_placement; i++) { + if (!capable(CAP_SYS_ADMIN)) { + if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) { + printk(KERN_ERR TTM_PFX "Need to be root to " + "modify NO_EVICT status.\n"); + return -EINVAL; + } + } + } + for (i = 0; i < placement->num_busy_placement; i++) { + if (!capable(CAP_SYS_ADMIN)) { + if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) { + printk(KERN_ERR TTM_PFX "Need to be root to " + "modify NO_EVICT status.\n"); + return -EINVAL; + } + } + } return 0; -err: - pr_debug("imgv: Permission denied to set '%s' flag: " - "is_root %d cur %08x set %08x clear %08x\n", - flag_name, is_root, cur, set, clear); - - return -EACCES; } int ttm_buffer_object_create(struct ttm_bo_device *bdev, @@ -291,116 +255,85 @@ int ttm_buffer_object_create(struct ttm_bo_device *bdev, return ret; } -struct create_params { - struct ttm_bo_device *bdev; - enum ttm_bo_type bo_type; - size_t size; - off_t align; - unsigned long user_address; - struct page **pages; - struct ttm_placement *placement; - struct ttm_object_file *tfile; - bool shareable; -}; -static int pl_create_buf(struct create_params *p, struct ttm_lock *lock, - struct ttm_pl_rep *rep) +int ttm_pl_create_ioctl(struct ttm_object_file *tfile, + struct ttm_bo_device *bdev, + struct ttm_lock *lock, void *data) { + union ttm_pl_create_arg *arg = data; + struct ttm_pl_create_req *req = &arg->req; + struct ttm_pl_rep *rep = &arg->rep; struct ttm_buffer_object *bo; struct ttm_buffer_object *tmp; struct ttm_bo_user_object *user_bo; - struct ttm_mem_global *mem_glob = p->bdev->glob->mem_glob; - size_t acc_size; - int pg_cnt; - int ret; - - pg_cnt = PAGE_ALIGN(p->size) >> PAGE_SHIFT; - acc_size = ttm_pl_size(p->bdev, pg_cnt); + uint32_t flags; + int ret = 0; + struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; + struct ttm_placement placement = default_placement; + size_t acc_size = + ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT); ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); - if (ret < 0) + if (unlikely(ret != 0)) return ret; + flags = req->placement; user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL); - if (!user_bo) { - ret = -ENOMEM; - goto err1; + if (unlikely(user_bo == NULL)) { + ttm_mem_global_free(mem_glob, acc_size); + return -ENOMEM; } bo = &user_bo->bo; - ret = ttm_read_lock(lock, true); - if (ret < 0) - goto err2; + if (unlikely(ret != 0)) { + ttm_mem_global_free(mem_glob, acc_size); + kfree(user_bo); + return ret; + } - ret = ttm_bo_init(p->bdev, bo, pg_cnt << PAGE_SHIFT, p->bo_type, - p->placement, p->align, p->user_address, true, NULL, - acc_size, &ttm_bo_user_destroy); + placement.num_placement = 1; + placement.placement = &flags; + + if ((flags & TTM_PL_MASK_CACHING) == 0) + flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; + + ret = ttm_bo_init(bdev, bo, req->size, + ttm_bo_type_device, &placement, + req->page_alignment, 0, true, + NULL, acc_size, &ttm_bo_user_destroy); + ttm_read_unlock(lock); /* * Note that the ttm_buffer_object_init function * would've called the destroy function on failure!! */ - if (ret < 0) { - ttm_read_unlock(lock); - goto err2; - } - - ttm_read_unlock(lock); - /* ttm_bo_unref->destroy will unset the fixed pages on failure */ - if (ret < 0) - goto err3; + if (unlikely(ret != 0)) + goto out; tmp = ttm_bo_reference(bo); - - ret = ttm_base_object_init(p->tfile, &user_bo->base, p->shareable, - ttm_buffer_type, &ttm_bo_user_release, + ret = ttm_base_object_init(tfile, &user_bo->base, + flags & TTM_PL_FLAG_SHARED, + ttm_buffer_type, + &ttm_bo_user_release, &ttm_bo_user_ref_release); - if (ret < 0) - goto err3; + if (unlikely(ret != 0)) + goto out_err; - spin_lock(&bo->bdev->fence_lock); + ret = ttm_bo_reserve(bo, true, false, false, 0); + if (unlikely(ret != 0)) + goto out_err; ttm_pl_fill_rep(bo, rep); - spin_unlock(&bo->bdev->fence_lock); - - ttm_bo_unref(&tmp); - + ttm_bo_unreserve(bo); + ttm_bo_unref(&bo); +out: return 0; -err3: +out_err: ttm_bo_unref(&tmp); -err2: - kfree(user_bo); -err1: - ttm_mem_global_free(mem_glob, acc_size); - + ttm_bo_unref(&bo); return ret; } -int ttm_pl_create_ioctl(struct ttm_object_file *tfile, - struct ttm_bo_device *bdev, - struct ttm_lock *lock, void *data) -{ - union ttm_pl_create_arg *arg = data; - struct ttm_pl_create_req *req = &arg->req; - struct ttm_pl_rep *rep = &arg->rep; - struct ttm_placement pl = default_placement; - uint32_t pl_flags = normalize_placement_flags(req->placement); - struct create_params cp = { - .bdev = bdev, - .bo_type = ttm_bo_type_device, - .size = req->size, - .align = req->page_alignment, - .placement = &pl, - .tfile = tfile, - .shareable = req->placement & TTM_PL_FLAG_SHARED, - }; - - pl.num_placement = 1; - pl.placement = &pl_flags; - - return pl_create_buf(&cp, lock, rep); -} - int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile, struct ttm_bo_device *bdev, struct ttm_lock *lock, void *data) @@ -408,23 +341,77 @@ int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile, union ttm_pl_create_ub_arg *arg = data; struct ttm_pl_create_ub_req *req = &arg->req; struct ttm_pl_rep *rep = &arg->rep; - struct ttm_placement pl = default_placement; - uint32_t pl_flags = normalize_placement_flags(req->placement); - struct create_params cp = { - .bdev = bdev, - .bo_type = ttm_bo_type_user, - .size = req->size, - .user_address = req->user_address, - .align = req->page_alignment, - .placement = &pl, - .tfile = tfile, - .shareable = req->placement & TTM_PL_FLAG_SHARED, - }; - - pl.num_placement = 1; - pl.placement = &pl_flags; - - return pl_create_buf(&cp, lock, rep); + struct ttm_buffer_object *bo; + struct ttm_buffer_object *tmp; + struct ttm_bo_user_object *user_bo; + uint32_t flags; + int ret = 0; + struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; + struct ttm_placement placement = default_placement; + size_t acc_size = + ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT); + ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); + if (unlikely(ret != 0)) + return ret; + + flags = req->placement; + user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL); + if (unlikely(user_bo == NULL)) { + ttm_mem_global_free(mem_glob, acc_size); + return -ENOMEM; + } + ret = ttm_read_lock(lock, true); + if (unlikely(ret != 0)) { + ttm_mem_global_free(mem_glob, acc_size); + kfree(user_bo); + return ret; + } + bo = &user_bo->bo; + + placement.num_placement = 1; + placement.placement = &flags; + + ret = ttm_bo_init(bdev, + bo, + req->size, + ttm_bo_type_user, + &placement, + req->page_alignment, + req->user_address, + true, + NULL, + acc_size, + &ttm_bo_user_destroy); + + /* + * Note that the ttm_buffer_object_init function + * would've called the destroy function on failure!! + */ + ttm_read_unlock(lock); + if (unlikely(ret != 0)) + goto out; + + tmp = ttm_bo_reference(bo); + ret = ttm_base_object_init(tfile, &user_bo->base, + flags & TTM_PL_FLAG_SHARED, + ttm_buffer_type, + &ttm_bo_user_release, + &ttm_bo_user_ref_release); + if (unlikely(ret != 0)) + goto out_err; + + ret = ttm_bo_reserve(bo, true, false, false, 0); + if (unlikely(ret != 0)) + goto out_err; + ttm_pl_fill_rep(bo, rep); + ttm_bo_unreserve(bo); + ttm_bo_unref(&bo); +out: + return 0; +out_err: + ttm_bo_unref(&tmp); + ttm_bo_unref(&bo); + return ret; } int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data) @@ -450,9 +437,11 @@ int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data) goto out; } - spin_lock(&bo->bdev->fence_lock); + ret = ttm_bo_reserve(bo, true, false, false, 0); + if (unlikely(ret != 0)) + goto out; ttm_pl_fill_rep(bo, rep); - spin_unlock(&bo->bdev->fence_lock); + ttm_bo_unreserve(bo); out: base = &user_bo->base; @@ -500,8 +489,21 @@ int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data) ttm_base_object_unref(&base); break; case TTM_PL_SYNCCPU_OP_RELEASE: + bo = ttm_buffer_object_lookup(tfile, arg->handle); + if (unlikely(bo == NULL)) { + printk(KERN_ERR "Could not find buffer object for synccpu release\n"); + ret = -EINVAL; + goto out; + } + ret = ttm_bo_reserve(bo, true, true, false, 0); + if (unlikely(ret != 0)) { + ttm_bo_unref(&bo); + return ret; + } ret = ttm_ref_object_base_unref(tfile, arg->handle, TTM_REF_SYNCCPU_WRITE); + ttm_bo_unreserve(bo); + ttm_bo_unref(&bo); break; default: ret = -EINVAL; @@ -520,7 +522,7 @@ int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile, struct ttm_buffer_object *bo; struct ttm_bo_device *bdev; struct ttm_placement placement = default_placement; - uint32_t pl_flags; + uint32_t flags[2]; int ret; bo = ttm_buffer_object_lookup(tfile, req->handle); @@ -544,14 +546,20 @@ int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile, if (unlikely(ret != 0)) goto out_err2; - spin_lock(&bo->bdev->fence_lock); + flags[0] = req->set_placement; + flags[1] = req->clr_placement; - placement.num_placement = 1; - ret = set_clear_placement_flags(bo, req->set_placement, - req->clr_placement, &pl_flags); - if (ret < 0) + placement.num_placement = 2; + placement.placement = flags; + + /* spin_lock(&bo->lock); */ /* Already get reserve lock */ + + ret = psb_ttm_bo_check_placement(bo, &placement); + if (unlikely(ret != 0)) goto out_err2; - placement.placement = &pl_flags; + + placement.num_placement = 1; + flags[0] = (req->set_placement | bo->mem.placement) & ~req->clr_placement; ret = ttm_bo_validate(bo, &placement, true, false, false); if (unlikely(ret != 0)) @@ -559,7 +567,7 @@ int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile, ttm_pl_fill_rep(bo, rep); out_err2: - spin_unlock(&bo->bdev->fence_lock); + /* spin_unlock(&bo->lock); */ ttm_bo_unreserve(bo); out_err1: ttm_read_unlock(lock); -- 2.7.4