diff options
| author | Rob Clark <robclark@freedesktop.org> | 2026-07-28 06:45:25 -0700 |
|---|---|---|
| committer | Rob Clark <robclark@freedesktop.org> | 2026-07-28 06:45:25 -0700 |
| commit | d7a6f5fc6ef97f129b0d422a3c2c92ec7264eea0 (patch) | |
| tree | 5f5e5f0b5e745d03e507dcecd3450bf9614d5c72 | |
| parent | f198c21dfcb89127083413dd4779a13b3f9a6507 (diff) | |
Remove libdrm_freedreno
The copy in libdrm has not been maintained so much since mesa (being the
only consumer) copied this into the mesa tree in ~2018)
Signed-off-by: Rob Clark <robclark@freedesktop.org>
27 files changed, 0 insertions, 4769 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index 28a11db4..ea954d40 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -1,4 +1,3 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/libdrm) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/freedreno) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libdrm_*intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libdrm_*intermediates) diff --git a/freedreno/freedreno-symbols.txt b/freedreno/freedreno-symbols.txt deleted file mode 100644 index 471ca997..00000000 --- a/freedreno/freedreno-symbols.txt +++ /dev/null @@ -1,45 +0,0 @@ -fd_bo_cpu_fini -fd_bo_cpu_prep -fd_bo_del -fd_bo_dmabuf -fd_bo_from_dmabuf -fd_bo_from_fbdev -fd_bo_from_handle -fd_bo_from_name -fd_bo_get_iova -fd_bo_get_name -fd_bo_handle -fd_bo_map -fd_bo_new -fd_bo_put_iova -fd_bo_ref -fd_bo_size -fd_device_del -fd_device_fd -fd_device_new -fd_device_new_dup -fd_device_ref -fd_device_version -fd_pipe_del -fd_pipe_get_param -fd_pipe_new -fd_pipe_new2 -fd_pipe_ref -fd_pipe_wait -fd_pipe_wait_timeout -fd_ringbuffer_cmd_count -fd_ringbuffer_del -fd_ringbuffer_emit_reloc_ring_full -fd_ringbuffer_flush -fd_ringbuffer_grow -fd_ringbuffer_new -fd_ringbuffer_new_flags -fd_ringbuffer_new_object -fd_ringbuffer_ref -fd_ringbuffer_reloc -fd_ringbuffer_reloc2 -fd_ringbuffer_reset -fd_ringbuffer_set_parent -fd_ringbuffer_size -fd_ringbuffer_timestamp -fd_ringbuffer_flush2 diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c deleted file mode 100644 index 3cdc9737..00000000 --- a/freedreno/freedreno_bo.c +++ /dev/null @@ -1,359 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include "freedreno_drmif.h" -#include "freedreno_priv.h" - -drm_private pthread_mutex_t table_lock = PTHREAD_MUTEX_INITIALIZER; -drm_private void bo_del(struct fd_bo *bo); - -/* set buffer name, and add to table, call w/ table_lock held: */ -static void set_name(struct fd_bo *bo, uint32_t name) -{ - bo->name = name; - /* add ourself into the handle table: */ - drmHashInsert(bo->dev->name_table, name, bo); -} - -/* lookup a buffer, call w/ table_lock held: */ -static struct fd_bo * lookup_bo(void *tbl, uint32_t key) -{ - struct fd_bo *bo = NULL; - if (!drmHashLookup(tbl, key, (void **)&bo)) { - /* found, incr refcnt and return: */ - bo = fd_bo_ref(bo); - - /* don't break the bucket if this bo was found in one */ - list_delinit(&bo->list); - } - return bo; -} - -/* allocate a new buffer object, call w/ table_lock held */ -static struct fd_bo * bo_from_handle(struct fd_device *dev, - uint32_t size, uint32_t handle) -{ - struct fd_bo *bo; - - bo = dev->funcs->bo_from_handle(dev, size, handle); - if (!bo) { - drmCloseBufferHandle(dev->fd, handle); - return NULL; - } - bo->dev = fd_device_ref(dev); - bo->size = size; - bo->handle = handle; - atomic_set(&bo->refcnt, 1); - list_inithead(&bo->list); - /* add ourself into the handle table: */ - drmHashInsert(dev->handle_table, handle, bo); - return bo; -} - -static struct fd_bo * -bo_new(struct fd_device *dev, uint32_t size, uint32_t flags, - struct fd_bo_cache *cache) -{ - struct fd_bo *bo = NULL; - uint32_t handle; - int ret; - - bo = fd_bo_cache_alloc(cache, &size, flags); - if (bo) - return bo; - - ret = dev->funcs->bo_new_handle(dev, size, flags, &handle); - if (ret) - return NULL; - - pthread_mutex_lock(&table_lock); - bo = bo_from_handle(dev, size, handle); - pthread_mutex_unlock(&table_lock); - - VG_BO_ALLOC(bo); - - return bo; -} - -drm_public struct fd_bo * -fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) -{ - struct fd_bo *bo = bo_new(dev, size, flags, &dev->bo_cache); - if (bo) - bo->bo_reuse = BO_CACHE; - return bo; -} - -/* internal function to allocate bo's that use the ringbuffer cache - * instead of the normal bo_cache. The purpose is, because cmdstream - * bo's get vmap'd on the kernel side, and that is expensive, we want - * to re-use cmdstream bo's for cmdstream and not unrelated purposes. - */ -drm_private struct fd_bo * -fd_bo_new_ring(struct fd_device *dev, uint32_t size, uint32_t flags) -{ - struct fd_bo *bo = bo_new(dev, size, flags, &dev->ring_cache); - if (bo) - bo->bo_reuse = RING_CACHE; - return bo; -} - -drm_public struct fd_bo * -fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size) -{ - struct fd_bo *bo = NULL; - - pthread_mutex_lock(&table_lock); - - bo = lookup_bo(dev->handle_table, handle); - if (bo) - goto out_unlock; - - bo = bo_from_handle(dev, size, handle); - - VG_BO_ALLOC(bo); - -out_unlock: - pthread_mutex_unlock(&table_lock); - - return bo; -} - -drm_public struct fd_bo * -fd_bo_from_dmabuf(struct fd_device *dev, int fd) -{ - int ret, size; - uint32_t handle; - struct fd_bo *bo; - - pthread_mutex_lock(&table_lock); - ret = drmPrimeFDToHandle(dev->fd, fd, &handle); - if (ret) { - pthread_mutex_unlock(&table_lock); - return NULL; - } - - bo = lookup_bo(dev->handle_table, handle); - if (bo) - goto out_unlock; - - /* lseek() to get bo size */ - size = lseek(fd, 0, SEEK_END); - lseek(fd, 0, SEEK_CUR); - - bo = bo_from_handle(dev, size, handle); - - VG_BO_ALLOC(bo); - -out_unlock: - pthread_mutex_unlock(&table_lock); - - return bo; -} - -drm_public struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name) -{ - struct drm_gem_open req = { - .name = name, - }; - struct fd_bo *bo; - - pthread_mutex_lock(&table_lock); - - /* check name table first, to see if bo is already open: */ - bo = lookup_bo(dev->name_table, name); - if (bo) - goto out_unlock; - - if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) { - ERROR_MSG("gem-open failed: %s", strerror(errno)); - goto out_unlock; - } - - bo = lookup_bo(dev->handle_table, req.handle); - if (bo) - goto out_unlock; - - bo = bo_from_handle(dev, req.size, req.handle); - if (bo) { - set_name(bo, name); - VG_BO_ALLOC(bo); - } - -out_unlock: - pthread_mutex_unlock(&table_lock); - - return bo; -} - -drm_public uint64_t fd_bo_get_iova(struct fd_bo *bo) -{ - return bo->funcs->iova(bo); -} - -drm_public void fd_bo_put_iova(struct fd_bo *bo) -{ - /* currently a no-op */ -} - -drm_public struct fd_bo * fd_bo_ref(struct fd_bo *bo) -{ - atomic_inc(&bo->refcnt); - return bo; -} - -drm_public void fd_bo_del(struct fd_bo *bo) -{ - struct fd_device *dev = bo->dev; - - if (!atomic_dec_and_test(&bo->refcnt)) - return; - - pthread_mutex_lock(&table_lock); - - if ((bo->bo_reuse == BO_CACHE) && (fd_bo_cache_free(&dev->bo_cache, bo) == 0)) - goto out; - if ((bo->bo_reuse == RING_CACHE) && (fd_bo_cache_free(&dev->ring_cache, bo) == 0)) - goto out; - - bo_del(bo); - fd_device_del_locked(dev); -out: - pthread_mutex_unlock(&table_lock); -} - -/* Called under table_lock */ -drm_private void bo_del(struct fd_bo *bo) -{ - VG_BO_FREE(bo); - - if (bo->map) - drm_munmap(bo->map, bo->size); - - /* TODO probably bo's in bucket list get removed from - * handle table?? - */ - - if (bo->handle) { - drmHashDelete(bo->dev->handle_table, bo->handle); - if (bo->name) - drmHashDelete(bo->dev->name_table, bo->name); - drmCloseBufferHandle(bo->dev->fd, bo->handle); - } - - bo->funcs->destroy(bo); -} - -drm_public int fd_bo_get_name(struct fd_bo *bo, uint32_t *name) -{ - if (!bo->name) { - struct drm_gem_flink req = { - .handle = bo->handle, - }; - int ret; - - ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req); - if (ret) { - return ret; - } - - pthread_mutex_lock(&table_lock); - set_name(bo, req.name); - pthread_mutex_unlock(&table_lock); - bo->bo_reuse = NO_CACHE; - } - - *name = bo->name; - - return 0; -} - -drm_public uint32_t fd_bo_handle(struct fd_bo *bo) -{ - return bo->handle; -} - -drm_public int fd_bo_dmabuf(struct fd_bo *bo) -{ - int ret, prime_fd; - - ret = drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC, - &prime_fd); - if (ret) { - ERROR_MSG("failed to get dmabuf fd: %d", ret); - return ret; - } - - bo->bo_reuse = NO_CACHE; - - return prime_fd; -} - -drm_public uint32_t fd_bo_size(struct fd_bo *bo) -{ - return bo->size; -} - -drm_public void * fd_bo_map(struct fd_bo *bo) -{ - if (!bo->map) { - uint64_t offset; - int ret; - - ret = bo->funcs->offset(bo, &offset); - if (ret) { - return NULL; - } - - bo->map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->dev->fd, offset); - if (bo->map == MAP_FAILED) { - ERROR_MSG("mmap failed: %s", strerror(errno)); - bo->map = NULL; - } - } - return bo->map; -} - -/* a bit odd to take the pipe as an arg, but it's a, umm, quirk of kgsl.. */ -drm_public int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) -{ - return bo->funcs->cpu_prep(bo, pipe, op); -} - -drm_public void fd_bo_cpu_fini(struct fd_bo *bo) -{ - bo->funcs->cpu_fini(bo); -} - -#if !HAVE_FREEDRENO_KGSL -drm_public struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size) -{ - return NULL; -} -#endif diff --git a/freedreno/freedreno_bo_cache.c b/freedreno/freedreno_bo_cache.c deleted file mode 100644 index bb0605ab..00000000 --- a/freedreno/freedreno_bo_cache.c +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2016 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include "freedreno_drmif.h" -#include "freedreno_priv.h" - -drm_private void bo_del(struct fd_bo *bo); -drm_private extern pthread_mutex_t table_lock; - -static void -add_bucket(struct fd_bo_cache *cache, int size) -{ - unsigned int i = cache->num_buckets; - - assert(i < ARRAY_SIZE(cache->cache_bucket)); - - list_inithead(&cache->cache_bucket[i].list); - cache->cache_bucket[i].size = size; - cache->num_buckets++; -} - -/** - * @coarse: if true, only power-of-two bucket sizes, otherwise - * fill in for a bit smoother size curve.. - */ -drm_private void -fd_bo_cache_init(struct fd_bo_cache *cache, int coarse) -{ - unsigned long size, cache_max_size = 64 * 1024 * 1024; - - /* OK, so power of two buckets was too wasteful of memory. - * Give 3 other sizes between each power of two, to hopefully - * cover things accurately enough. (The alternative is - * probably to just go for exact matching of sizes, and assume - * that for things like composited window resize the tiled - * width/height alignment and rounding of sizes to pages will - * get us useful cache hit rates anyway) - */ - add_bucket(cache, 4096); - add_bucket(cache, 4096 * 2); - if (!coarse) - add_bucket(cache, 4096 * 3); - - /* Initialize the linked lists for BO reuse cache. */ - for (size = 4 * 4096; size <= cache_max_size; size *= 2) { - add_bucket(cache, size); - if (!coarse) { - add_bucket(cache, size + size * 1 / 4); - add_bucket(cache, size + size * 2 / 4); - add_bucket(cache, size + size * 3 / 4); - } - } -} - -/* Frees older cached buffers. Called under table_lock */ -drm_private void -fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time) -{ - int i; - - if (cache->time == time) - return; - - for (i = 0; i < cache->num_buckets; i++) { - struct fd_bo_bucket *bucket = &cache->cache_bucket[i]; - struct fd_bo *bo; - - while (!LIST_IS_EMPTY(&bucket->list)) { - bo = LIST_ENTRY(struct fd_bo, bucket->list.next, list); - - /* keep things in cache for at least 1 second: */ - if (time && ((time - bo->free_time) <= 1)) - break; - - VG_BO_OBTAIN(bo); - list_del(&bo->list); - bo_del(bo); - } - } - - cache->time = time; -} - -static struct fd_bo_bucket * get_bucket(struct fd_bo_cache *cache, uint32_t size) -{ - int i; - - /* hmm, this is what intel does, but I suppose we could calculate our - * way to the correct bucket size rather than looping.. - */ - for (i = 0; i < cache->num_buckets; i++) { - struct fd_bo_bucket *bucket = &cache->cache_bucket[i]; - if (bucket->size >= size) { - return bucket; - } - } - - return NULL; -} - -static int is_idle(struct fd_bo *bo) -{ - return fd_bo_cpu_prep(bo, NULL, - DRM_FREEDRENO_PREP_READ | - DRM_FREEDRENO_PREP_WRITE | - DRM_FREEDRENO_PREP_NOSYNC) == 0; -} - -static struct fd_bo *find_in_bucket(struct fd_bo_bucket *bucket, uint32_t flags) -{ - struct fd_bo *bo = NULL; - - /* TODO .. if we had an ALLOC_FOR_RENDER flag like intel, we could - * skip the busy check.. if it is only going to be a render target - * then we probably don't need to stall.. - * - * NOTE that intel takes ALLOC_FOR_RENDER bo's from the list tail - * (MRU, since likely to be in GPU cache), rather than head (LRU).. - */ - pthread_mutex_lock(&table_lock); - if (!LIST_IS_EMPTY(&bucket->list)) { - bo = LIST_ENTRY(struct fd_bo, bucket->list.next, list); - /* TODO check for compatible flags? */ - if (is_idle(bo)) { - list_del(&bo->list); - } else { - bo = NULL; - } - } - pthread_mutex_unlock(&table_lock); - - return bo; -} - -/* NOTE: size is potentially rounded up to bucket size: */ -drm_private struct fd_bo * -fd_bo_cache_alloc(struct fd_bo_cache *cache, uint32_t *size, uint32_t flags) -{ - struct fd_bo *bo = NULL; - struct fd_bo_bucket *bucket; - - *size = ALIGN(*size, 4096); - bucket = get_bucket(cache, *size); - - /* see if we can be green and recycle: */ -retry: - if (bucket) { - *size = bucket->size; - bo = find_in_bucket(bucket, flags); - if (bo) { - VG_BO_OBTAIN(bo); - if (bo->funcs->madvise(bo, TRUE) <= 0) { - /* we've lost the backing pages, delete and try again: */ - pthread_mutex_lock(&table_lock); - bo_del(bo); - pthread_mutex_unlock(&table_lock); - goto retry; - } - atomic_set(&bo->refcnt, 1); - fd_device_ref(bo->dev); - return bo; - } - } - - return NULL; -} - -drm_private int -fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo) -{ - struct fd_bo_bucket *bucket = get_bucket(cache, bo->size); - - /* see if we can be green and recycle: */ - if (bucket) { - struct timespec time; - - bo->funcs->madvise(bo, FALSE); - - clock_gettime(CLOCK_MONOTONIC, &time); - - bo->free_time = time.tv_sec; - VG_BO_RELEASE(bo); - list_addtail(&bo->list, &bucket->list); - fd_bo_cache_cleanup(cache, time.tv_sec); - - /* bo's in the bucket cache don't have a ref and - * don't hold a ref to the dev: - */ - fd_device_del_locked(bo->dev); - - return 0; - } - - return -1; -} diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c deleted file mode 100644 index ac234304..00000000 --- a/freedreno/freedreno_device.c +++ /dev/null @@ -1,145 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "freedreno_drmif.h" -#include "freedreno_priv.h" - -static pthread_mutex_t table_lock = PTHREAD_MUTEX_INITIALIZER; - -struct fd_device * kgsl_device_new(int fd); -struct fd_device * msm_device_new(int fd); - -drm_public struct fd_device * fd_device_new(int fd) -{ - struct fd_device *dev; - drmVersionPtr version; - - /* figure out if we are kgsl or msm drm driver: */ - version = drmGetVersion(fd); - if (!version) { - ERROR_MSG("cannot get version: %s", strerror(errno)); - return NULL; - } - - if (!strcmp(version->name, "msm")) { - DEBUG_MSG("msm DRM device"); - if (version->version_major != 1) { - ERROR_MSG("unsupported version: %u.%u.%u", version->version_major, - version->version_minor, version->version_patchlevel); - dev = NULL; - goto out; - } - - dev = msm_device_new(fd); - dev->version = version->version_minor; -#if HAVE_FREEDRENO_KGSL - } else if (!strcmp(version->name, "kgsl")) { - DEBUG_MSG("kgsl DRM device"); - dev = kgsl_device_new(fd); -#endif - } else { - ERROR_MSG("unknown device: %s", version->name); - dev = NULL; - } - -out: - drmFreeVersion(version); - - if (!dev) - return NULL; - - atomic_set(&dev->refcnt, 1); - dev->fd = fd; - dev->handle_table = drmHashCreate(); - dev->name_table = drmHashCreate(); - fd_bo_cache_init(&dev->bo_cache, FALSE); - fd_bo_cache_init(&dev->ring_cache, TRUE); - - return dev; -} - -/* like fd_device_new() but creates it's own private dup() of the fd - * which is close()d when the device is finalized. - */ -drm_public struct fd_device * fd_device_new_dup(int fd) -{ - int dup_fd = dup(fd); - struct fd_device *dev = fd_device_new(dup_fd); - if (dev) - dev->closefd = 1; - else - close(dup_fd); - return dev; -} - -drm_public struct fd_device * fd_device_ref(struct fd_device *dev) -{ - atomic_inc(&dev->refcnt); - return dev; -} - -static void fd_device_del_impl(struct fd_device *dev) -{ - int close_fd = dev->closefd ? dev->fd : -1; - fd_bo_cache_cleanup(&dev->bo_cache, 0); - drmHashDestroy(dev->handle_table); - drmHashDestroy(dev->name_table); - dev->funcs->destroy(dev); - if (close_fd >= 0) - close(close_fd); -} - -drm_private void fd_device_del_locked(struct fd_device *dev) -{ - if (!atomic_dec_and_test(&dev->refcnt)) - return; - fd_device_del_impl(dev); -} - -drm_public void fd_device_del(struct fd_device *dev) -{ - if (!atomic_dec_and_test(&dev->refcnt)) - return; - pthread_mutex_lock(&table_lock); - fd_device_del_impl(dev); - pthread_mutex_unlock(&table_lock); -} - -drm_public int fd_device_fd(struct fd_device *dev) -{ - return dev->fd; -} - -drm_public enum fd_version fd_device_version(struct fd_device *dev) -{ - return dev->version; -} diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h deleted file mode 100644 index c95c21be..00000000 --- a/freedreno/freedreno_drmif.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#ifndef FREEDRENO_DRMIF_H_ -#define FREEDRENO_DRMIF_H_ - -#include <xf86drm.h> -#include <stdint.h> - -#if defined(__GNUC__) -# define drm_deprecated __attribute__((__deprecated__)) -#else -# define drm_deprecated -#endif - -/* an empty marker for things that will be deprecated in the future: */ -#define will_be_deprecated - -struct fd_bo; -struct fd_pipe; -struct fd_device; - -enum fd_pipe_id { - FD_PIPE_3D = 1, - FD_PIPE_2D = 2, - /* some devices have two 2d blocks.. not really sure how to - * use that yet, so just ignoring the 2nd 2d pipe for now - */ - FD_PIPE_MAX -}; - -enum fd_param_id { - FD_DEVICE_ID, - FD_GMEM_SIZE, - FD_GPU_ID, - FD_CHIP_ID, - FD_MAX_FREQ, - FD_TIMESTAMP, - FD_NR_RINGS, /* # of rings == # of distinct priority levels */ -}; - -/* bo flags: */ -#define DRM_FREEDRENO_GEM_TYPE_SMI 0x00000001 -#define DRM_FREEDRENO_GEM_TYPE_KMEM 0x00000002 -#define DRM_FREEDRENO_GEM_TYPE_MEM_MASK 0x0000000f -#define DRM_FREEDRENO_GEM_CACHE_NONE 0x00000000 -#define DRM_FREEDRENO_GEM_CACHE_WCOMBINE 0x00100000 -#define DRM_FREEDRENO_GEM_CACHE_WTHROUGH 0x00200000 -#define DRM_FREEDRENO_GEM_CACHE_WBACK 0x00400000 -#define DRM_FREEDRENO_GEM_CACHE_WBACKWA 0x00800000 -#define DRM_FREEDRENO_GEM_CACHE_MASK 0x00f00000 -#define DRM_FREEDRENO_GEM_GPUREADONLY 0x01000000 - -/* bo access flags: (keep aligned to MSM_PREP_x) */ -#define DRM_FREEDRENO_PREP_READ 0x01 -#define DRM_FREEDRENO_PREP_WRITE 0x02 -#define DRM_FREEDRENO_PREP_NOSYNC 0x04 - -/* device functions: - */ - -struct fd_device * fd_device_new(int fd); -struct fd_device * fd_device_new_dup(int fd); -struct fd_device * fd_device_ref(struct fd_device *dev); -void fd_device_del(struct fd_device *dev); -int fd_device_fd(struct fd_device *dev); - -enum fd_version { - FD_VERSION_MADVISE = 1, /* kernel supports madvise */ - FD_VERSION_UNLIMITED_CMDS = 1, /* submits w/ >4 cmd buffers (growable ringbuffer) */ - FD_VERSION_FENCE_FD = 2, /* submit command supports in/out fences */ - FD_VERSION_SUBMIT_QUEUES = 3, /* submit queues and multiple priority levels */ - FD_VERSION_BO_IOVA = 3, /* supports fd_bo_get/put_iova() */ -}; -enum fd_version fd_device_version(struct fd_device *dev); - -/* pipe functions: - */ - -struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); -struct fd_pipe * fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio); -struct fd_pipe * fd_pipe_ref(struct fd_pipe *pipe); -void fd_pipe_del(struct fd_pipe *pipe); -int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, - uint64_t *value); -int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp); -/* timeout in nanosec */ -int fd_pipe_wait_timeout(struct fd_pipe *pipe, uint32_t timestamp, - uint64_t timeout); - - -/* buffer-object functions: - */ - -struct fd_bo * fd_bo_new(struct fd_device *dev, - uint32_t size, uint32_t flags); -struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe, - int fbfd, uint32_t size); -struct fd_bo *fd_bo_from_handle(struct fd_device *dev, - uint32_t handle, uint32_t size); -struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name); -struct fd_bo * fd_bo_from_dmabuf(struct fd_device *dev, int fd); -uint64_t fd_bo_get_iova(struct fd_bo *bo); -void fd_bo_put_iova(struct fd_bo *bo); -struct fd_bo * fd_bo_ref(struct fd_bo *bo); -void fd_bo_del(struct fd_bo *bo); -int fd_bo_get_name(struct fd_bo *bo, uint32_t *name); -uint32_t fd_bo_handle(struct fd_bo *bo); -int fd_bo_dmabuf(struct fd_bo *bo); -uint32_t fd_bo_size(struct fd_bo *bo); -void * fd_bo_map(struct fd_bo *bo); -int fd_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op); -void fd_bo_cpu_fini(struct fd_bo *bo); - -#endif /* FREEDRENO_DRMIF_H_ */ diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c deleted file mode 100644 index e82e6448..00000000 --- a/freedreno/freedreno_pipe.c +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include "freedreno_drmif.h" -#include "freedreno_priv.h" - -/** - * priority of zero is highest priority, and higher numeric values are - * lower priorities - */ -drm_public struct fd_pipe * -fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio) -{ - struct fd_pipe *pipe; - uint64_t val; - - if (id > FD_PIPE_MAX) { - ERROR_MSG("invalid pipe id: %d", id); - return NULL; - } - - if ((prio != 1) && (fd_device_version(dev) < FD_VERSION_SUBMIT_QUEUES)) { - ERROR_MSG("invalid priority!"); - return NULL; - } - - pipe = dev->funcs->pipe_new(dev, id, prio); - if (!pipe) { - ERROR_MSG("allocation failed"); - return NULL; - } - - pipe->dev = dev; - pipe->id = id; - atomic_set(&pipe->refcnt, 1); - - fd_pipe_get_param(pipe, FD_GPU_ID, &val); - pipe->gpu_id = val; - - return pipe; -} - -drm_public struct fd_pipe * -fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) -{ - return fd_pipe_new2(dev, id, 1); -} - -drm_public struct fd_pipe * fd_pipe_ref(struct fd_pipe *pipe) -{ - atomic_inc(&pipe->refcnt); - return pipe; -} - -drm_public void fd_pipe_del(struct fd_pipe *pipe) -{ - if (!atomic_dec_and_test(&pipe->refcnt)) - return; - pipe->funcs->destroy(pipe); -} - -drm_public int fd_pipe_get_param(struct fd_pipe *pipe, - enum fd_param_id param, uint64_t *value) -{ - return pipe->funcs->get_param(pipe, param, value); -} - -drm_public int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp) -{ - return fd_pipe_wait_timeout(pipe, timestamp, ~0); -} - -drm_public int fd_pipe_wait_timeout(struct fd_pipe *pipe, uint32_t timestamp, - uint64_t timeout) -{ - return pipe->funcs->wait(pipe, timestamp, timeout); -} diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h deleted file mode 100644 index b8eac4b2..00000000 --- a/freedreno/freedreno_priv.h +++ /dev/null @@ -1,258 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#ifndef FREEDRENO_PRIV_H_ -#define FREEDRENO_PRIV_H_ - -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <pthread.h> -#include <stdio.h> -#include <assert.h> - -#include "libdrm_macros.h" -#include "xf86drm.h" -#include "xf86atomic.h" - -#include "util_double_list.h" -#include "util_math.h" - -#include "freedreno_drmif.h" -#include "freedreno_ringbuffer.h" -#include "drm.h" - -#ifndef TRUE -# define TRUE 1 -#endif -#ifndef FALSE -# define FALSE 0 -#endif - -struct fd_device_funcs { - int (*bo_new_handle)(struct fd_device *dev, uint32_t size, - uint32_t flags, uint32_t *handle); - struct fd_bo * (*bo_from_handle)(struct fd_device *dev, - uint32_t size, uint32_t handle); - struct fd_pipe * (*pipe_new)(struct fd_device *dev, enum fd_pipe_id id, - unsigned prio); - void (*destroy)(struct fd_device *dev); -}; - -struct fd_bo_bucket { - uint32_t size; - struct list_head list; -}; - -struct fd_bo_cache { - struct fd_bo_bucket cache_bucket[14 * 4]; - int num_buckets; - time_t time; -}; - -struct fd_device { - int fd; - enum fd_version version; - atomic_t refcnt; - - /* tables to keep track of bo's, to avoid "evil-twin" fd_bo objects: - * - * handle_table: maps handle to fd_bo - * name_table: maps flink name to fd_bo - * - * We end up needing two tables, because DRM_IOCTL_GEM_OPEN always - * returns a new handle. So we need to figure out if the bo is already - * open in the process first, before calling gem-open. - */ - void *handle_table, *name_table; - - const struct fd_device_funcs *funcs; - - struct fd_bo_cache bo_cache; - struct fd_bo_cache ring_cache; - - int closefd; /* call close(fd) upon destruction */ - - /* just for valgrind: */ - int bo_size; -}; - -drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse); -drm_private void fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time); -drm_private struct fd_bo * fd_bo_cache_alloc(struct fd_bo_cache *cache, - uint32_t *size, uint32_t flags); -drm_private int fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo); - -/* for where @table_lock is already held: */ -drm_private void fd_device_del_locked(struct fd_device *dev); - -struct fd_pipe_funcs { - struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size, - enum fd_ringbuffer_flags flags); - int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value); - int (*wait)(struct fd_pipe *pipe, uint32_t timestamp, uint64_t timeout); - void (*destroy)(struct fd_pipe *pipe); -}; - -struct fd_pipe { - struct fd_device *dev; - enum fd_pipe_id id; - uint32_t gpu_id; - atomic_t refcnt; - const struct fd_pipe_funcs *funcs; -}; - -struct fd_ringbuffer_funcs { - void * (*hostptr)(struct fd_ringbuffer *ring); - int (*flush)(struct fd_ringbuffer *ring, uint32_t *last_start, - int in_fence_fd, int *out_fence_fd); - void (*grow)(struct fd_ringbuffer *ring, uint32_t size); - void (*reset)(struct fd_ringbuffer *ring); - void (*emit_reloc)(struct fd_ringbuffer *ring, - const struct fd_reloc *reloc); - uint32_t (*emit_reloc_ring)(struct fd_ringbuffer *ring, - struct fd_ringbuffer *target, uint32_t cmd_idx); - uint32_t (*cmd_count)(struct fd_ringbuffer *ring); - void (*destroy)(struct fd_ringbuffer *ring); -}; - -struct fd_bo_funcs { - int (*offset)(struct fd_bo *bo, uint64_t *offset); - int (*cpu_prep)(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op); - void (*cpu_fini)(struct fd_bo *bo); - int (*madvise)(struct fd_bo *bo, int willneed); - uint64_t (*iova)(struct fd_bo *bo); - void (*destroy)(struct fd_bo *bo); -}; - -struct fd_bo { - struct fd_device *dev; - uint32_t size; - uint32_t handle; - uint32_t name; - void *map; - atomic_t refcnt; - const struct fd_bo_funcs *funcs; - - enum { - NO_CACHE = 0, - BO_CACHE = 1, - RING_CACHE = 2, - } bo_reuse; - - struct list_head list; /* bucket-list entry */ - time_t free_time; /* time when added to bucket-list */ -}; - -drm_private struct fd_bo *fd_bo_new_ring(struct fd_device *dev, - uint32_t size, uint32_t flags); - -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) - -#define enable_debug 0 /* TODO make dynamic */ - -#define INFO_MSG(fmt, ...) \ - do { drmMsg("[I] "fmt " (%s:%d)\n", \ - ##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0) -#define DEBUG_MSG(fmt, ...) \ - do if (enable_debug) { drmMsg("[D] "fmt " (%s:%d)\n", \ - ##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0) -#define WARN_MSG(fmt, ...) \ - do { drmMsg("[W] "fmt " (%s:%d)\n", \ - ##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0) -#define ERROR_MSG(fmt, ...) \ - do { drmMsg("[E] " fmt " (%s:%d)\n", \ - ##__VA_ARGS__, __FUNCTION__, __LINE__); } while (0) - -#define U642VOID(x) ((void *)(unsigned long)(x)) -#define VOID2U64(x) ((uint64_t)(unsigned long)(x)) - -static inline uint32_t -offset_bytes(void *end, void *start) -{ - return ((char *)end) - ((char *)start); -} - -#if HAVE_VALGRIND -# include <memcheck.h> - -/* - * For tracking the backing memory (if valgrind enabled, we force a mmap - * for the purposes of tracking) - */ -static inline void VG_BO_ALLOC(struct fd_bo *bo) -{ - if (bo && RUNNING_ON_VALGRIND) { - VALGRIND_MALLOCLIKE_BLOCK(fd_bo_map(bo), bo->size, 0, 1); - } -} - -static inline void VG_BO_FREE(struct fd_bo *bo) -{ - VALGRIND_FREELIKE_BLOCK(bo->map, 0); -} - -/* - * For tracking bo structs that are in the buffer-cache, so that valgrind - * doesn't attribute ownership to the first one to allocate the recycled - * bo. - * - * Note that the list_head in fd_bo is used to track the buffers in cache - * so disable error reporting on the range while they are in cache so - * valgrind doesn't squawk about list traversal. - * - */ -static inline void VG_BO_RELEASE(struct fd_bo *bo) -{ - if (RUNNING_ON_VALGRIND) { - VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size); - VALGRIND_MAKE_MEM_NOACCESS(bo, bo->dev->bo_size); - VALGRIND_FREELIKE_BLOCK(bo->map, 0); - } -} -static inline void VG_BO_OBTAIN(struct fd_bo *bo) -{ - if (RUNNING_ON_VALGRIND) { - VALGRIND_MAKE_MEM_DEFINED(bo, bo->dev->bo_size); - VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size); - VALGRIND_MALLOCLIKE_BLOCK(bo->map, bo->size, 0, 1); - } -} -#else -static inline void VG_BO_ALLOC(struct fd_bo *bo) {} -static inline void VG_BO_FREE(struct fd_bo *bo) {} -static inline void VG_BO_RELEASE(struct fd_bo *bo) {} -static inline void VG_BO_OBTAIN(struct fd_bo *bo) {} -#endif - - -#endif /* FREEDRENO_PRIV_H_ */ diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c deleted file mode 100644 index 8f0093ae..00000000 --- a/freedreno/freedreno_ringbuffer.c +++ /dev/null @@ -1,182 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include <assert.h> - -#include "freedreno_drmif.h" -#include "freedreno_priv.h" -#include "freedreno_ringbuffer.h" - -drm_public struct fd_ringbuffer * -fd_ringbuffer_new_flags(struct fd_pipe *pipe, uint32_t size, - enum fd_ringbuffer_flags flags) -{ - struct fd_ringbuffer *ring; - - /* we can't really support "growable" rb's in general for - * stateobj's since we need a single gpu addr (ie. can't - * do the trick of a chain of IB packets): - */ - if (flags & FD_RINGBUFFER_OBJECT) - assert(size); - - ring = pipe->funcs->ringbuffer_new(pipe, size, flags); - if (!ring) - return NULL; - - ring->flags = flags; - ring->pipe = pipe; - ring->start = ring->funcs->hostptr(ring); - ring->end = &(ring->start[ring->size/4]); - - ring->cur = ring->last_start = ring->start; - - return ring; -} - -drm_public struct fd_ringbuffer * -fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size) -{ - return fd_ringbuffer_new_flags(pipe, size, 0); -} - -drm_public struct fd_ringbuffer * -fd_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size) -{ - return fd_ringbuffer_new_flags(pipe, size, FD_RINGBUFFER_OBJECT); -} - -drm_public void fd_ringbuffer_del(struct fd_ringbuffer *ring) -{ - if (!atomic_dec_and_test(&ring->refcnt)) - return; - - fd_ringbuffer_reset(ring); - ring->funcs->destroy(ring); -} - -drm_public struct fd_ringbuffer * -fd_ringbuffer_ref(struct fd_ringbuffer *ring) -{ - STATIC_ASSERT(sizeof(ring->refcnt) <= sizeof(ring->__pad)); - atomic_inc(&ring->refcnt); - return ring; -} - -/* ringbuffers which are IB targets should set the toplevel rb (ie. - * the IB source) as it's parent before emitting reloc's, to ensure - * the bookkeeping works out properly. - */ -drm_public void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring, - struct fd_ringbuffer *parent) -{ - /* state objects should not be parented! */ - assert(!(ring->flags & FD_RINGBUFFER_OBJECT)); - ring->parent = parent; -} - -drm_public void fd_ringbuffer_reset(struct fd_ringbuffer *ring) -{ - uint32_t *start = ring->start; - if (ring->pipe->id == FD_PIPE_2D) - start = &ring->start[0x140]; - ring->cur = ring->last_start = start; - if (ring->funcs->reset) - ring->funcs->reset(ring); -} - -drm_public int fd_ringbuffer_flush(struct fd_ringbuffer *ring) -{ - return ring->funcs->flush(ring, ring->last_start, -1, NULL); -} - -drm_public int fd_ringbuffer_flush2(struct fd_ringbuffer *ring, int in_fence_fd, - int *out_fence_fd) -{ - return ring->funcs->flush(ring, ring->last_start, in_fence_fd, out_fence_fd); -} - -drm_public void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords) -{ - assert(ring->funcs->grow); /* unsupported on kgsl */ - - /* there is an upper bound on IB size, which appears to be 0x100000 */ - if (ring->size < 0x100000) - ring->size *= 2; - - ring->funcs->grow(ring, ring->size); - - ring->start = ring->funcs->hostptr(ring); - ring->end = &(ring->start[ring->size/4]); - - ring->cur = ring->last_start = ring->start; -} - -drm_public uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring) -{ - return ring->last_timestamp; -} - -drm_public void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, - const struct fd_reloc *reloc) -{ - assert(ring->pipe->gpu_id < 500); - ring->funcs->emit_reloc(ring, reloc); -} - -drm_public void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring, - const struct fd_reloc *reloc) -{ - ring->funcs->emit_reloc(ring, reloc); -} - -drm_public uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring) -{ - if (!ring->funcs->cmd_count) - return 1; - return ring->funcs->cmd_count(ring); -} - -drm_public uint32_t -fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring, - struct fd_ringbuffer *target, uint32_t cmd_idx) -{ - return ring->funcs->emit_reloc_ring(ring, target, cmd_idx); -} - -drm_public uint32_t -fd_ringbuffer_size(struct fd_ringbuffer *ring) -{ - /* only really needed for stateobj ringbuffers, and won't really - * do what you expect for growable rb's.. so lets just restrict - * this to stateobj's for now: - */ - assert(ring->flags & FD_RINGBUFFER_OBJECT); - return offset_bytes(ring->cur, ring->start); -} - diff --git a/freedreno/freedreno_ringbuffer.h b/freedreno/freedreno_ringbuffer.h deleted file mode 100644 index bc41a31c..00000000 --- a/freedreno/freedreno_ringbuffer.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#ifndef FREEDRENO_RINGBUFFER_H_ -#define FREEDRENO_RINGBUFFER_H_ - -#include <freedreno_drmif.h> - -/* the ringbuffer object is not opaque so that OUT_RING() type stuff - * can be inlined. Note that users should not make assumptions about - * the size of this struct. - */ - -struct fd_ringbuffer_funcs; - -enum fd_ringbuffer_flags { - - /* Ringbuffer is a "state object", which is potentially reused - * many times, rather than being used in one-shot mode linked - * to a parent ringbuffer. - */ - FD_RINGBUFFER_OBJECT = 0x1, - - /* Hint that the stateobj will be used for streaming state - * that is used once or a few times and then discarded. - * - * For sub-allocation, non streaming stateobj's should be - * sub-allocated from a page size buffer, so one long lived - * state obj doesn't prevent other pages from being freed. - * (Ie. it would be no worse than allocating a page sized - * bo for each small non-streaming stateobj). - * - * But streaming stateobj's could be sub-allocated from a - * larger buffer to reduce the alloc/del overhead. - */ - FD_RINGBUFFER_STREAMING = 0x2, -}; - -struct fd_ringbuffer { - int size; - uint32_t *cur, *end, *start, *last_start; - struct fd_pipe *pipe; - const struct fd_ringbuffer_funcs *funcs; - uint32_t last_timestamp; - struct fd_ringbuffer *parent; - - /* for users of fd_ringbuffer to store their own private per- - * ringbuffer data - */ - void *user; - - enum fd_ringbuffer_flags flags; - - /* This is a bit gross, but we can't use atomic_t in exported - * headers. OTOH, we don't need the refcnt to be publicly - * visible. The only reason that this struct is exported is - * because fd_ringbuffer_emit needs to be something that can - * be inlined for performance reasons. - */ - union { -#ifdef HAS_ATOMIC_OPS - atomic_t refcnt; -#endif - uint64_t __pad; - }; -}; - -struct fd_ringbuffer * fd_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size); -will_be_deprecated -struct fd_ringbuffer * fd_ringbuffer_new_object(struct fd_pipe *pipe, - uint32_t size); -struct fd_ringbuffer * fd_ringbuffer_new_flags(struct fd_pipe *pipe, - uint32_t size, enum fd_ringbuffer_flags flags); - -struct fd_ringbuffer *fd_ringbuffer_ref(struct fd_ringbuffer *ring); -void fd_ringbuffer_del(struct fd_ringbuffer *ring); -void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring, - struct fd_ringbuffer *parent); -will_be_deprecated -void fd_ringbuffer_reset(struct fd_ringbuffer *ring); -int fd_ringbuffer_flush(struct fd_ringbuffer *ring); -/* in_fence_fd: -1 for no in-fence, else fence fd - * out_fence_fd: NULL for no output-fence requested, else ptr to return out-fence - */ -int fd_ringbuffer_flush2(struct fd_ringbuffer *ring, int in_fence_fd, - int *out_fence_fd); -void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords); -uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring); - -static inline void fd_ringbuffer_emit(struct fd_ringbuffer *ring, - uint32_t data) -{ - (*ring->cur++) = data; -} - -struct fd_reloc { - struct fd_bo *bo; -#define FD_RELOC_READ 0x0001 -#define FD_RELOC_WRITE 0x0002 - uint32_t flags; - uint32_t offset; - uint32_t or; - int32_t shift; - uint32_t orhi; /* used for a5xx+ */ -}; - -/* NOTE: relocs are 2 dwords on a5xx+ */ - -void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring, const struct fd_reloc *reloc); -will_be_deprecated void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, const struct fd_reloc *reloc); -uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring); -uint32_t fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring, - struct fd_ringbuffer *target, uint32_t cmd_idx); -uint32_t fd_ringbuffer_size(struct fd_ringbuffer *ring); - -#endif /* FREEDRENO_RINGBUFFER_H_ */ diff --git a/freedreno/kgsl/README b/freedreno/kgsl/README deleted file mode 100644 index c46ba08b..00000000 --- a/freedreno/kgsl/README +++ /dev/null @@ -1,26 +0,0 @@ -This is a historical description of what is now the kgsl backend -in libdrm freedreno (before the upstream drm/msm driver). Note -that the kgsl backend requires the "kgsl-drm" shim driver, which -usually is in disrepair (QCOM does not build it for android), and -due to random differences between different downstream android -kernel branches it may or may not work. So YMMV. - -Original README: ----------------- - -Note that current msm kernel driver is a bit strange. It provides a -DRM interface for GEM, which is basically sufficient to have DRI2 -working. But it does not provide KMS. And interface to 2d and 3d -cores is via different other devices (/dev/kgsl-*). This is not -quite how I'd write a DRM driver, but at this stage it is useful for -xf86-video-freedreno and fdre (and eventual gallium driver) to be -able to work on existing kernel driver from QCOM, to allow to -capture cmdstream dumps from the binary blob drivers without having -to reboot. So libdrm_freedreno attempts to hide most of the crazy. -The intention is that when there is a proper kernel driver, it will -be mostly just changes in libdrm_freedreno to adapt the gallium -driver and xf86-video-freedreno (ignoring the fbdev->KMS changes). - -So don't look at freedreno as an example of how to write a libdrm -module or a DRM driver.. it is just an attempt to paper over a non- -standard kernel driver architecture. diff --git a/freedreno/kgsl/kgsl_bo.c b/freedreno/kgsl/kgsl_bo.c deleted file mode 100644 index 55b6e5c0..00000000 --- a/freedreno/kgsl/kgsl_bo.c +++ /dev/null @@ -1,309 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include "kgsl_priv.h" - -static int set_memtype(struct fd_device *dev, uint32_t handle, uint32_t flags) -{ - struct drm_kgsl_gem_memtype req = { - .handle = handle, - .type = flags & DRM_FREEDRENO_GEM_TYPE_MEM_MASK, - }; - - return drmCommandWrite(dev->fd, DRM_KGSL_GEM_SETMEMTYPE, - &req, sizeof(req)); -} - -static int bo_alloc(struct kgsl_bo *kgsl_bo) -{ - struct fd_bo *bo = &kgsl_bo->base; - if (!kgsl_bo->offset) { - struct drm_kgsl_gem_alloc req = { - .handle = bo->handle, - }; - int ret; - - /* if the buffer is already backed by pages then this - * doesn't actually do anything (other than giving us - * the offset) - */ - ret = drmCommandWriteRead(bo->dev->fd, DRM_KGSL_GEM_ALLOC, - &req, sizeof(req)); - if (ret) { - ERROR_MSG("alloc failed: %s", strerror(errno)); - return ret; - } - - kgsl_bo->offset = req.offset; - } - - return 0; -} - -static int kgsl_bo_offset(struct fd_bo *bo, uint64_t *offset) -{ - struct kgsl_bo *kgsl_bo = to_kgsl_bo(bo); - int ret = bo_alloc(kgsl_bo); - if (ret) - return ret; - *offset = kgsl_bo->offset; - return 0; -} - -static int kgsl_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) -{ - uint32_t timestamp = kgsl_bo_get_timestamp(to_kgsl_bo(bo)); - - if (op & DRM_FREEDRENO_PREP_NOSYNC) { - uint32_t current; - int ret; - - /* special case for is_idle().. we can't really handle that - * properly in kgsl (perhaps we need a way to just disable - * the bo-cache for kgsl?) - */ - if (!pipe) - return -EBUSY; - - ret = kgsl_pipe_timestamp(to_kgsl_pipe(pipe), ¤t); - if (ret) - return ret; - - if (timestamp > current) - return -EBUSY; - - return 0; - } - - if (timestamp) - fd_pipe_wait(pipe, timestamp); - - return 0; -} - -static void kgsl_bo_cpu_fini(struct fd_bo *bo) -{ -} - -static int kgsl_bo_madvise(struct fd_bo *bo, int willneed) -{ - return willneed; /* not supported by kgsl */ -} - -static void kgsl_bo_destroy(struct fd_bo *bo) -{ - struct kgsl_bo *kgsl_bo = to_kgsl_bo(bo); - free(kgsl_bo); - -} - -static const struct fd_bo_funcs funcs = { - .offset = kgsl_bo_offset, - .cpu_prep = kgsl_bo_cpu_prep, - .cpu_fini = kgsl_bo_cpu_fini, - .madvise = kgsl_bo_madvise, - .destroy = kgsl_bo_destroy, -}; - -/* allocate a buffer handle: */ -drm_private int kgsl_bo_new_handle(struct fd_device *dev, - uint32_t size, uint32_t flags, uint32_t *handle) -{ - struct drm_kgsl_gem_create req = { - .size = size, - }; - int ret; - - ret = drmCommandWriteRead(dev->fd, DRM_KGSL_GEM_CREATE, - &req, sizeof(req)); - if (ret) - return ret; - - // TODO make flags match msm driver, since kgsl is legacy.. - // translate flags in kgsl.. - - set_memtype(dev, req.handle, flags); - - *handle = req.handle; - - return 0; -} - -/* allocate a new buffer object */ -drm_private struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev, - uint32_t size, uint32_t handle) -{ - struct kgsl_bo *kgsl_bo; - struct fd_bo *bo; - unsigned i; - - kgsl_bo = calloc(1, sizeof(*kgsl_bo)); - if (!kgsl_bo) - return NULL; - - bo = &kgsl_bo->base; - bo->funcs = &funcs; - - for (i = 0; i < ARRAY_SIZE(kgsl_bo->list); i++) - list_inithead(&kgsl_bo->list[i]); - - return bo; -} - -drm_public struct fd_bo * -fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size) -{ - struct fd_bo *bo; - - if (!is_kgsl_pipe(pipe)) - return NULL; - - bo = fd_bo_new(pipe->dev, 1, 0); - - /* this is fugly, but works around a bug in the kernel.. - * priv->memdesc.size never gets set, so getbufinfo ioctl - * thinks the buffer hasn't be allocate and fails - */ - if (bo) { - void *fbmem = drm_mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_SHARED, fbfd, 0); - struct kgsl_map_user_mem req = { - .memtype = KGSL_USER_MEM_TYPE_ADDR, - .len = size, - .offset = 0, - .hostptr = (unsigned long)fbmem, - }; - struct kgsl_bo *kgsl_bo = to_kgsl_bo(bo); - int ret; - - ret = ioctl(to_kgsl_pipe(pipe)->fd, IOCTL_KGSL_MAP_USER_MEM, &req); - if (ret) { - ERROR_MSG("mapping user mem failed: %s", - strerror(errno)); - goto fail; - } - kgsl_bo->gpuaddr = req.gpuaddr; - bo->map = fbmem; - } - - return bo; -fail: - if (bo) - fd_bo_del(bo); - return NULL; -} - -drm_private uint32_t kgsl_bo_gpuaddr(struct kgsl_bo *kgsl_bo, uint32_t offset) -{ - struct fd_bo *bo = &kgsl_bo->base; - if (!kgsl_bo->gpuaddr) { - struct drm_kgsl_gem_bufinfo req = { - .handle = bo->handle, - }; - int ret; - - ret = bo_alloc(kgsl_bo); - if (ret) { - return ret; - } - - ret = drmCommandWriteRead(bo->dev->fd, DRM_KGSL_GEM_GET_BUFINFO, - &req, sizeof(req)); - if (ret) { - ERROR_MSG("get bufinfo failed: %s", strerror(errno)); - return 0; - } - - kgsl_bo->gpuaddr = req.gpuaddr[0]; - } - return kgsl_bo->gpuaddr + offset; -} - -/* - * Super-cheezy way to synchronization between mesa and ddx.. the - * SET_ACTIVE ioctl gives us a way to stash a 32b # w/ a GEM bo, and - * GET_BUFINFO gives us a way to retrieve it. We use this to stash - * the timestamp of the last ISSUEIBCMDS on the buffer. - * - * To avoid an obscene amount of syscalls, we: - * 1) Only set the timestamp for buffers w/ an flink name, ie. - * only buffers shared across processes. This is enough to - * catch the DRI2 buffers. - * 2) Only set the timestamp for buffers submitted to the 3d ring - * and only check the timestamps on buffers submitted to the - * 2d ring. This should be enough to handle synchronizing of - * presentation blit. We could do synchronization in the other - * direction too, but that would be problematic if we are using - * the 3d ring from DDX, since client side wouldn't know this. - * - * The waiting on timestamp happens before flush, and setting of - * timestamp happens after flush. It is transparent to the user - * of libdrm_freedreno as all the tracking of buffers happens via - * _emit_reloc().. - */ - -drm_private void kgsl_bo_set_timestamp(struct kgsl_bo *kgsl_bo, - uint32_t timestamp) -{ - struct fd_bo *bo = &kgsl_bo->base; - if (bo->name) { - struct drm_kgsl_gem_active req = { - .handle = bo->handle, - .active = timestamp, - }; - int ret; - - ret = drmCommandWrite(bo->dev->fd, DRM_KGSL_GEM_SET_ACTIVE, - &req, sizeof(req)); - if (ret) { - ERROR_MSG("set active failed: %s", strerror(errno)); - } - } -} - -drm_private uint32_t kgsl_bo_get_timestamp(struct kgsl_bo *kgsl_bo) -{ - struct fd_bo *bo = &kgsl_bo->base; - uint32_t timestamp = 0; - if (bo->name) { - struct drm_kgsl_gem_bufinfo req = { - .handle = bo->handle, - }; - int ret; - - ret = drmCommandWriteRead(bo->dev->fd, DRM_KGSL_GEM_GET_BUFINFO, - &req, sizeof(req)); - if (ret) { - ERROR_MSG("get bufinfo failed: %s", strerror(errno)); - return 0; - } - - timestamp = req.active; - } - return timestamp; -} diff --git a/freedreno/kgsl/kgsl_device.c b/freedreno/kgsl/kgsl_device.c deleted file mode 100644 index 914f3412..00000000 --- a/freedreno/kgsl/kgsl_device.c +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "kgsl_priv.h" - -static void kgsl_device_destroy(struct fd_device *dev) -{ - struct kgsl_device *kgsl_dev = to_kgsl_device(dev); - free(kgsl_dev); -} - -static const struct fd_device_funcs funcs = { - .bo_new_handle = kgsl_bo_new_handle, - .bo_from_handle = kgsl_bo_from_handle, - .pipe_new = kgsl_pipe_new, - .destroy = kgsl_device_destroy, -}; - -drm_private struct fd_device * kgsl_device_new(int fd) -{ - struct kgsl_device *kgsl_dev; - struct fd_device *dev; - - kgsl_dev = calloc(1, sizeof(*kgsl_dev)); - if (!kgsl_dev) - return NULL; - - dev = &kgsl_dev->base; - dev->funcs = &funcs; - - dev->bo_size = sizeof(struct kgsl_bo); - - return dev; -} diff --git a/freedreno/kgsl/kgsl_drm.h b/freedreno/kgsl/kgsl_drm.h deleted file mode 100644 index 281978ea..00000000 --- a/freedreno/kgsl/kgsl_drm.h +++ /dev/null @@ -1,192 +0,0 @@ -#ifndef _KGSL_DRM_H_ -#define _KGSL_DRM_H_ - -#include "drm.h" - -#define DRM_KGSL_GEM_CREATE 0x00 -#define DRM_KGSL_GEM_PREP 0x01 -#define DRM_KGSL_GEM_SETMEMTYPE 0x02 -#define DRM_KGSL_GEM_GETMEMTYPE 0x03 -#define DRM_KGSL_GEM_MMAP 0x04 -#define DRM_KGSL_GEM_ALLOC 0x05 -#define DRM_KGSL_GEM_BIND_GPU 0x06 -#define DRM_KGSL_GEM_UNBIND_GPU 0x07 - -#define DRM_KGSL_GEM_GET_BUFINFO 0x08 -#define DRM_KGSL_GEM_SET_BUFCOUNT 0x09 -#define DRM_KGSL_GEM_SET_ACTIVE 0x0A -#define DRM_KGSL_GEM_LOCK_HANDLE 0x0B -#define DRM_KGSL_GEM_UNLOCK_HANDLE 0x0C -#define DRM_KGSL_GEM_UNLOCK_ON_TS 0x0D -#define DRM_KGSL_GEM_CREATE_FD 0x0E - -#define DRM_IOCTL_KGSL_GEM_CREATE \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_CREATE, struct drm_kgsl_gem_create) - -#define DRM_IOCTL_KGSL_GEM_PREP \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_PREP, struct drm_kgsl_gem_prep) - -#define DRM_IOCTL_KGSL_GEM_SETMEMTYPE \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_SETMEMTYPE, \ -struct drm_kgsl_gem_memtype) - -#define DRM_IOCTL_KGSL_GEM_GETMEMTYPE \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_GETMEMTYPE, \ -struct drm_kgsl_gem_memtype) - -#define DRM_IOCTL_KGSL_GEM_MMAP \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_MMAP, struct drm_kgsl_gem_mmap) - -#define DRM_IOCTL_KGSL_GEM_ALLOC \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_ALLOC, struct drm_kgsl_gem_alloc) - -#define DRM_IOCTL_KGSL_GEM_BIND_GPU \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_BIND_GPU, struct drm_kgsl_gem_bind_gpu) - -#define DRM_IOCTL_KGSL_GEM_UNBIND_GPU \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_UNBIND_GPU, \ -struct drm_kgsl_gem_bind_gpu) - -#define DRM_IOCTL_KGSL_GEM_GET_BUFINFO \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_GET_BUFINFO, \ - struct drm_kgsl_gem_bufinfo) - -#define DRM_IOCTL_KGSL_GEM_SET_BUFCOUNT \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_SET_BUFCOUNT, \ - struct drm_kgsl_gem_bufcount) - -#define DRM_IOCTL_KGSL_GEM_SET_ACTIVE \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_SET_ACTIVE, \ - struct drm_kgsl_gem_active) - -#define DRM_IOCTL_KGSL_GEM_LOCK_HANDLE \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_LOCK_HANDLE, \ -struct drm_kgsl_gem_lock_handles) - -#define DRM_IOCTL_KGSL_GEM_UNLOCK_HANDLE \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_UNLOCK_HANDLE, \ -struct drm_kgsl_gem_unlock_handles) - -#define DRM_IOCTL_KGSL_GEM_UNLOCK_ON_TS \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_UNLOCK_ON_TS, \ -struct drm_kgsl_gem_unlock_on_ts) - -#define DRM_IOCTL_KGSL_GEM_CREATE_FD \ -DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_CREATE_FD, \ -struct drm_kgsl_gem_create_fd) - -/* Maximum number of sub buffers per GEM object */ -#define DRM_KGSL_GEM_MAX_BUFFERS 2 - -/* Memory types - these define the source and caching policies - of the GEM memory chunk */ - -/* Legacy definitions left for compatibility */ - -#define DRM_KGSL_GEM_TYPE_EBI 0 -#define DRM_KGSL_GEM_TYPE_SMI 1 -#define DRM_KGSL_GEM_TYPE_KMEM 2 -#define DRM_KGSL_GEM_TYPE_KMEM_NOCACHE 3 -#define DRM_KGSL_GEM_TYPE_MEM_MASK 0xF - -/* Contiguous memory (PMEM) */ -#define DRM_KGSL_GEM_TYPE_PMEM 0x000100 - -/* PMEM memory types */ -#define DRM_KGSL_GEM_PMEM_EBI 0x001000 -#define DRM_KGSL_GEM_PMEM_SMI 0x002000 - -/* Standard paged memory */ -#define DRM_KGSL_GEM_TYPE_MEM 0x010000 - -/* Caching controls */ -#define DRM_KGSL_GEM_CACHE_NONE 0x000000 -#define DRM_KGSL_GEM_CACHE_WCOMBINE 0x100000 -#define DRM_KGSL_GEM_CACHE_WTHROUGH 0x200000 -#define DRM_KGSL_GEM_CACHE_WBACK 0x400000 -#define DRM_KGSL_GEM_CACHE_WBACKWA 0x800000 -#define DRM_KGSL_GEM_CACHE_MASK 0xF00000 - -/* FD based objects */ -#define DRM_KGSL_GEM_TYPE_FD_FBMEM 0x1000000 -#define DRM_KGSL_GEM_TYPE_FD_MASK 0xF000000 - -/* Timestamp types */ -#define DRM_KGSL_GEM_TS_3D 0x00000430 -#define DRM_KGSL_GEM_TS_2D 0x00000180 - - -struct drm_kgsl_gem_create { - uint32_t size; - uint32_t handle; -}; - -struct drm_kgsl_gem_prep { - uint32_t handle; - uint32_t phys; - uint64_t offset; -}; - -struct drm_kgsl_gem_memtype { - uint32_t handle; - uint32_t type; -}; - -struct drm_kgsl_gem_mmap { - uint32_t handle; - uint32_t size; - uint32_t hostptr; - uint64_t offset; -}; - -struct drm_kgsl_gem_alloc { - uint32_t handle; - uint64_t offset; -}; - -struct drm_kgsl_gem_bind_gpu { - uint32_t handle; - uint32_t gpuptr; -}; - -struct drm_kgsl_gem_bufinfo { - uint32_t handle; - uint32_t count; - uint32_t active; - uint32_t offset[DRM_KGSL_GEM_MAX_BUFFERS]; - uint32_t gpuaddr[DRM_KGSL_GEM_MAX_BUFFERS]; -}; - -struct drm_kgsl_gem_bufcount { - uint32_t handle; - uint32_t bufcount; -}; - -struct drm_kgsl_gem_active { - uint32_t handle; - uint32_t active; -}; - -struct drm_kgsl_gem_lock_handles { - uint32_t num_handles; - uint32_t *handle_list; - uint32_t pid; - uint32_t lock_id; /* Returned lock id used for unlocking */ -}; - -struct drm_kgsl_gem_unlock_handles { - uint32_t lock_id; -}; - -struct drm_kgsl_gem_unlock_on_ts { - uint32_t lock_id; - uint32_t timestamp; /* This field is a hw generated ts */ - uint32_t type; /* Which pipe to check for ts generation */ -}; - -struct drm_kgsl_gem_create_fd { - uint32_t fd; - uint32_t handle; -}; - -#endif diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c deleted file mode 100644 index 0a8b6586..00000000 --- a/freedreno/kgsl/kgsl_pipe.c +++ /dev/null @@ -1,282 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include "kgsl_priv.h" - - -static int kgsl_pipe_get_param(struct fd_pipe *pipe, - enum fd_param_id param, uint64_t *value) -{ - struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe); - switch (param) { - case FD_DEVICE_ID: - *value = kgsl_pipe->devinfo.device_id; - return 0; - case FD_GPU_ID: - *value = kgsl_pipe->devinfo.gpu_id; - return 0; - case FD_GMEM_SIZE: - *value = kgsl_pipe->devinfo.gmem_sizebytes; - return 0; - case FD_CHIP_ID: - *value = kgsl_pipe->devinfo.chip_id; - return 0; - case FD_MAX_FREQ: - case FD_TIMESTAMP: - case FD_NR_RINGS: - /* unsupported on kgsl */ - return -1; - default: - ERROR_MSG("invalid param id: %d", param); - return -1; - } -} - -static int kgsl_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp, - uint64_t timeout) -{ - struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe); - struct kgsl_device_waittimestamp req = { - .timestamp = timestamp, - .timeout = 5000, - }; - int ret; - - do { - ret = ioctl(kgsl_pipe->fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP, &req); - } while ((ret == -1) && ((errno == EINTR) || (errno == EAGAIN))); - if (ret) - ERROR_MSG("waittimestamp failed! %d (%s)", ret, strerror(errno)); - else - kgsl_pipe_process_pending(kgsl_pipe, timestamp); - return ret; -} - -drm_private int kgsl_pipe_timestamp(struct kgsl_pipe *kgsl_pipe, - uint32_t *timestamp) -{ - struct kgsl_cmdstream_readtimestamp req = { - .type = KGSL_TIMESTAMP_RETIRED - }; - int ret = ioctl(kgsl_pipe->fd, IOCTL_KGSL_CMDSTREAM_READTIMESTAMP, &req); - if (ret) { - ERROR_MSG("readtimestamp failed! %d (%s)", - ret, strerror(errno)); - return ret; - } - *timestamp = req.timestamp; - return 0; -} - -static void kgsl_pipe_destroy(struct fd_pipe *pipe) -{ - struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe); - struct kgsl_drawctxt_destroy req = { - .drawctxt_id = kgsl_pipe->drawctxt_id, - }; - - if (kgsl_pipe->drawctxt_id) - ioctl(kgsl_pipe->fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &req); - - if (kgsl_pipe->fd >= 0) - close(kgsl_pipe->fd); - - free(kgsl_pipe); -} - -static const struct fd_pipe_funcs funcs = { - .ringbuffer_new = kgsl_ringbuffer_new, - .get_param = kgsl_pipe_get_param, - .wait = kgsl_pipe_wait, - .destroy = kgsl_pipe_destroy, -}; - -drm_private int is_kgsl_pipe(struct fd_pipe *pipe) -{ - return pipe->funcs == &funcs; -} - -/* add buffer to submit list when it is referenced in cmdstream: */ -drm_private void kgsl_pipe_add_submit(struct kgsl_pipe *kgsl_pipe, - struct kgsl_bo *kgsl_bo) -{ - struct fd_pipe *pipe = &kgsl_pipe->base; - struct fd_bo *bo = &kgsl_bo->base; - struct list_head *list = &kgsl_bo->list[pipe->id]; - if (LIST_IS_EMPTY(list)) { - fd_bo_ref(bo); - } else { - list_del(list); - } - list_addtail(list, &kgsl_pipe->submit_list); -} - -/* prepare buffers on submit list before flush: */ -drm_private void kgsl_pipe_pre_submit(struct kgsl_pipe *kgsl_pipe) -{ - struct fd_pipe *pipe = &kgsl_pipe->base; - struct kgsl_bo *kgsl_bo = NULL; - - if (!kgsl_pipe->p3d) - kgsl_pipe->p3d = fd_pipe_new(pipe->dev, FD_PIPE_3D); - - LIST_FOR_EACH_ENTRY(kgsl_bo, &kgsl_pipe->submit_list, list[pipe->id]) { - uint32_t timestamp = kgsl_bo_get_timestamp(kgsl_bo); - if (timestamp) - fd_pipe_wait(kgsl_pipe->p3d, timestamp); - } -} - -/* process buffers on submit list after flush: */ -drm_private void kgsl_pipe_post_submit(struct kgsl_pipe *kgsl_pipe, - uint32_t timestamp) -{ - struct fd_pipe *pipe = &kgsl_pipe->base; - struct kgsl_bo *kgsl_bo = NULL, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(kgsl_bo, tmp, &kgsl_pipe->submit_list, list[pipe->id]) { - struct list_head *list = &kgsl_bo->list[pipe->id]; - list_del(list); - kgsl_bo->timestamp[pipe->id] = timestamp; - list_addtail(list, &kgsl_pipe->pending_list); - - kgsl_bo_set_timestamp(kgsl_bo, timestamp); - } - - if (!kgsl_pipe_timestamp(kgsl_pipe, ×tamp)) - kgsl_pipe_process_pending(kgsl_pipe, timestamp); -} - -drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *kgsl_pipe, - uint32_t timestamp) -{ - struct fd_pipe *pipe = &kgsl_pipe->base; - struct kgsl_bo *kgsl_bo = NULL, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(kgsl_bo, tmp, &kgsl_pipe->pending_list, list[pipe->id]) { - struct list_head *list = &kgsl_bo->list[pipe->id]; - if (kgsl_bo->timestamp[pipe->id] > timestamp) - return; - list_delinit(list); - kgsl_bo->timestamp[pipe->id] = 0; - fd_bo_del(&kgsl_bo->base); - } -} - -static int getprop(int fd, enum kgsl_property_type type, - void *value, int sizebytes) -{ - struct kgsl_device_getproperty req = { - .type = type, - .value = value, - .sizebytes = sizebytes, - }; - return ioctl(fd, IOCTL_KGSL_DEVICE_GETPROPERTY, &req); -} - -#define GETPROP(fd, prop, x) do { \ - if (getprop((fd), KGSL_PROP_##prop, &(x), sizeof(x))) { \ - ERROR_MSG("failed to get property: " #prop); \ - goto fail; \ - } } while (0) - - -drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, - enum fd_pipe_id id, uint32_t prio) -{ - static const char *paths[] = { - [FD_PIPE_3D] = "/dev/kgsl-3d0", - [FD_PIPE_2D] = "/dev/kgsl-2d0", - }; - struct kgsl_drawctxt_create req = { - .flags = 0x2000, /* ??? */ - }; - struct kgsl_pipe *kgsl_pipe = NULL; - struct fd_pipe *pipe = NULL; - int ret, fd; - - fd = open(paths[id], O_RDWR); - if (fd < 0) { - ERROR_MSG("could not open %s device: %d (%s)", - paths[id], fd, strerror(errno)); - goto fail; - } - - ret = ioctl(fd, IOCTL_KGSL_DRAWCTXT_CREATE, &req); - if (ret) { - ERROR_MSG("failed to allocate context: %d (%s)", - ret, strerror(errno)); - goto fail; - } - - kgsl_pipe = calloc(1, sizeof(*kgsl_pipe)); - if (!kgsl_pipe) { - ERROR_MSG("allocation failed"); - goto fail; - } - - pipe = &kgsl_pipe->base; - pipe->funcs = &funcs; - - kgsl_pipe->fd = fd; - kgsl_pipe->drawctxt_id = req.drawctxt_id; - - list_inithead(&kgsl_pipe->submit_list); - list_inithead(&kgsl_pipe->pending_list); - - GETPROP(fd, VERSION, kgsl_pipe->version); - GETPROP(fd, DEVICE_INFO, kgsl_pipe->devinfo); - - if (kgsl_pipe->devinfo.gpu_id >= 500) { - ERROR_MSG("64b unsupported with kgsl"); - goto fail; - } - - INFO_MSG("Pipe Info:"); - INFO_MSG(" Device: %s", paths[id]); - INFO_MSG(" Chip-id: %d.%d.%d.%d", - (kgsl_pipe->devinfo.chip_id >> 24) & 0xff, - (kgsl_pipe->devinfo.chip_id >> 16) & 0xff, - (kgsl_pipe->devinfo.chip_id >> 8) & 0xff, - (kgsl_pipe->devinfo.chip_id >> 0) & 0xff); - INFO_MSG(" Device-id: %d", kgsl_pipe->devinfo.device_id); - INFO_MSG(" GPU-id: %d", kgsl_pipe->devinfo.gpu_id); - INFO_MSG(" MMU enabled: %d", kgsl_pipe->devinfo.mmu_enabled); - INFO_MSG(" GMEM Base addr: 0x%08x", kgsl_pipe->devinfo.gmem_gpubaseaddr); - INFO_MSG(" GMEM size: 0x%08x", kgsl_pipe->devinfo.gmem_sizebytes); - INFO_MSG(" Driver version: %d.%d", - kgsl_pipe->version.drv_major, kgsl_pipe->version.drv_minor); - INFO_MSG(" Device version: %d.%d", - kgsl_pipe->version.dev_major, kgsl_pipe->version.dev_minor); - - return pipe; -fail: - if (pipe) - fd_pipe_del(pipe); - return NULL; -} diff --git a/freedreno/kgsl/kgsl_priv.h b/freedreno/kgsl/kgsl_priv.h deleted file mode 100644 index a6bf2d40..00000000 --- a/freedreno/kgsl/kgsl_priv.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#ifndef KGSL_PRIV_H_ -#define KGSL_PRIV_H_ - -#include "freedreno_priv.h" -#include "msm_kgsl.h" -#include "kgsl_drm.h" - -struct kgsl_device { - struct fd_device base; -}; - -static inline struct kgsl_device * to_kgsl_device(struct fd_device *x) -{ - return (struct kgsl_device *)x; -} - -struct kgsl_pipe { - struct fd_pipe base; - - int fd; - uint32_t drawctxt_id; - - /* device properties: */ - struct kgsl_version version; - struct kgsl_devinfo devinfo; - - /* list of bo's that are referenced in ringbuffer but not - * submitted yet: - */ - struct list_head submit_list; - - /* list of bo's that have been submitted but timestamp has - * not passed yet (so still ref'd in active cmdstream) - */ - struct list_head pending_list; - - /* if we are the 2d pipe, and want to wait on a timestamp - * from 3d, we need to also internally open the 3d pipe: - */ - struct fd_pipe *p3d; -}; - -static inline struct kgsl_pipe * to_kgsl_pipe(struct fd_pipe *x) -{ - return (struct kgsl_pipe *)x; -} - -drm_private int is_kgsl_pipe(struct fd_pipe *pipe); - -struct kgsl_bo { - struct fd_bo base; - uint64_t offset; - uint32_t gpuaddr; - /* timestamp (per pipe) for bo's in a pipe's pending_list: */ - uint32_t timestamp[FD_PIPE_MAX]; - /* list-node for pipe's submit_list or pending_list */ - struct list_head list[FD_PIPE_MAX]; -}; - -static inline struct kgsl_bo * to_kgsl_bo(struct fd_bo *x) -{ - return (struct kgsl_bo *)x; -} - - -drm_private struct fd_device * kgsl_device_new(int fd); - -drm_private int kgsl_pipe_timestamp(struct kgsl_pipe *kgsl_pipe, - uint32_t *timestamp); -drm_private void kgsl_pipe_add_submit(struct kgsl_pipe *pipe, - struct kgsl_bo *bo); -drm_private void kgsl_pipe_pre_submit(struct kgsl_pipe *pipe); -drm_private void kgsl_pipe_post_submit(struct kgsl_pipe *pipe, - uint32_t timestamp); -drm_private void kgsl_pipe_process_pending(struct kgsl_pipe *pipe, - uint32_t timestamp); -drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, - enum fd_pipe_id id, uint32_t prio); - -drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size, enum fd_ringbuffer_flags flags); - -drm_private int kgsl_bo_new_handle(struct fd_device *dev, - uint32_t size, uint32_t flags, uint32_t *handle); -drm_private struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev, - uint32_t size, uint32_t handle); - -drm_private uint32_t kgsl_bo_gpuaddr(struct kgsl_bo *bo, uint32_t offset); -drm_private void kgsl_bo_set_timestamp(struct kgsl_bo *bo, uint32_t timestamp); -drm_private uint32_t kgsl_bo_get_timestamp(struct kgsl_bo *bo); - -#endif /* KGSL_PRIV_H_ */ diff --git a/freedreno/kgsl/kgsl_ringbuffer.c b/freedreno/kgsl/kgsl_ringbuffer.c deleted file mode 100644 index 9abf0adf..00000000 --- a/freedreno/kgsl/kgsl_ringbuffer.c +++ /dev/null @@ -1,235 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include <assert.h> - -#include "xf86atomic.h" -#include "freedreno_ringbuffer.h" -#include "kgsl_priv.h" - - -/* because kgsl tries to validate the gpuaddr on kernel side in ISSUEIBCMDS, - * we can't use normal gem bo's for ringbuffer.. someday the kernel part - * needs to be reworked into a single sane drm driver :-/ - */ -struct kgsl_rb_bo { - struct kgsl_pipe *pipe; - void *hostptr; - uint32_t gpuaddr; - uint32_t size; -}; - -struct kgsl_ringbuffer { - struct fd_ringbuffer base; - struct kgsl_rb_bo *bo; -}; - -static inline struct kgsl_ringbuffer * to_kgsl_ringbuffer(struct fd_ringbuffer *x) -{ - return (struct kgsl_ringbuffer *)x; -} - -static void kgsl_rb_bo_del(struct kgsl_rb_bo *bo) -{ - struct kgsl_sharedmem_free req = { - .gpuaddr = bo->gpuaddr, - }; - int ret; - - drm_munmap(bo->hostptr, bo->size); - - ret = ioctl(bo->pipe->fd, IOCTL_KGSL_SHAREDMEM_FREE, &req); - if (ret) { - ERROR_MSG("sharedmem free failed: %s", strerror(errno)); - } - - free(bo); -} - -static struct kgsl_rb_bo * kgsl_rb_bo_new(struct kgsl_pipe *pipe, uint32_t size) -{ - struct kgsl_rb_bo *bo; - struct kgsl_gpumem_alloc req = { - .size = ALIGN(size, 4096), - .flags = KGSL_MEMFLAGS_GPUREADONLY, - }; - int ret; - - bo = calloc(1, sizeof(*bo)); - if (!bo) { - ERROR_MSG("allocation failed"); - return NULL; - } - ret = ioctl(pipe->fd, IOCTL_KGSL_GPUMEM_ALLOC, &req); - if (ret) { - ERROR_MSG("gpumem allocation failed: %s", strerror(errno)); - goto fail; - } - - bo->pipe = pipe; - bo->gpuaddr = req.gpuaddr; - bo->size = size; - bo->hostptr = drm_mmap(NULL, size, PROT_WRITE|PROT_READ, - MAP_SHARED, pipe->fd, req.gpuaddr); - - return bo; -fail: - if (bo) - kgsl_rb_bo_del(bo); - return NULL; -} - -static void * kgsl_ringbuffer_hostptr(struct fd_ringbuffer *ring) -{ - struct kgsl_ringbuffer *kgsl_ring = to_kgsl_ringbuffer(ring); - return kgsl_ring->bo->hostptr; -} - -static int kgsl_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start, - int in_fence_fd, int *out_fence_fd) -{ - struct kgsl_ringbuffer *kgsl_ring = to_kgsl_ringbuffer(ring); - struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(ring->pipe); - uint32_t offset = (uint8_t *)last_start - (uint8_t *)ring->start; - struct kgsl_ibdesc ibdesc = { - .gpuaddr = kgsl_ring->bo->gpuaddr + offset, - .hostptr = last_start, - .sizedwords = ring->cur - last_start, - }; - struct kgsl_ringbuffer_issueibcmds req = { - .drawctxt_id = kgsl_pipe->drawctxt_id, - .ibdesc_addr = (unsigned long)&ibdesc, - .numibs = 1, - .flags = KGSL_CONTEXT_SUBMIT_IB_LIST, - }; - int ret; - - assert(in_fence_fd == -1); - assert(out_fence_fd == NULL); - - kgsl_pipe_pre_submit(kgsl_pipe); - - /* z180_cmdstream_issueibcmds() is made of fail: */ - if (ring->pipe->id == FD_PIPE_2D) { - /* fix up size field in last cmd packet */ - uint32_t last_size = (uint32_t)(ring->cur - last_start); - /* 5 is length of first packet, 2 for the two 7f000000's */ - last_start[2] = last_size - (5 + 2); - ibdesc.gpuaddr = kgsl_ring->bo->gpuaddr; - ibdesc.hostptr = kgsl_ring->bo->hostptr; - ibdesc.sizedwords = 0x145; - req.timestamp = (uintptr_t)kgsl_ring->bo->hostptr; - } - - do { - ret = ioctl(kgsl_pipe->fd, IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS, &req); - } while ((ret == -1) && ((errno == EINTR) || (errno == EAGAIN))); - if (ret) - ERROR_MSG("issueibcmds failed! %d (%s)", ret, strerror(errno)); - - ring->last_timestamp = req.timestamp; - ring->last_start = ring->cur; - - kgsl_pipe_post_submit(kgsl_pipe, req.timestamp); - - return ret; -} - -static void kgsl_ringbuffer_emit_reloc(struct fd_ringbuffer *ring, - const struct fd_reloc *r) -{ - struct kgsl_bo *kgsl_bo = to_kgsl_bo(r->bo); - uint32_t addr = kgsl_bo_gpuaddr(kgsl_bo, r->offset); - assert(addr); - if (r->shift < 0) - addr >>= -r->shift; - else - addr <<= r->shift; - (*ring->cur++) = addr | r->or; - kgsl_pipe_add_submit(to_kgsl_pipe(ring->pipe), kgsl_bo); -} - -static uint32_t kgsl_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, - struct fd_ringbuffer *target, uint32_t cmd_idx) -{ - struct kgsl_ringbuffer *target_ring = to_kgsl_ringbuffer(target); - assert(cmd_idx == 0); - (*ring->cur++) = target_ring->bo->gpuaddr; - return offset_bytes(target->cur, target->start); -} - -static void kgsl_ringbuffer_destroy(struct fd_ringbuffer *ring) -{ - struct kgsl_ringbuffer *kgsl_ring = to_kgsl_ringbuffer(ring); - if (ring->last_timestamp) - fd_pipe_wait(ring->pipe, ring->last_timestamp); - if (kgsl_ring->bo) - kgsl_rb_bo_del(kgsl_ring->bo); - free(kgsl_ring); -} - -static const struct fd_ringbuffer_funcs funcs = { - .hostptr = kgsl_ringbuffer_hostptr, - .flush = kgsl_ringbuffer_flush, - .emit_reloc = kgsl_ringbuffer_emit_reloc, - .emit_reloc_ring = kgsl_ringbuffer_emit_reloc_ring, - .destroy = kgsl_ringbuffer_destroy, -}; - -drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size, enum fd_ringbuffer_flags flags) -{ - struct kgsl_ringbuffer *kgsl_ring; - struct fd_ringbuffer *ring = NULL; - - assert(!flags); - - kgsl_ring = calloc(1, sizeof(*kgsl_ring)); - if (!kgsl_ring) { - ERROR_MSG("allocation failed"); - goto fail; - } - - ring = &kgsl_ring->base; - atomic_set(&ring->refcnt, 1); - - ring->funcs = &funcs; - ring->size = size; - - kgsl_ring->bo = kgsl_rb_bo_new(to_kgsl_pipe(pipe), size); - if (!kgsl_ring->bo) { - ERROR_MSG("ringbuffer allocation failed"); - goto fail; - } - - return ring; -fail: - if (ring) - fd_ringbuffer_del(ring); - return NULL; -} diff --git a/freedreno/kgsl/msm_kgsl.h b/freedreno/kgsl/msm_kgsl.h deleted file mode 100644 index 5b36eeb4..00000000 --- a/freedreno/kgsl/msm_kgsl.h +++ /dev/null @@ -1,519 +0,0 @@ -#ifndef _MSM_KGSL_H -#define _MSM_KGSL_H - -#define KGSL_VERSION_MAJOR 3 -#define KGSL_VERSION_MINOR 11 - -/*context flags */ -#define KGSL_CONTEXT_SAVE_GMEM 0x00000001 -#define KGSL_CONTEXT_NO_GMEM_ALLOC 0x00000002 -#define KGSL_CONTEXT_SUBMIT_IB_LIST 0x00000004 -#define KGSL_CONTEXT_CTX_SWITCH 0x00000008 -#define KGSL_CONTEXT_PREAMBLE 0x00000010 -#define KGSL_CONTEXT_TRASH_STATE 0x00000020 -#define KGSL_CONTEXT_PER_CONTEXT_TS 0x00000040 - -#define KGSL_CONTEXT_INVALID 0xffffffff - -/* Memory allocayion flags */ -#define KGSL_MEMFLAGS_GPUREADONLY 0x01000000 - -/* generic flag values */ -#define KGSL_FLAGS_NORMALMODE 0x00000000 -#define KGSL_FLAGS_SAFEMODE 0x00000001 -#define KGSL_FLAGS_INITIALIZED0 0x00000002 -#define KGSL_FLAGS_INITIALIZED 0x00000004 -#define KGSL_FLAGS_STARTED 0x00000008 -#define KGSL_FLAGS_ACTIVE 0x00000010 -#define KGSL_FLAGS_RESERVED0 0x00000020 -#define KGSL_FLAGS_RESERVED1 0x00000040 -#define KGSL_FLAGS_RESERVED2 0x00000080 -#define KGSL_FLAGS_SOFT_RESET 0x00000100 -#define KGSL_FLAGS_PER_CONTEXT_TIMESTAMPS 0x00000200 - -/* Clock flags to show which clocks should be controlled by a given platform */ -#define KGSL_CLK_SRC 0x00000001 -#define KGSL_CLK_CORE 0x00000002 -#define KGSL_CLK_IFACE 0x00000004 -#define KGSL_CLK_MEM 0x00000008 -#define KGSL_CLK_MEM_IFACE 0x00000010 -#define KGSL_CLK_AXI 0x00000020 - -/* - * Reset status values for context - */ -enum kgsl_ctx_reset_stat { - KGSL_CTX_STAT_NO_ERROR = 0x00000000, - KGSL_CTX_STAT_GUILTY_CONTEXT_RESET_EXT = 0x00000001, - KGSL_CTX_STAT_INNOCENT_CONTEXT_RESET_EXT = 0x00000002, - KGSL_CTX_STAT_UNKNOWN_CONTEXT_RESET_EXT = 0x00000003 -}; - -#define KGSL_MAX_PWRLEVELS 5 - -#define KGSL_CONVERT_TO_MBPS(val) \ - (val*1000*1000U) - -/* device id */ -enum kgsl_deviceid { - KGSL_DEVICE_3D0 = 0x00000000, - KGSL_DEVICE_2D0 = 0x00000001, - KGSL_DEVICE_2D1 = 0x00000002, - KGSL_DEVICE_MAX = 0x00000003 -}; - -enum kgsl_user_mem_type { - KGSL_USER_MEM_TYPE_PMEM = 0x00000000, - KGSL_USER_MEM_TYPE_ASHMEM = 0x00000001, - KGSL_USER_MEM_TYPE_ADDR = 0x00000002, - KGSL_USER_MEM_TYPE_ION = 0x00000003, - KGSL_USER_MEM_TYPE_MAX = 0x00000004, -}; - -struct kgsl_devinfo { - - unsigned int device_id; - /* chip revision id - * coreid:8 majorrev:8 minorrev:8 patch:8 - */ - unsigned int chip_id; - unsigned int mmu_enabled; - unsigned int gmem_gpubaseaddr; - /* - * This field contains the adreno revision - * number 200, 205, 220, etc... - */ - unsigned int gpu_id; - unsigned int gmem_sizebytes; -}; - -/* this structure defines the region of memory that can be mmap()ed from this - driver. The timestamp fields are volatile because they are written by the - GPU -*/ -struct kgsl_devmemstore { - volatile unsigned int soptimestamp; - unsigned int sbz; - volatile unsigned int eoptimestamp; - unsigned int sbz2; - volatile unsigned int ts_cmp_enable; - unsigned int sbz3; - volatile unsigned int ref_wait_ts; - unsigned int sbz4; - unsigned int current_context; - unsigned int sbz5; -}; - -#define KGSL_MEMSTORE_OFFSET(ctxt_id, field) \ - ((ctxt_id)*sizeof(struct kgsl_devmemstore) + \ - offsetof(struct kgsl_devmemstore, field)) - -/* timestamp id*/ -enum kgsl_timestamp_type { - KGSL_TIMESTAMP_CONSUMED = 0x00000001, /* start-of-pipeline timestamp */ - KGSL_TIMESTAMP_RETIRED = 0x00000002, /* end-of-pipeline timestamp*/ - KGSL_TIMESTAMP_QUEUED = 0x00000003, -}; - -/* property types - used with kgsl_device_getproperty */ -enum kgsl_property_type { - KGSL_PROP_DEVICE_INFO = 0x00000001, - KGSL_PROP_DEVICE_SHADOW = 0x00000002, - KGSL_PROP_DEVICE_POWER = 0x00000003, - KGSL_PROP_SHMEM = 0x00000004, - KGSL_PROP_SHMEM_APERTURES = 0x00000005, - KGSL_PROP_MMU_ENABLE = 0x00000006, - KGSL_PROP_INTERRUPT_WAITS = 0x00000007, - KGSL_PROP_VERSION = 0x00000008, - KGSL_PROP_GPU_RESET_STAT = 0x00000009, - KGSL_PROP_PWRCTRL = 0x0000000E, -}; - -struct kgsl_shadowprop { - unsigned int gpuaddr; - unsigned int size; - unsigned int flags; /* contains KGSL_FLAGS_ values */ -}; - -struct kgsl_pwrlevel { - unsigned int gpu_freq; - unsigned int bus_freq; - unsigned int io_fraction; -}; - -struct kgsl_version { - unsigned int drv_major; - unsigned int drv_minor; - unsigned int dev_major; - unsigned int dev_minor; -}; - -#ifdef __KERNEL__ - -#define KGSL_3D0_REG_MEMORY "kgsl_3d0_reg_memory" -#define KGSL_3D0_IRQ "kgsl_3d0_irq" -#define KGSL_2D0_REG_MEMORY "kgsl_2d0_reg_memory" -#define KGSL_2D0_IRQ "kgsl_2d0_irq" -#define KGSL_2D1_REG_MEMORY "kgsl_2d1_reg_memory" -#define KGSL_2D1_IRQ "kgsl_2d1_irq" - -enum kgsl_iommu_context_id { - KGSL_IOMMU_CONTEXT_USER = 0, - KGSL_IOMMU_CONTEXT_PRIV = 1, -}; - -struct kgsl_iommu_ctx { - const char *iommu_ctx_name; - enum kgsl_iommu_context_id ctx_id; -}; - -struct kgsl_device_iommu_data { - const struct kgsl_iommu_ctx *iommu_ctxs; - int iommu_ctx_count; - unsigned int physstart; - unsigned int physend; -}; - -struct kgsl_device_platform_data { - struct kgsl_pwrlevel pwrlevel[KGSL_MAX_PWRLEVELS]; - int init_level; - int num_levels; - int (*set_grp_async)(void); - unsigned int idle_timeout; - bool strtstp_sleepwake; - unsigned int nap_allowed; - unsigned int clk_map; - unsigned int idle_needed; - struct msm_bus_scale_pdata *bus_scale_table; - struct kgsl_device_iommu_data *iommu_data; - int iommu_count; - struct msm_dcvs_core_info *core_info; -}; - -#endif - -/* structure holds list of ibs */ -struct kgsl_ibdesc { - unsigned int gpuaddr; - void *hostptr; - unsigned int sizedwords; - unsigned int ctrl; -}; - -/* ioctls */ -#define KGSL_IOC_TYPE 0x09 - -/* get misc info about the GPU - type should be a value from enum kgsl_property_type - value points to a structure that varies based on type - sizebytes is sizeof() that structure - for KGSL_PROP_DEVICE_INFO, use struct kgsl_devinfo - this structure contaings hardware versioning info. - for KGSL_PROP_DEVICE_SHADOW, use struct kgsl_shadowprop - this is used to find mmap() offset and sizes for mapping - struct kgsl_memstore into userspace. -*/ -struct kgsl_device_getproperty { - unsigned int type; - void *value; - unsigned int sizebytes; -}; - -#define IOCTL_KGSL_DEVICE_GETPROPERTY \ - _IOWR(KGSL_IOC_TYPE, 0x2, struct kgsl_device_getproperty) - -/* IOCTL_KGSL_DEVICE_READ (0x3) - removed 03/2012 - */ - -/* block until the GPU has executed past a given timestamp - * timeout is in milliseconds. - */ -struct kgsl_device_waittimestamp { - unsigned int timestamp; - unsigned int timeout; -}; - -#define IOCTL_KGSL_DEVICE_WAITTIMESTAMP \ - _IOW(KGSL_IOC_TYPE, 0x6, struct kgsl_device_waittimestamp) - -struct kgsl_device_waittimestamp_ctxtid { - unsigned int context_id; - unsigned int timestamp; - unsigned int timeout; -}; - -#define IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID \ - _IOW(KGSL_IOC_TYPE, 0x7, struct kgsl_device_waittimestamp_ctxtid) - -/* issue indirect commands to the GPU. - * drawctxt_id must have been created with IOCTL_KGSL_DRAWCTXT_CREATE - * ibaddr and sizedwords must specify a subset of a buffer created - * with IOCTL_KGSL_SHAREDMEM_FROM_PMEM - * flags may be a mask of KGSL_CONTEXT_ values - * timestamp is a returned counter value which can be passed to - * other ioctls to determine when the commands have been executed by - * the GPU. - */ -struct kgsl_ringbuffer_issueibcmds { - unsigned int drawctxt_id; - unsigned int ibdesc_addr; - unsigned int numibs; - unsigned int timestamp; /*output param */ - unsigned int flags; -}; - -#define IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS \ - _IOWR(KGSL_IOC_TYPE, 0x10, struct kgsl_ringbuffer_issueibcmds) - -/* read the most recently executed timestamp value - * type should be a value from enum kgsl_timestamp_type - */ -struct kgsl_cmdstream_readtimestamp { - unsigned int type; - unsigned int timestamp; /*output param */ -}; - -#define IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_OLD \ - _IOR(KGSL_IOC_TYPE, 0x11, struct kgsl_cmdstream_readtimestamp) - -#define IOCTL_KGSL_CMDSTREAM_READTIMESTAMP \ - _IOWR(KGSL_IOC_TYPE, 0x11, struct kgsl_cmdstream_readtimestamp) - -/* free memory when the GPU reaches a given timestamp. - * gpuaddr specify a memory region created by a - * IOCTL_KGSL_SHAREDMEM_FROM_PMEM call - * type should be a value from enum kgsl_timestamp_type - */ -struct kgsl_cmdstream_freememontimestamp { - unsigned int gpuaddr; - unsigned int type; - unsigned int timestamp; -}; - -#define IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP \ - _IOW(KGSL_IOC_TYPE, 0x12, struct kgsl_cmdstream_freememontimestamp) - -/* Previous versions of this header had incorrectly defined - IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP as a read-only ioctl instead - of a write only ioctl. To ensure binary compatibility, the following - #define will be used to intercept the incorrect ioctl -*/ - -#define IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP_OLD \ - _IOR(KGSL_IOC_TYPE, 0x12, struct kgsl_cmdstream_freememontimestamp) - -/* create a draw context, which is used to preserve GPU state. - * The flags field may contain a mask KGSL_CONTEXT_* values - */ -struct kgsl_drawctxt_create { - unsigned int flags; - unsigned int drawctxt_id; /*output param */ -}; - -#define IOCTL_KGSL_DRAWCTXT_CREATE \ - _IOWR(KGSL_IOC_TYPE, 0x13, struct kgsl_drawctxt_create) - -/* destroy a draw context */ -struct kgsl_drawctxt_destroy { - unsigned int drawctxt_id; -}; - -#define IOCTL_KGSL_DRAWCTXT_DESTROY \ - _IOW(KGSL_IOC_TYPE, 0x14, struct kgsl_drawctxt_destroy) - -/* add a block of pmem, fb, ashmem or user allocated address - * into the GPU address space */ -struct kgsl_map_user_mem { - int fd; - unsigned int gpuaddr; /*output param */ - unsigned int len; - unsigned int offset; - unsigned int hostptr; /*input param */ - enum kgsl_user_mem_type memtype; - unsigned int reserved; /* May be required to add - params for another mem type */ -}; - -#define IOCTL_KGSL_MAP_USER_MEM \ - _IOWR(KGSL_IOC_TYPE, 0x15, struct kgsl_map_user_mem) - -struct kgsl_cmdstream_readtimestamp_ctxtid { - unsigned int context_id; - unsigned int type; - unsigned int timestamp; /*output param */ -}; - -#define IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_CTXTID \ - _IOWR(KGSL_IOC_TYPE, 0x16, struct kgsl_cmdstream_readtimestamp_ctxtid) - -struct kgsl_cmdstream_freememontimestamp_ctxtid { - unsigned int context_id; - unsigned int gpuaddr; - unsigned int type; - unsigned int timestamp; -}; - -#define IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP_CTXTID \ - _IOW(KGSL_IOC_TYPE, 0x17, \ - struct kgsl_cmdstream_freememontimestamp_ctxtid) - -/* add a block of pmem or fb into the GPU address space */ -struct kgsl_sharedmem_from_pmem { - int pmem_fd; - unsigned int gpuaddr; /*output param */ - unsigned int len; - unsigned int offset; -}; - -#define IOCTL_KGSL_SHAREDMEM_FROM_PMEM \ - _IOWR(KGSL_IOC_TYPE, 0x20, struct kgsl_sharedmem_from_pmem) - -/* remove memory from the GPU's address space */ -struct kgsl_sharedmem_free { - unsigned int gpuaddr; -}; - -#define IOCTL_KGSL_SHAREDMEM_FREE \ - _IOW(KGSL_IOC_TYPE, 0x21, struct kgsl_sharedmem_free) - -struct kgsl_cff_user_event { - unsigned char cff_opcode; - unsigned int op1; - unsigned int op2; - unsigned int op3; - unsigned int op4; - unsigned int op5; - unsigned int __pad[2]; -}; - -#define IOCTL_KGSL_CFF_USER_EVENT \ - _IOW(KGSL_IOC_TYPE, 0x31, struct kgsl_cff_user_event) - -struct kgsl_gmem_desc { - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; - unsigned int pitch; -}; - -struct kgsl_buffer_desc { - void *hostptr; - unsigned int gpuaddr; - int size; - unsigned int format; - unsigned int pitch; - unsigned int enabled; -}; - -struct kgsl_bind_gmem_shadow { - unsigned int drawctxt_id; - struct kgsl_gmem_desc gmem_desc; - unsigned int shadow_x; - unsigned int shadow_y; - struct kgsl_buffer_desc shadow_buffer; - unsigned int buffer_id; -}; - -#define IOCTL_KGSL_DRAWCTXT_BIND_GMEM_SHADOW \ - _IOW(KGSL_IOC_TYPE, 0x22, struct kgsl_bind_gmem_shadow) - -/* add a block of memory into the GPU address space */ -struct kgsl_sharedmem_from_vmalloc { - unsigned int gpuaddr; /*output param */ - unsigned int hostptr; - unsigned int flags; -}; - -#define IOCTL_KGSL_SHAREDMEM_FROM_VMALLOC \ - _IOWR(KGSL_IOC_TYPE, 0x23, struct kgsl_sharedmem_from_vmalloc) - -#define IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE \ - _IOW(KGSL_IOC_TYPE, 0x24, struct kgsl_sharedmem_free) - -struct kgsl_drawctxt_set_bin_base_offset { - unsigned int drawctxt_id; - unsigned int offset; -}; - -#define IOCTL_KGSL_DRAWCTXT_SET_BIN_BASE_OFFSET \ - _IOW(KGSL_IOC_TYPE, 0x25, struct kgsl_drawctxt_set_bin_base_offset) - -enum kgsl_cmdwindow_type { - KGSL_CMDWINDOW_MIN = 0x00000000, - KGSL_CMDWINDOW_2D = 0x00000000, - KGSL_CMDWINDOW_3D = 0x00000001, /* legacy */ - KGSL_CMDWINDOW_MMU = 0x00000002, - KGSL_CMDWINDOW_ARBITER = 0x000000FF, - KGSL_CMDWINDOW_MAX = 0x000000FF, -}; - -/* write to the command window */ -struct kgsl_cmdwindow_write { - enum kgsl_cmdwindow_type target; - unsigned int addr; - unsigned int data; -}; - -#define IOCTL_KGSL_CMDWINDOW_WRITE \ - _IOW(KGSL_IOC_TYPE, 0x2e, struct kgsl_cmdwindow_write) - -struct kgsl_gpumem_alloc { - unsigned long gpuaddr; - size_t size; - unsigned int flags; -}; - -#define IOCTL_KGSL_GPUMEM_ALLOC \ - _IOWR(KGSL_IOC_TYPE, 0x2f, struct kgsl_gpumem_alloc) - -struct kgsl_cff_syncmem { - unsigned int gpuaddr; - unsigned int len; - unsigned int __pad[2]; /* For future binary compatibility */ -}; - -#define IOCTL_KGSL_CFF_SYNCMEM \ - _IOW(KGSL_IOC_TYPE, 0x30, struct kgsl_cff_syncmem) - -/* - * A timestamp event allows the user space to register an action following an - * expired timestamp. - */ - -struct kgsl_timestamp_event { - int type; /* Type of event (see list below) */ - unsigned int timestamp; /* Timestamp to trigger event on */ - unsigned int context_id; /* Context for the timestamp */ - void *priv; /* Pointer to the event specific blob */ - size_t len; /* Size of the event specific blob */ -}; - -#define IOCTL_KGSL_TIMESTAMP_EVENT \ - _IOW(KGSL_IOC_TYPE, 0x31, struct kgsl_timestamp_event) - -/* A genlock timestamp event releases an existing lock on timestamp expire */ - -#define KGSL_TIMESTAMP_EVENT_GENLOCK 1 - -struct kgsl_timestamp_event_genlock { - int handle; /* Handle of the genlock lock to release */ -}; - -/* - * Set a property within the kernel. Uses the same structure as - * IOCTL_KGSL_GETPROPERTY - */ - -#define IOCTL_KGSL_SETPROPERTY \ - _IOW(KGSL_IOC_TYPE, 0x32, struct kgsl_device_getproperty) - -#ifdef __KERNEL__ -#ifdef CONFIG_MSM_KGSL_DRM -int kgsl_gem_obj_addr(int drm_fd, int handle, unsigned long *start, - unsigned long *len); -#else -#define kgsl_gem_obj_addr(...) 0 -#endif -#endif -#endif /* _MSM_KGSL_H */ diff --git a/freedreno/libdrm_freedreno.pc.in b/freedreno/libdrm_freedreno.pc.in deleted file mode 100644 index b736b65a..00000000 --- a/freedreno/libdrm_freedreno.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libdrm_freedreno -Description: Userspace interface to freedreno kernel DRM services -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -ldrm_freedreno -Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/freedreno -Requires.private: libdrm diff --git a/freedreno/meson.build b/freedreno/meson.build deleted file mode 100644 index 156362ef..00000000 --- a/freedreno/meson.build +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright © 2017-2018 Intel Corporation - -# 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, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS 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. - -files_freedreno = files( - 'freedreno_device.c', - 'freedreno_pipe.c', - 'freedreno_ringbuffer.c', - 'freedreno_bo.c', - 'freedreno_bo_cache.c', - 'msm/msm_bo.c', - 'msm/msm_device.c', - 'msm/msm_pipe.c', - 'msm/msm_ringbuffer.c', -) - -if with_freedreno_kgsl - files_freedreno += files( - 'kgsl/kgsl_bo.c', - 'kgsl/kgsl_device.c', - 'kgsl/kgsl_pipe.c', - 'kgsl/kgsl_ringbuffer.c', - ) -endif - -libdrm_freedreno = library( - 'drm_freedreno', - [files_freedreno, config_file], - c_args : libdrm_c_args, - include_directories : [inc_root, inc_drm], - dependencies : [dep_valgrind, dep_threads, dep_rt, dep_atomic_ops], - link_with : libdrm, - version : '1.@0@.0'.format(patch_ver), - install : true, -) - -ext_libdrm_freedreno = declare_dependency( - link_with : [libdrm, libdrm_freedreno], - include_directories : [inc_drm, include_directories('.')], -) - -meson.override_dependency('libdrm_freedreno', ext_libdrm_freedreno) - -install_headers( - 'freedreno_drmif.h', 'freedreno_ringbuffer.h', - subdir : 'freedreno' -) - -pkg.generate( - libdrm_freedreno, - name : 'libdrm_freedreno', - subdirs : ['.', 'libdrm', 'freedreno'], - description : 'Userspace interface to freedreno kernel DRM services', -) - -test( - 'freedreno-symbols-check', - symbols_check, - args : [ - '--lib', libdrm_freedreno, - '--symbols-file', files('freedreno-symbols.txt'), - '--nm', prog_nm.full_path(), - ], -) diff --git a/freedreno/msm/msm_bo.c b/freedreno/msm/msm_bo.c deleted file mode 100644 index 8b3d0bcb..00000000 --- a/freedreno/msm/msm_bo.c +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include "msm_priv.h" - -static int bo_allocate(struct msm_bo *msm_bo) -{ - struct fd_bo *bo = &msm_bo->base; - if (!msm_bo->offset) { - struct drm_msm_gem_info req = { - .handle = bo->handle, - }; - int ret; - - /* if the buffer is already backed by pages then this - * doesn't actually do anything (other than giving us - * the offset) - */ - ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, - &req, sizeof(req)); - if (ret) { - ERROR_MSG("alloc failed: %s", strerror(errno)); - return ret; - } - - msm_bo->offset = req.offset; - } - - return 0; -} - -static int msm_bo_offset(struct fd_bo *bo, uint64_t *offset) -{ - struct msm_bo *msm_bo = to_msm_bo(bo); - int ret = bo_allocate(msm_bo); - if (ret) - return ret; - *offset = msm_bo->offset; - return 0; -} - -static int msm_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op) -{ - struct drm_msm_gem_cpu_prep req = { - .handle = bo->handle, - .op = op, - }; - - get_abs_timeout(&req.timeout, 5000000000); - - return drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_PREP, &req, sizeof(req)); -} - -static void msm_bo_cpu_fini(struct fd_bo *bo) -{ - struct drm_msm_gem_cpu_fini req = { - .handle = bo->handle, - }; - - drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_FINI, &req, sizeof(req)); -} - -static int msm_bo_madvise(struct fd_bo *bo, int willneed) -{ - struct drm_msm_gem_madvise req = { - .handle = bo->handle, - .madv = willneed ? MSM_MADV_WILLNEED : MSM_MADV_DONTNEED, - }; - int ret; - - /* older kernels do not support this: */ - if (bo->dev->version < FD_VERSION_MADVISE) - return willneed; - - ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_MADVISE, &req, sizeof(req)); - if (ret) - return ret; - - return req.retained; -} - -static uint64_t msm_bo_iova(struct fd_bo *bo) -{ - struct drm_msm_gem_info req = { - .handle = bo->handle, - .flags = MSM_INFO_IOVA, - }; - - drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req)); - - return req.offset; -} - -static void msm_bo_destroy(struct fd_bo *bo) -{ - struct msm_bo *msm_bo = to_msm_bo(bo); - free(msm_bo); - -} - -static const struct fd_bo_funcs funcs = { - .offset = msm_bo_offset, - .cpu_prep = msm_bo_cpu_prep, - .cpu_fini = msm_bo_cpu_fini, - .madvise = msm_bo_madvise, - .iova = msm_bo_iova, - .destroy = msm_bo_destroy, -}; - -/* allocate a buffer handle: */ -drm_private int msm_bo_new_handle(struct fd_device *dev, - uint32_t size, uint32_t flags, uint32_t *handle) -{ - struct drm_msm_gem_new req = { - .size = size, - .flags = MSM_BO_WC, // TODO figure out proper flags.. - }; - int ret; - - ret = drmCommandWriteRead(dev->fd, DRM_MSM_GEM_NEW, - &req, sizeof(req)); - if (ret) - return ret; - - *handle = req.handle; - - return 0; -} - -/* allocate a new buffer object */ -drm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev, - uint32_t size, uint32_t handle) -{ - struct msm_bo *msm_bo; - struct fd_bo *bo; - - msm_bo = calloc(1, sizeof(*msm_bo)); - if (!msm_bo) - return NULL; - - bo = &msm_bo->base; - bo->funcs = &funcs; - - return bo; -} diff --git a/freedreno/msm/msm_device.c b/freedreno/msm/msm_device.c deleted file mode 100644 index 58b0746d..00000000 --- a/freedreno/msm/msm_device.c +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "msm_priv.h" - -static void msm_device_destroy(struct fd_device *dev) -{ - struct msm_device *msm_dev = to_msm_device(dev); - free(msm_dev); -} - -static const struct fd_device_funcs funcs = { - .bo_new_handle = msm_bo_new_handle, - .bo_from_handle = msm_bo_from_handle, - .pipe_new = msm_pipe_new, - .destroy = msm_device_destroy, -}; - -drm_private struct fd_device * msm_device_new(int fd) -{ - struct msm_device *msm_dev; - struct fd_device *dev; - - msm_dev = calloc(1, sizeof(*msm_dev)); - if (!msm_dev) - return NULL; - - dev = &msm_dev->base; - dev->funcs = &funcs; - - dev->bo_size = sizeof(struct msm_bo); - - return dev; -} diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c deleted file mode 100644 index e070b317..00000000 --- a/freedreno/msm/msm_pipe.c +++ /dev/null @@ -1,212 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include "msm_priv.h" - -static int query_param(struct fd_pipe *pipe, uint32_t param, - uint64_t *value) -{ - struct msm_pipe *msm_pipe = to_msm_pipe(pipe); - struct drm_msm_param req = { - .pipe = msm_pipe->pipe, - .param = param, - }; - int ret; - - ret = drmCommandWriteRead(pipe->dev->fd, DRM_MSM_GET_PARAM, - &req, sizeof(req)); - if (ret) - return ret; - - *value = req.value; - - return 0; -} - -static int msm_pipe_get_param(struct fd_pipe *pipe, - enum fd_param_id param, uint64_t *value) -{ - struct msm_pipe *msm_pipe = to_msm_pipe(pipe); - switch(param) { - case FD_DEVICE_ID: // XXX probably get rid of this.. - case FD_GPU_ID: - *value = msm_pipe->gpu_id; - return 0; - case FD_GMEM_SIZE: - *value = msm_pipe->gmem; - return 0; - case FD_CHIP_ID: - *value = msm_pipe->chip_id; - return 0; - case FD_MAX_FREQ: - return query_param(pipe, MSM_PARAM_MAX_FREQ, value); - case FD_TIMESTAMP: - return query_param(pipe, MSM_PARAM_TIMESTAMP, value); - case FD_NR_RINGS: - return query_param(pipe, MSM_PARAM_NR_RINGS, value); - default: - ERROR_MSG("invalid param id: %d", param); - return -1; - } -} - -static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp, - uint64_t timeout) -{ - struct fd_device *dev = pipe->dev; - struct drm_msm_wait_fence req = { - .fence = timestamp, - .queueid = to_msm_pipe(pipe)->queue_id, - }; - int ret; - - get_abs_timeout(&req.timeout, timeout); - - ret = drmCommandWrite(dev->fd, DRM_MSM_WAIT_FENCE, &req, sizeof(req)); - if (ret) { - ERROR_MSG("wait-fence failed! %d (%s)", ret, strerror(errno)); - return ret; - } - - return 0; -} - -static int open_submitqueue(struct fd_pipe *pipe, uint32_t prio) -{ - struct drm_msm_submitqueue req = { - .flags = 0, - .prio = prio, - }; - uint64_t nr_rings = 1; - int ret; - - if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) { - to_msm_pipe(pipe)->queue_id = 0; - return 0; - } - - msm_pipe_get_param(pipe, FD_NR_RINGS, &nr_rings); - - req.prio = MIN2(req.prio, MAX2(nr_rings, 1) - 1); - - ret = drmCommandWriteRead(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_NEW, - &req, sizeof(req)); - if (ret) { - ERROR_MSG("could not create submitqueue! %d (%s)", ret, strerror(errno)); - return ret; - } - - to_msm_pipe(pipe)->queue_id = req.id; - return 0; -} - -static void close_submitqueue(struct fd_pipe *pipe, uint32_t queue_id) -{ - if (fd_device_version(pipe->dev) < FD_VERSION_SUBMIT_QUEUES) - return; - - drmCommandWrite(pipe->dev->fd, DRM_MSM_SUBMITQUEUE_CLOSE, - &queue_id, sizeof(queue_id)); -} - -static void msm_pipe_destroy(struct fd_pipe *pipe) -{ - struct msm_pipe *msm_pipe = to_msm_pipe(pipe); - close_submitqueue(pipe, msm_pipe->queue_id); - - if (msm_pipe->suballoc_ring) { - fd_ringbuffer_del(msm_pipe->suballoc_ring); - msm_pipe->suballoc_ring = NULL; - } - - free(msm_pipe); -} - -static const struct fd_pipe_funcs funcs = { - .ringbuffer_new = msm_ringbuffer_new, - .get_param = msm_pipe_get_param, - .wait = msm_pipe_wait, - .destroy = msm_pipe_destroy, -}; - -static uint64_t get_param(struct fd_pipe *pipe, uint32_t param) -{ - uint64_t value; - int ret = query_param(pipe, param, &value); - if (ret) { - ERROR_MSG("get-param failed! %d (%s)", ret, strerror(errno)); - return 0; - } - return value; -} - -drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, - enum fd_pipe_id id, uint32_t prio) -{ - static const uint32_t pipe_id[] = { - [FD_PIPE_3D] = MSM_PIPE_3D0, - [FD_PIPE_2D] = MSM_PIPE_2D0, - }; - struct msm_pipe *msm_pipe = NULL; - struct fd_pipe *pipe = NULL; - - msm_pipe = calloc(1, sizeof(*msm_pipe)); - if (!msm_pipe) { - ERROR_MSG("allocation failed"); - goto fail; - } - - pipe = &msm_pipe->base; - pipe->funcs = &funcs; - - /* initialize before get_param(): */ - pipe->dev = dev; - msm_pipe->pipe = pipe_id[id]; - - /* these params should be supported since the first version of drm/msm: */ - msm_pipe->gpu_id = get_param(pipe, MSM_PARAM_GPU_ID); - msm_pipe->gmem = get_param(pipe, MSM_PARAM_GMEM_SIZE); - msm_pipe->chip_id = get_param(pipe, MSM_PARAM_CHIP_ID); - - if (! msm_pipe->gpu_id) - goto fail; - - INFO_MSG("Pipe Info:"); - INFO_MSG(" GPU-id: %d", msm_pipe->gpu_id); - INFO_MSG(" Chip-id: 0x%08x", msm_pipe->chip_id); - INFO_MSG(" GMEM size: 0x%08x", msm_pipe->gmem); - - if (open_submitqueue(pipe, prio)) - goto fail; - - return pipe; -fail: - if (pipe) - fd_pipe_del(pipe); - return NULL; -} diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h deleted file mode 100644 index cc951fba..00000000 --- a/freedreno/msm/msm_priv.h +++ /dev/null @@ -1,141 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#ifndef MSM_PRIV_H_ -#define MSM_PRIV_H_ - -#include "freedreno_priv.h" - -#ifndef __user -# define __user -#endif - -#include "msm_drm.h" - -struct msm_device { - struct fd_device base; - struct fd_bo_cache ring_cache; - unsigned ring_cnt; -}; - -static inline struct msm_device * to_msm_device(struct fd_device *x) -{ - return (struct msm_device *)x; -} - -drm_private struct fd_device * msm_device_new(int fd); - -struct msm_pipe { - struct fd_pipe base; - uint32_t pipe; - uint32_t gpu_id; - uint32_t gmem; - uint32_t chip_id; - uint32_t queue_id; - - /* Allow for sub-allocation of stateobj ring buffers (ie. sharing - * the same underlying bo).. - * - * This takes advantage of each context having it's own fd_pipe, - * so we don't have to worry about access from multiple threads. - * - * We also rely on previous stateobj having been fully constructed - * so we can reclaim extra space at it's end. - */ - struct fd_ringbuffer *suballoc_ring; -}; - -static inline struct msm_pipe * to_msm_pipe(struct fd_pipe *x) -{ - return (struct msm_pipe *)x; -} - -drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, - enum fd_pipe_id id, uint32_t prio); - -drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size, enum fd_ringbuffer_flags flags); - -struct msm_bo { - struct fd_bo base; - uint64_t offset; - uint64_t presumed; - /* to avoid excess hashtable lookups, cache the ring this bo was - * last emitted on (since that will probably also be the next ring - * it is emitted on) - */ - unsigned current_ring_seqno; - uint32_t idx; -}; - -static inline struct msm_bo * to_msm_bo(struct fd_bo *x) -{ - return (struct msm_bo *)x; -} - -drm_private int msm_bo_new_handle(struct fd_device *dev, - uint32_t size, uint32_t flags, uint32_t *handle); -drm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev, - uint32_t size, uint32_t handle); - -static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns) -{ - struct timespec t; - uint32_t s = ns / 1000000000; - clock_gettime(CLOCK_MONOTONIC, &t); - tv->tv_sec = t.tv_sec + s; - tv->tv_nsec = t.tv_nsec + ns - (s * 1000000000); -} - -/* - * Stupid/simple growable array implementation: - */ - -static inline void * -grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz) -{ - if ((nr + 1) > *max) { - if ((*max * 2) < (nr + 1)) - *max = nr + 5; - else - *max = *max * 2; - ptr = realloc(ptr, *max * sz); - } - return ptr; -} - -#define DECLARE_ARRAY(type, name) \ - unsigned nr_ ## name, max_ ## name; \ - type * name; - -#define APPEND(x, name) ({ \ - (x)->name = grow((x)->name, (x)->nr_ ## name, &(x)->max_ ## name, sizeof((x)->name[0])); \ - (x)->nr_ ## name ++; \ -}) - -#endif /* MSM_PRIV_H_ */ diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c deleted file mode 100644 index 7b9df4a0..00000000 --- a/freedreno/msm/msm_ringbuffer.c +++ /dev/null @@ -1,723 +0,0 @@ -/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ - -/* - * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> - * - * 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, sublicense, - * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Rob Clark <robclark@freedesktop.org> - */ - -#include <assert.h> -#include <inttypes.h> - -#include "xf86atomic.h" -#include "freedreno_ringbuffer.h" -#include "msm_priv.h" - -/* represents a single cmd buffer in the submit ioctl. Each cmd buffer has - * a backing bo, and a reloc table. - */ -struct msm_cmd { - struct list_head list; - - struct fd_ringbuffer *ring; - struct fd_bo *ring_bo; - - /* reloc's table: */ - DECLARE_ARRAY(struct drm_msm_gem_submit_reloc, relocs); - - uint32_t size; - - /* has cmd already been added to parent rb's submit.cmds table? */ - int is_appended_to_submit; -}; - -struct msm_ringbuffer { - struct fd_ringbuffer base; - - /* submit ioctl related tables: - * Note that bos and cmds are tracked by the parent ringbuffer, since - * that is global to the submit ioctl call. The reloc's table is tracked - * per cmd-buffer. - */ - struct { - /* bo's table: */ - DECLARE_ARRAY(struct drm_msm_gem_submit_bo, bos); - - /* cmd's table: */ - DECLARE_ARRAY(struct drm_msm_gem_submit_cmd, cmds); - } submit; - - /* should have matching entries in submit.bos: */ - /* Note, only in parent ringbuffer */ - DECLARE_ARRAY(struct fd_bo *, bos); - - /* should have matching entries in submit.cmds: */ - DECLARE_ARRAY(struct msm_cmd *, cmds); - - /* List of physical cmdstream buffers (msm_cmd) associated with this - * logical fd_ringbuffer. - * - * Note that this is different from msm_ringbuffer::cmds (which - * shadows msm_ringbuffer::submit::cmds for tracking submit ioctl - * related stuff, and *only* is tracked in the parent ringbuffer. - * And only has "completed" cmd buffers (ie. we already know the - * size) added via get_cmd(). - */ - struct list_head cmd_list; - - int is_growable; - unsigned cmd_count; - - unsigned offset; /* for sub-allocated stateobj rb's */ - - unsigned seqno; - - /* maps fd_bo to idx: */ - void *bo_table; - - /* maps msm_cmd to drm_msm_gem_submit_cmd in parent rb. Each rb has a - * list of msm_cmd's which correspond to each chunk of cmdstream in - * a 'growable' rb. For each of those we need to create one - * drm_msm_gem_submit_cmd in the parent rb which collects the state - * for the submit ioctl. Because we can have multiple IB's to the same - * target rb (for example, or same stateobj emit multiple times), and - * because in theory we can have multiple different rb's that have a - * reference to a given target, we need a hashtable to track this per - * rb. - */ - void *cmd_table; -}; - -static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x) -{ - return (struct msm_ringbuffer *)x; -} - -#define INIT_SIZE 0x1000 - -static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER; - -static struct msm_cmd *current_cmd(struct fd_ringbuffer *ring) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); - assert(!LIST_IS_EMPTY(&msm_ring->cmd_list)); - return LIST_LAST_ENTRY(&msm_ring->cmd_list, struct msm_cmd, list); -} - -static void ring_cmd_del(struct msm_cmd *cmd) -{ - fd_bo_del(cmd->ring_bo); - list_del(&cmd->list); - to_msm_ringbuffer(cmd->ring)->cmd_count--; - free(cmd->relocs); - free(cmd); -} - -static struct msm_cmd * ring_cmd_new(struct fd_ringbuffer *ring, uint32_t size, - enum fd_ringbuffer_flags flags) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); - struct msm_cmd *cmd = calloc(1, sizeof(*cmd)); - - if (!cmd) - return NULL; - - cmd->ring = ring; - - /* TODO separate suballoc buffer for small non-streaming state, using - * smaller page-sized backing bo's. - */ - if (flags & FD_RINGBUFFER_STREAMING) { - struct msm_pipe *msm_pipe = to_msm_pipe(ring->pipe); - unsigned suballoc_offset = 0; - struct fd_bo *suballoc_bo = NULL; - - if (msm_pipe->suballoc_ring) { - struct msm_ringbuffer *suballoc_ring = to_msm_ringbuffer(msm_pipe->suballoc_ring); - - assert(msm_pipe->suballoc_ring->flags & FD_RINGBUFFER_OBJECT); - assert(suballoc_ring->cmd_count == 1); - - suballoc_bo = current_cmd(msm_pipe->suballoc_ring)->ring_bo; - - suballoc_offset = fd_ringbuffer_size(msm_pipe->suballoc_ring) + - suballoc_ring->offset; - - suballoc_offset = ALIGN(suballoc_offset, 0x10); - - if ((size + suballoc_offset) > suballoc_bo->size) { - suballoc_bo = NULL; - } - } - - if (!suballoc_bo) { - cmd->ring_bo = fd_bo_new_ring(ring->pipe->dev, 0x8000, 0); - msm_ring->offset = 0; - } else { - cmd->ring_bo = fd_bo_ref(suballoc_bo); - msm_ring->offset = suballoc_offset; - } - - if (msm_pipe->suballoc_ring) - fd_ringbuffer_del(msm_pipe->suballoc_ring); - - msm_pipe->suballoc_ring = fd_ringbuffer_ref(ring); - } else { - cmd->ring_bo = fd_bo_new_ring(ring->pipe->dev, size, 0); - } - if (!cmd->ring_bo) - goto fail; - - list_addtail(&cmd->list, &msm_ring->cmd_list); - msm_ring->cmd_count++; - - return cmd; - -fail: - ring_cmd_del(cmd); - return NULL; -} - -static uint32_t append_bo(struct fd_ringbuffer *ring, struct fd_bo *bo) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); - uint32_t idx; - - idx = APPEND(&msm_ring->submit, bos); - idx = APPEND(msm_ring, bos); - - msm_ring->submit.bos[idx].flags = 0; - msm_ring->submit.bos[idx].handle = bo->handle; - msm_ring->submit.bos[idx].presumed = to_msm_bo(bo)->presumed; - - msm_ring->bos[idx] = fd_bo_ref(bo); - - return idx; -} - -/* add (if needed) bo, return idx: */ -static uint32_t bo2idx(struct fd_ringbuffer *ring, struct fd_bo *bo, uint32_t flags) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); - struct msm_bo *msm_bo = to_msm_bo(bo); - uint32_t idx; - pthread_mutex_lock(&idx_lock); - if (msm_bo->current_ring_seqno == msm_ring->seqno) { - idx = msm_bo->idx; - } else { - void *val; - - if (!msm_ring->bo_table) - msm_ring->bo_table = drmHashCreate(); - - if (!drmHashLookup(msm_ring->bo_table, bo->handle, &val)) { - /* found */ - idx = (uint32_t)(uintptr_t)val; - } else { - idx = append_bo(ring, bo); - val = (void *)(uintptr_t)idx; - drmHashInsert(msm_ring->bo_table, bo->handle, val); - } - msm_bo->current_ring_seqno = msm_ring->seqno; - msm_bo->idx = idx; - } - pthread_mutex_unlock(&idx_lock); - if (flags & FD_RELOC_READ) - msm_ring->submit.bos[idx].flags |= MSM_SUBMIT_BO_READ; - if (flags & FD_RELOC_WRITE) - msm_ring->submit.bos[idx].flags |= MSM_SUBMIT_BO_WRITE; - return idx; -} - -/* Ensure that submit has corresponding entry in cmds table for the - * target cmdstream buffer: - * - * Returns TRUE if new cmd added (else FALSE if it was already in - * the cmds table) - */ -static int get_cmd(struct fd_ringbuffer *ring, struct msm_cmd *target_cmd, - uint32_t submit_offset, uint32_t size, uint32_t type) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); - struct drm_msm_gem_submit_cmd *cmd; - uint32_t i; - void *val; - - if (!msm_ring->cmd_table) - msm_ring->cmd_table = drmHashCreate(); - - /* figure out if we already have a cmd buf.. short-circuit hash - * lookup if: - * - target cmd has never been added to submit.cmds - * - target cmd is not a streaming stateobj (which unlike longer - * lived CSO stateobj, is not expected to be reused with multiple - * submits) - */ - if (target_cmd->is_appended_to_submit && - !(target_cmd->ring->flags & FD_RINGBUFFER_STREAMING) && - !drmHashLookup(msm_ring->cmd_table, (unsigned long)target_cmd, &val)) { - i = VOID2U64(val); - cmd = &msm_ring->submit.cmds[i]; - - assert(cmd->submit_offset == submit_offset); - assert(cmd->size == size); - assert(cmd->type == type); - assert(msm_ring->submit.bos[cmd->submit_idx].handle == - target_cmd->ring_bo->handle); - - return FALSE; - } - - /* create cmd buf if not: */ - i = APPEND(&msm_ring->submit, cmds); - APPEND(msm_ring, cmds); - msm_ring->cmds[i] = target_cmd; - cmd = &msm_ring->submit.cmds[i]; - cmd->type = type; - cmd->submit_idx = bo2idx(ring, target_cmd->ring_bo, FD_RELOC_READ); - cmd->submit_offset = submit_offset; - cmd->size = size; - cmd->pad = 0; - - target_cmd->is_appended_to_submit = TRUE; - - if (!(target_cmd->ring->flags & FD_RINGBUFFER_STREAMING)) { - drmHashInsert(msm_ring->cmd_table, (unsigned long)target_cmd, - U642VOID(i)); - } - - target_cmd->size = size; - - return TRUE; -} - -static void * msm_ringbuffer_hostptr(struct fd_ringbuffer *ring) -{ - struct msm_cmd *cmd = current_cmd(ring); - uint8_t *base = fd_bo_map(cmd->ring_bo); - return base + to_msm_ringbuffer(ring)->offset; -} - -static void delete_cmds(struct msm_ringbuffer *msm_ring) -{ - struct msm_cmd *cmd, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(cmd, tmp, &msm_ring->cmd_list, list) { - ring_cmd_del(cmd); - } -} - -static void flush_reset(struct fd_ringbuffer *ring) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); - unsigned i; - - for (i = 0; i < msm_ring->nr_bos; i++) { - struct msm_bo *msm_bo = to_msm_bo(msm_ring->bos[i]); - if (!msm_bo) - continue; - msm_bo->current_ring_seqno = 0; - fd_bo_del(&msm_bo->base); - } - - for (i = 0; i < msm_ring->nr_cmds; i++) { - struct msm_cmd *msm_cmd = msm_ring->cmds[i]; - - if (msm_cmd->ring == ring) - continue; - - if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) - fd_ringbuffer_del(msm_cmd->ring); - } - - msm_ring->submit.nr_cmds = 0; - msm_ring->submit.nr_bos = 0; - msm_ring->nr_cmds = 0; - msm_ring->nr_bos = 0; - - if (msm_ring->bo_table) { - drmHashDestroy(msm_ring->bo_table); - msm_ring->bo_table = NULL; - } - - if (msm_ring->cmd_table) { - drmHashDestroy(msm_ring->cmd_table); - msm_ring->cmd_table = NULL; - } - - if (msm_ring->is_growable) { - delete_cmds(msm_ring); - } else { - /* in old mode, just reset the # of relocs: */ - current_cmd(ring)->nr_relocs = 0; - } -} - -static void finalize_current_cmd(struct fd_ringbuffer *ring, uint32_t *last_start) -{ - uint32_t submit_offset, size, type; - struct fd_ringbuffer *parent; - - if (ring->parent) { - parent = ring->parent; - type = MSM_SUBMIT_CMD_IB_TARGET_BUF; - } else { - parent = ring; - type = MSM_SUBMIT_CMD_BUF; - } - - submit_offset = offset_bytes(last_start, ring->start); - size = offset_bytes(ring->cur, last_start); - - get_cmd(parent, current_cmd(ring), submit_offset, size, type); -} - -static void dump_submit(struct msm_ringbuffer *msm_ring) -{ - uint32_t i, j; - - for (i = 0; i < msm_ring->submit.nr_bos; i++) { - struct drm_msm_gem_submit_bo *bo = &msm_ring->submit.bos[i]; - ERROR_MSG(" bos[%d]: handle=%u, flags=%x", i, bo->handle, bo->flags); - } - for (i = 0; i < msm_ring->submit.nr_cmds; i++) { - struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i]; - struct drm_msm_gem_submit_reloc *relocs = U642VOID(cmd->relocs); - ERROR_MSG(" cmd[%d]: type=%u, submit_idx=%u, submit_offset=%u, size=%u", - i, cmd->type, cmd->submit_idx, cmd->submit_offset, cmd->size); - for (j = 0; j < cmd->nr_relocs; j++) { - struct drm_msm_gem_submit_reloc *r = &relocs[j]; - ERROR_MSG(" reloc[%d]: submit_offset=%u, or=%08x, shift=%d, reloc_idx=%u" - ", reloc_offset=%"PRIu64, j, r->submit_offset, r->or, r->shift, - r->reloc_idx, r->reloc_offset); - } - } -} - -static struct drm_msm_gem_submit_reloc * -handle_stateobj_relocs(struct fd_ringbuffer *parent, struct fd_ringbuffer *stateobj, - struct drm_msm_gem_submit_reloc *orig_relocs, unsigned nr_relocs) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(stateobj); - struct drm_msm_gem_submit_reloc *relocs = malloc(nr_relocs * sizeof(*relocs)); - unsigned i; - - for (i = 0; i < nr_relocs; i++) { - unsigned idx = orig_relocs[i].reloc_idx; - struct fd_bo *bo = msm_ring->bos[idx]; - unsigned flags = 0; - - if (msm_ring->submit.bos[idx].flags & MSM_SUBMIT_BO_READ) - flags |= FD_RELOC_READ; - if (msm_ring->submit.bos[idx].flags & MSM_SUBMIT_BO_WRITE) - flags |= FD_RELOC_WRITE; - - relocs[i] = orig_relocs[i]; - relocs[i].reloc_idx = bo2idx(parent, bo, flags); - } - - /* stateobj rb's could have reloc's to other stateobj rb's which didn't - * get propagated to the parent rb at _emit_reloc_ring() time (because - * the parent wasn't known then), so fix that up now: - */ - for (i = 0; i < msm_ring->nr_cmds; i++) { - struct msm_cmd *msm_cmd = msm_ring->cmds[i]; - struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i]; - - if (msm_ring->cmds[i]->ring == stateobj) - continue; - - assert(msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT); - - if (get_cmd(parent, msm_cmd, cmd->submit_offset, cmd->size, cmd->type)) { - fd_ringbuffer_ref(msm_cmd->ring); - } - } - - return relocs; -} - -static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start, - int in_fence_fd, int *out_fence_fd) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); - struct msm_pipe *msm_pipe = to_msm_pipe(ring->pipe); - struct drm_msm_gem_submit req = { - .flags = msm_pipe->pipe, - .queueid = msm_pipe->queue_id, - }; - uint32_t i; - int ret; - - assert(!ring->parent); - - if (in_fence_fd != -1) { - req.flags |= MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_NO_IMPLICIT; - req.fence_fd = in_fence_fd; - } - - if (out_fence_fd) { - req.flags |= MSM_SUBMIT_FENCE_FD_OUT; - } - - finalize_current_cmd(ring, last_start); - - /* for each of the cmd's fix up their reloc's: */ - for (i = 0; i < msm_ring->submit.nr_cmds; i++) { - struct msm_cmd *msm_cmd = msm_ring->cmds[i]; - struct drm_msm_gem_submit_reloc *relocs = msm_cmd->relocs; - struct drm_msm_gem_submit_cmd *cmd; - unsigned nr_relocs = msm_cmd->nr_relocs; - - /* for reusable stateobjs, the reloc table has reloc_idx that - * points into it's own private bos table, rather than the global - * bos table used for the submit, so we need to add the stateobj's - * bos to the global table and construct new relocs table with - * corresponding reloc_idx - */ - if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) { - relocs = handle_stateobj_relocs(ring, msm_cmd->ring, - relocs, nr_relocs); - } - - cmd = &msm_ring->submit.cmds[i]; - cmd->relocs = VOID2U64(relocs); - cmd->nr_relocs = nr_relocs; - } - - /* needs to be after get_cmd() as that could create bos/cmds table: */ - req.bos = VOID2U64(msm_ring->submit.bos), - req.nr_bos = msm_ring->submit.nr_bos; - req.cmds = VOID2U64(msm_ring->submit.cmds), - req.nr_cmds = msm_ring->submit.nr_cmds; - - DEBUG_MSG("nr_cmds=%u, nr_bos=%u", req.nr_cmds, req.nr_bos); - - ret = drmCommandWriteRead(ring->pipe->dev->fd, DRM_MSM_GEM_SUBMIT, - &req, sizeof(req)); - if (ret) { - ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno)); - dump_submit(msm_ring); - } else if (!ret) { - /* update timestamp on all rings associated with submit: */ - for (i = 0; i < msm_ring->submit.nr_cmds; i++) { - struct msm_cmd *msm_cmd = msm_ring->cmds[i]; - msm_cmd->ring->last_timestamp = req.fence; - } - - if (out_fence_fd) { - *out_fence_fd = req.fence_fd; - } - } - - /* free dynamically constructed stateobj relocs tables: */ - for (i = 0; i < msm_ring->submit.nr_cmds; i++) { - struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i]; - struct msm_cmd *msm_cmd = msm_ring->cmds[i]; - if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) { - free(U642VOID(cmd->relocs)); - } - } - - flush_reset(ring); - - return ret; -} - -static void msm_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t size) -{ - assert(to_msm_ringbuffer(ring)->is_growable); - finalize_current_cmd(ring, ring->last_start); - ring_cmd_new(ring, size, 0); -} - -static void msm_ringbuffer_reset(struct fd_ringbuffer *ring) -{ - flush_reset(ring); -} - -static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring, - const struct fd_reloc *r) -{ - struct fd_ringbuffer *parent = ring->parent ? ring->parent : ring; - struct msm_bo *msm_bo = to_msm_bo(r->bo); - struct drm_msm_gem_submit_reloc *reloc; - struct msm_cmd *cmd = current_cmd(ring); - uint32_t idx = APPEND(cmd, relocs); - uint32_t addr; - - reloc = &cmd->relocs[idx]; - - reloc->reloc_idx = bo2idx(parent, r->bo, r->flags); - reloc->reloc_offset = r->offset; - reloc->or = r->or; - reloc->shift = r->shift; - reloc->submit_offset = offset_bytes(ring->cur, ring->start) + - to_msm_ringbuffer(ring)->offset; - - addr = msm_bo->presumed; - if (reloc->shift < 0) - addr >>= -reloc->shift; - else - addr <<= reloc->shift; - (*ring->cur++) = addr | r->or; - - if (ring->pipe->gpu_id >= 500) { - struct drm_msm_gem_submit_reloc *reloc_hi; - - /* NOTE: grab reloc_idx *before* APPEND() since that could - * realloc() meaning that 'reloc' ptr is no longer valid: - */ - uint32_t reloc_idx = reloc->reloc_idx; - - idx = APPEND(cmd, relocs); - - reloc_hi = &cmd->relocs[idx]; - - reloc_hi->reloc_idx = reloc_idx; - reloc_hi->reloc_offset = r->offset; - reloc_hi->or = r->orhi; - reloc_hi->shift = r->shift - 32; - reloc_hi->submit_offset = offset_bytes(ring->cur, ring->start) + - to_msm_ringbuffer(ring)->offset; - - addr = msm_bo->presumed >> 32; - if (reloc_hi->shift < 0) - addr >>= -reloc_hi->shift; - else - addr <<= reloc_hi->shift; - (*ring->cur++) = addr | r->orhi; - } -} - -static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, - struct fd_ringbuffer *target, uint32_t cmd_idx) -{ - struct msm_cmd *cmd = NULL; - struct msm_ringbuffer *msm_target = to_msm_ringbuffer(target); - uint32_t idx = 0; - int added_cmd = FALSE; - uint32_t size; - uint32_t submit_offset = msm_target->offset; - - LIST_FOR_EACH_ENTRY(cmd, &msm_target->cmd_list, list) { - if (idx == cmd_idx) - break; - idx++; - } - - assert(cmd && (idx == cmd_idx)); - - if (idx < (msm_target->cmd_count - 1)) { - /* All but the last cmd buffer is fully "baked" (ie. already has - * done get_cmd() to add it to the cmds table). But in this case, - * the size we get is invalid (since it is calculated from the - * last cmd buffer): - */ - size = cmd->size; - } else { - struct fd_ringbuffer *parent = ring->parent ? ring->parent : ring; - size = offset_bytes(target->cur, target->start); - added_cmd = get_cmd(parent, cmd, submit_offset, size, - MSM_SUBMIT_CMD_IB_TARGET_BUF); - } - - msm_ringbuffer_emit_reloc(ring, &(struct fd_reloc){ - .bo = cmd->ring_bo, - .flags = FD_RELOC_READ, - .offset = submit_offset, - }); - - /* Unlike traditional ringbuffers which are deleted as a set (after - * being flushed), mesa can't really guarantee that a stateobj isn't - * destroyed after emitted but before flush, so we must hold a ref: - */ - if (added_cmd && (target->flags & FD_RINGBUFFER_OBJECT)) { - fd_ringbuffer_ref(target); - } - - return size; -} - -static uint32_t msm_ringbuffer_cmd_count(struct fd_ringbuffer *ring) -{ - return to_msm_ringbuffer(ring)->cmd_count; -} - -static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring) -{ - struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); - - flush_reset(ring); - delete_cmds(msm_ring); - - free(msm_ring->submit.cmds); - free(msm_ring->submit.bos); - free(msm_ring->bos); - free(msm_ring->cmds); - free(msm_ring); -} - -static const struct fd_ringbuffer_funcs funcs = { - .hostptr = msm_ringbuffer_hostptr, - .flush = msm_ringbuffer_flush, - .grow = msm_ringbuffer_grow, - .reset = msm_ringbuffer_reset, - .emit_reloc = msm_ringbuffer_emit_reloc, - .emit_reloc_ring = msm_ringbuffer_emit_reloc_ring, - .cmd_count = msm_ringbuffer_cmd_count, - .destroy = msm_ringbuffer_destroy, -}; - -drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, - uint32_t size, enum fd_ringbuffer_flags flags) -{ - struct msm_ringbuffer *msm_ring; - struct fd_ringbuffer *ring; - - msm_ring = calloc(1, sizeof(*msm_ring)); - if (!msm_ring) { - ERROR_MSG("allocation failed"); - return NULL; - } - - if (size == 0) { - assert(pipe->dev->version >= FD_VERSION_UNLIMITED_CMDS); - size = INIT_SIZE; - msm_ring->is_growable = TRUE; - } - - list_inithead(&msm_ring->cmd_list); - msm_ring->seqno = ++to_msm_device(pipe->dev)->ring_cnt; - - ring = &msm_ring->base; - atomic_set(&ring->refcnt, 1); - - ring->funcs = &funcs; - ring->size = size; - ring->pipe = pipe; /* needed in ring_cmd_new() */ - - ring_cmd_new(ring, size, flags); - - return ring; -} diff --git a/meson.build b/meson.build index 1796b213..ec3a0d53 100644 --- a/meson.build +++ b/meson.build @@ -43,7 +43,6 @@ pkg = import('pkgconfig') config = configuration_data() config.set10('UDEV', get_option('udev')) -with_freedreno_kgsl = get_option('freedreno-kgsl') with_install_tests = get_option('install-test-programs') with_tests = get_option('tests') @@ -129,13 +128,6 @@ with_omap = get_option('omap') \ .enabled() summary('OMAP', with_omap) -with_freedreno = get_option('freedreno') \ - .require(with_atomics, error_message : 'libdrm_freedreno requires atomics') \ - .disable_auto_if(not ['arm', 'aarch64'].contains(host_machine.cpu_family())) \ - .allowed() -summary('Freedreno', with_freedreno) -summary('Freedreon-kgsl', with_freedreno_kgsl) - with_tegra = get_option('tegra') \ .require(with_atomics, error_message : 'libdrm_tegra requires atomics') \ .disable_auto_if(not ['arm', 'aarch64'].contains(host_machine.cpu_family())) \ @@ -211,9 +203,6 @@ dep_cairo = dependency('cairo', required : get_option('cairo-tests')) with_cairo_tests = dep_cairo.found() valgrind_version = [] -if with_freedreno - valgrind_version = '>=3.10.0' -endif dep_valgrind = dependency('valgrind', required : get_option('valgrind'), version : valgrind_version) with_valgrind = dep_valgrind.found() @@ -224,7 +213,6 @@ config.set10('HAVE_VISIBILITY', cc.has_function_attribute('visibility:hidden')) foreach t : [ [with_exynos, 'EXYNOS'], - [with_freedreno_kgsl, 'FREEDRENO_KGSL'], [with_intel, 'INTEL'], [with_nouveau, 'NOUVEAU'], [with_radeon, 'RADEON'], @@ -235,9 +223,6 @@ foreach t : [ ] config.set10('HAVE_@0@'.format(t[1]), t[0]) endforeach -if with_freedreno_kgsl and not with_freedreno - error('cannot enable freedreno-kgsl without freedreno support') -endif config.set10('_GNU_SOURCE', true) if target_machine.endian() == 'big' @@ -341,9 +326,6 @@ endif if with_exynos subdir('exynos') endif -if with_freedreno - subdir('freedreno') -endif if with_tegra subdir('tegra') endif diff --git a/meson_options.txt b/meson_options.txt index 922145af..6f7f054b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -54,11 +54,6 @@ option( description : '''Enable support for EXYNOS's experimental KMS API.''', ) option( - 'freedreno', - type : 'feature', - description : '''Enable support for freedreno's KMS API.''', -) -option( 'tegra', type : 'feature', description : '''Enable support for Tegra's experimental KMS API.''', @@ -89,12 +84,6 @@ option( description : 'Build libdrm with valgrind support.', ) option( - 'freedreno-kgsl', - type : 'boolean', - value : false, - description : 'Enable support for freedreno to use downstream android kernel API.', -) -option( 'install-test-programs', type : 'boolean', value : false, |
