diff --git a/drivers/gpu/nvgpu/common/fence/fence.c b/drivers/gpu/nvgpu/common/fence/fence.c index e489de17d..3dd40f7c0 100644 --- a/drivers/gpu/nvgpu/common/fence/fence.c +++ b/drivers/gpu/nvgpu/common/fence/fence.c @@ -90,9 +90,7 @@ int nvgpu_fence_install_fd(struct nvgpu_fence_type *f, int fd) return -EINVAL; } - f->os_fence.ops->install_fence(&f->os_fence, fd); - - return 0; + return f->os_fence.ops->install_fence(&f->os_fence, fd); } int nvgpu_fence_wait(struct gk20a *g, struct nvgpu_fence_type *f, diff --git a/drivers/gpu/nvgpu/common/sync/channel_sync_syncpt.c b/drivers/gpu/nvgpu/common/sync/channel_sync_syncpt.c index 50ee638f5..1b245c540 100644 --- a/drivers/gpu/nvgpu/common/sync/channel_sync_syncpt.c +++ b/drivers/gpu/nvgpu/common/sync/channel_sync_syncpt.c @@ -22,6 +22,10 @@ * DEALINGS IN THE SOFTWARE. */ +#ifndef CONFIG_NVGPU_SYNCFD_NONE +#include +#endif + #include #include #include @@ -57,8 +61,7 @@ nvgpu_channel_sync_syncpt_from_base(struct nvgpu_channel_sync *base) } static void channel_sync_syncpt_gen_wait_cmd(struct nvgpu_channel *c, - u32 id, u32 thresh, struct priv_cmd_entry *wait_cmd, - u32 wait_cmd_size) + u32 id, u32 thresh, struct priv_cmd_entry *wait_cmd) { nvgpu_log(c->g, gpu_dbg_info, "sp->id %d gpu va %llx", id, c->vm->syncpt_ro_map_gpu_va); @@ -77,19 +80,31 @@ static int channel_sync_syncpt_wait_raw(struct nvgpu_channel_sync_syncpt *s, return -EINVAL; } - err = nvgpu_priv_cmdbuf_alloc(c->priv_cmd_q, - c->g->ops.sync.syncpt.get_wait_cmd_size(), - wait_cmd); + err = nvgpu_priv_cmdbuf_alloc(c->priv_cmd_q, wait_cmd_size, wait_cmd); if (err != 0) { return err; } - channel_sync_syncpt_gen_wait_cmd(c, id, thresh, - *wait_cmd, wait_cmd_size); + channel_sync_syncpt_gen_wait_cmd(c, id, thresh, *wait_cmd); return 0; } +#ifndef CONFIG_NVGPU_SYNCFD_NONE +struct gen_wait_cmd_iter_data { + struct nvgpu_channel *c; + struct priv_cmd_entry *wait_cmd; +}; + +static int gen_wait_cmd_iter(struct nvhost_ctrl_sync_fence_info info, void *d) +{ + struct gen_wait_cmd_iter_data *data = d; + + channel_sync_syncpt_gen_wait_cmd(data->c, info.id, info.thresh, + data->wait_cmd); + return 0; +} + static int channel_sync_syncpt_wait_fd(struct nvgpu_channel_sync *s, int fd, struct priv_cmd_entry **wait_cmd, u32 max_wait_cmds) { @@ -98,10 +113,11 @@ static int channel_sync_syncpt_wait_fd(struct nvgpu_channel_sync *s, int fd, struct nvgpu_channel_sync_syncpt *sp = nvgpu_channel_sync_syncpt_from_base(s); struct nvgpu_channel *c = sp->c; + struct gen_wait_cmd_iter_data iter_data = { + .c = c + }; + u32 num_fences, wait_cmd_size; int err = 0; - u32 i, num_fences, wait_cmd_size; - u32 syncpt_id = 0U; - u32 syncpt_thresh = 0U; err = nvgpu_os_fence_fdget(&os_fence, c, fd); if (err != 0) { @@ -124,16 +140,6 @@ static int channel_sync_syncpt_wait_fd(struct nvgpu_channel_sync *s, int fd, goto cleanup; } - for (i = 0; i < num_fences; i++) { - nvgpu_os_fence_syncpt_extract_nth_syncpt( - &os_fence_syncpt, i, &syncpt_id, &syncpt_thresh); - if ((syncpt_id == 0U) || !nvgpu_nvhost_syncpt_is_valid_pt_ext( - c->g->nvhost, syncpt_id)) { - err = -EINVAL; - goto cleanup; - } - } - wait_cmd_size = c->g->ops.sync.syncpt.get_wait_cmd_size(); err = nvgpu_priv_cmdbuf_alloc(c->priv_cmd_q, wait_cmd_size * num_fences, wait_cmd); @@ -141,17 +147,26 @@ static int channel_sync_syncpt_wait_fd(struct nvgpu_channel_sync *s, int fd, goto cleanup; } - for (i = 0; i < num_fences; i++) { - nvgpu_os_fence_syncpt_extract_nth_syncpt( - &os_fence_syncpt, i, &syncpt_id, &syncpt_thresh); - channel_sync_syncpt_gen_wait_cmd(c, syncpt_id, - syncpt_thresh, *wait_cmd, wait_cmd_size); - } + iter_data.wait_cmd = *wait_cmd; + + nvgpu_os_fence_syncpt_foreach_pt(&os_fence_syncpt, + gen_wait_cmd_iter, &iter_data); cleanup: os_fence.ops->drop_ref(&os_fence); return err; } +#else /* CONFIG_NVGPU_SYNCFD_NONE */ +static int channel_sync_syncpt_wait_fd(struct nvgpu_channel_sync *s, int fd, + struct priv_cmd_entry **wait_cmd, u32 max_wait_cmds) +{ + struct nvgpu_channel_sync_syncpt *sp = + nvgpu_channel_sync_syncpt_from_base(s); + nvgpu_err(sp->c->g, + "trying to use sync fds with CONFIG_NVGPU_SYNCFD_NONE"); + return -ENODEV; +} +#endif /* CONFIG_NVGPU_SYNCFD_NONE */ static void channel_sync_syncpt_update(void *priv, int nr_completed) { diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h b/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h index fbd518488..3dc032923 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h +++ b/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_android.h @@ -31,9 +31,9 @@ int nvgpu_os_fence_sema_fdget(struct nvgpu_os_fence *fence_out, void nvgpu_os_fence_init(struct nvgpu_os_fence *fence_out, struct gk20a *g, const struct nvgpu_os_fence_ops *fops, - struct sync_fence *fence); + void *fence); -void nvgpu_os_fence_android_install_fd(struct nvgpu_os_fence *s, int fd); +int nvgpu_os_fence_android_install_fd(struct nvgpu_os_fence *s, int fd); int nvgpu_os_fence_syncpt_fdget( struct nvgpu_os_fence *fence_out, diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_dma.h b/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_dma.h index b17545e01..7c57486d6 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_dma.h +++ b/drivers/gpu/nvgpu/include/nvgpu/linux/os_fence_dma.h @@ -31,9 +31,9 @@ int nvgpu_os_fence_sema_fdget(struct nvgpu_os_fence *fence_out, void nvgpu_os_fence_init(struct nvgpu_os_fence *fence_out, struct gk20a *g, const struct nvgpu_os_fence_ops *fops, - struct dma_fence *fence); + void *fence); -void nvgpu_os_fence_dma_install_fd(struct nvgpu_os_fence *s, int fd); +int nvgpu_os_fence_dma_install_fd(struct nvgpu_os_fence *s, int fd); int nvgpu_os_fence_syncpt_fdget(struct nvgpu_os_fence *fence_out, struct nvgpu_channel *c, int fd); diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvhost.h b/drivers/gpu/nvgpu/include/nvgpu/nvhost.h index 5f2f64d54..60df1e8f3 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/nvhost.h +++ b/drivers/gpu/nvgpu/include/nvgpu/nvhost.h @@ -31,8 +31,6 @@ struct gk20a; #ifdef CONFIG_TEGRA_GK20A_NVHOST struct nvgpu_nvhost_dev; -struct sync_pt; -struct sync_fence; /** * @file Functions that initialize the sync points @@ -241,17 +239,6 @@ u32 nvgpu_nvhost_get_syncpt_client_managed(struct nvgpu_nvhost_dev *nvgpu_syncpt_dev, const char *syncpt_name); -#ifdef CONFIG_NVGPU_SYNCFD_ANDROID -u32 nvgpu_nvhost_sync_pt_id(struct sync_pt *pt); -u32 nvgpu_nvhost_sync_pt_thresh(struct sync_pt *pt); -int nvgpu_nvhost_sync_num_pts(struct sync_fence *fence); - -struct sync_fence *nvgpu_nvhost_sync_fdget(int fd); -struct sync_fence *nvgpu_nvhost_sync_create_fence( - struct nvgpu_nvhost_dev *nvgpu_syncpt_dev, - u32 id, u32 thresh, const char *name); -#endif /* CONFIG_NVGPU_SYNCFD_ANDROID */ - #ifdef CONFIG_TEGRA_T19X_GRHOST /** diff --git a/drivers/gpu/nvgpu/include/nvgpu/os_fence.h b/drivers/gpu/nvgpu/include/nvgpu/os_fence.h index 0de7c1f46..ae418589b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/os_fence.h +++ b/drivers/gpu/nvgpu/include/nvgpu/os_fence.h @@ -58,12 +58,15 @@ struct nvgpu_os_fence_ops { * Used to install the fd in the corresponding OS. The underlying * implementation varies from OS to OS. */ - void (*install_fence)(struct nvgpu_os_fence *s, int fd); + int (*install_fence)(struct nvgpu_os_fence *s, int fd); }; /* - * The priv structure here is used to contain the struct sync_fence - * for LINUX_VERSION <= 4.9 and dma_fence for LINUX_VERSION > 4.9 + * The priv field contains the actual backend: + * - struct sync_fence for semas on LINUX_VERSION <= 4.14 + * - struct dma_fence for semas on LINUX_VERSION > 4.14 + * - struct nvhost_fence (which is an opaque alias for one of the two above) + * for syncpt-backed fences on all kernel versions */ struct nvgpu_os_fence { void *priv; diff --git a/drivers/gpu/nvgpu/include/nvgpu/os_fence_syncpts.h b/drivers/gpu/nvgpu/include/nvgpu/os_fence_syncpts.h index fb3346ce8..84e1fef22 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/os_fence_syncpts.h +++ b/drivers/gpu/nvgpu/include/nvgpu/os_fence_syncpts.h @@ -26,6 +26,7 @@ #define NVGPU_OS_FENCE_SYNCPT_H struct nvgpu_os_fence; +struct nvhost_ctrl_sync_fence_info; struct nvgpu_os_fence_syncpt { struct nvgpu_os_fence *fence; @@ -40,14 +41,15 @@ int nvgpu_os_fence_get_syncpts(struct nvgpu_os_fence_syncpt *fence_syncpt_out, struct nvgpu_os_fence *fence_in); /* - * This method returns the nth syncpt id and syncpt threshold as *syncpt_id - * and *syncpt_threshold respectively and should be called on a valid - * instance of type nvgpu_os_fence_syncpt. + * Go through the id/value pairs inside a sync fd and call the supplied iter + * callback for each, providing the given data pointer as the second argument. + * The first argument contains the syncpt id and threshold for each individual + * fence. */ -void nvgpu_os_fence_syncpt_extract_nth_syncpt( - struct nvgpu_os_fence_syncpt *fence, u32 n, - u32 *syncpt_id, u32 *syncpt_threshold); - +int nvgpu_os_fence_syncpt_foreach_pt( + struct nvgpu_os_fence_syncpt *fence, + int (*iter)(struct nvhost_ctrl_sync_fence_info, void *), + void *data); /* * This method returns the number of underlying syncpoints @@ -66,12 +68,6 @@ static inline int nvgpu_os_fence_get_syncpts( return -EINVAL; } -static inline void nvgpu_os_fence_syncpt_extract_nth_syncpt( - struct nvgpu_os_fence_syncpt *fence, u32 n, - u32 *syncpt_id, u32 *syncpt_threshold) -{ -} - static inline u32 nvgpu_os_fence_syncpt_get_num_syncpoints( struct nvgpu_os_fence_syncpt *fence) { diff --git a/drivers/gpu/nvgpu/os/linux/nvhost.c b/drivers/gpu/nvgpu/os/linux/nvhost.c index 9945c06a3..e1139ab5c 100644 --- a/drivers/gpu/nvgpu/os/linux/nvhost.c +++ b/drivers/gpu/nvgpu/os/linux/nvhost.c @@ -237,40 +237,6 @@ void nvgpu_nvhost_remove_symlink(struct gk20a *g) } } -#ifndef CONFIG_NVGPU_SYNCFD_NONE -u32 nvgpu_nvhost_sync_pt_id(struct sync_pt *pt) -{ - return nvhost_sync_pt_id(pt); -} - -u32 nvgpu_nvhost_sync_pt_thresh(struct sync_pt *pt) -{ - return nvhost_sync_pt_thresh(pt); -} - -struct sync_fence *nvgpu_nvhost_sync_fdget(int fd) -{ - return nvhost_sync_fdget(fd); -} - -int nvgpu_nvhost_sync_num_pts(struct sync_fence *fence) -{ - return nvhost_sync_num_pts(fence); -} - -struct sync_fence *nvgpu_nvhost_sync_create_fence( - struct nvgpu_nvhost_dev *nvhost_dev, - u32 id, u32 thresh, const char *name) -{ - struct nvhost_ctrl_sync_fence_info pt = { - .id = id, - .thresh = thresh, - }; - - return nvhost_sync_create_fence(nvhost_dev->host1x_pdev, &pt, 1, name); -} -#endif /* !CONFIG_NVGPU_SYNCFD_NONE */ - #ifdef CONFIG_TEGRA_T19X_GRHOST int nvgpu_nvhost_get_syncpt_aperture( struct nvgpu_nvhost_dev *nvhost_dev, diff --git a/drivers/gpu/nvgpu/os/linux/os_fence_android.c b/drivers/gpu/nvgpu/os/linux/os_fence_android.c index 1c07ac605..7bbb3dd95 100644 --- a/drivers/gpu/nvgpu/os/linux/os_fence_android.c +++ b/drivers/gpu/nvgpu/os/linux/os_fence_android.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -37,11 +37,11 @@ static void nvgpu_os_fence_clear(struct nvgpu_os_fence *fence_out) void nvgpu_os_fence_init(struct nvgpu_os_fence *fence_out, struct gk20a *g, const struct nvgpu_os_fence_ops *fops, - struct sync_fence *fence) + void *fence) { fence_out->g = g; fence_out->ops = fops; - fence_out->priv = (void *)fence; + fence_out->priv = fence; } void nvgpu_os_fence_android_drop_ref(struct nvgpu_os_fence *s) @@ -53,12 +53,14 @@ void nvgpu_os_fence_android_drop_ref(struct nvgpu_os_fence *s) nvgpu_os_fence_clear(s); } -void nvgpu_os_fence_android_install_fd(struct nvgpu_os_fence *s, int fd) +int nvgpu_os_fence_android_install_fd(struct nvgpu_os_fence *s, int fd) { struct sync_fence *fence = nvgpu_get_sync_fence(s); sync_fence_get(fence); sync_fence_install(fence, fd); + + return 0; } int nvgpu_os_fence_fdget(struct nvgpu_os_fence *fence_out, diff --git a/drivers/gpu/nvgpu/os/linux/os_fence_android_syncpt.c b/drivers/gpu/nvgpu/os/linux/os_fence_android_syncpt.c index 459b02670..7143fa99e 100644 --- a/drivers/gpu/nvgpu/os/linux/os_fence_android_syncpt.c +++ b/drivers/gpu/nvgpu/os/linux/os_fence_android_syncpt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -14,7 +14,10 @@ * along with this program. If not, see . */ +#include + #include +#include #include #include @@ -27,19 +30,34 @@ #include #include -#include "../drivers/staging/android/sync.h" +#include "nvhost_priv.h" + +static int nvgpu_os_fence_android_syncpt_install_fd(struct nvgpu_os_fence *s, + int fd) +{ + return nvhost_fence_install(s->priv, fd); +} + +static void nvgpu_os_fence_android_syncpt_drop_ref(struct nvgpu_os_fence *s) +{ + nvhost_fence_put(s->priv); +} static const struct nvgpu_os_fence_ops syncpt_ops = { - .drop_ref = nvgpu_os_fence_android_drop_ref, - .install_fence = nvgpu_os_fence_android_install_fd, + .drop_ref = nvgpu_os_fence_android_syncpt_drop_ref, + .install_fence = nvgpu_os_fence_android_syncpt_install_fd, }; -int nvgpu_os_fence_syncpt_create( - struct nvgpu_os_fence *fence_out, struct nvgpu_channel *c, - struct nvgpu_nvhost_dev *nvhost_dev, u32 id, u32 thresh) +int nvgpu_os_fence_syncpt_create(struct nvgpu_os_fence *fence_out, + struct nvgpu_channel *c, struct nvgpu_nvhost_dev *nvhost_dev, + u32 id, u32 thresh) { - struct sync_fence *fence = nvgpu_nvhost_sync_create_fence( - nvhost_dev, id, thresh, "fence"); + struct nvhost_ctrl_sync_fence_info pt = { + .id = id, + .thresh = thresh, + }; + struct nvhost_fence *fence = nvhost_fence_create( + nvhost_dev->host1x_pdev, &pt, 1, "fence"); if (IS_ERR(fence)) { nvgpu_err(c->g, "error %d during construction of fence.", @@ -55,7 +73,7 @@ int nvgpu_os_fence_syncpt_create( int nvgpu_os_fence_syncpt_fdget(struct nvgpu_os_fence *fence_out, struct nvgpu_channel *c, int fd) { - struct sync_fence *fence = nvgpu_nvhost_sync_fdget(fd); + struct nvhost_fence *fence = nvhost_fence_get(fd); if (fence == NULL) { return -ENOMEM; @@ -82,19 +100,13 @@ int nvgpu_os_fence_get_syncpts( u32 nvgpu_os_fence_syncpt_get_num_syncpoints( struct nvgpu_os_fence_syncpt *fence) { - struct sync_fence *f = nvgpu_get_sync_fence(fence->fence); - - return (u32)f->num_fences; + return nvhost_fence_num_pts(fence->fence->priv); } -void nvgpu_os_fence_syncpt_extract_nth_syncpt( - struct nvgpu_os_fence_syncpt *fence, u32 n, - u32 *syncpt_id, u32 *syncpt_threshold) +int nvgpu_os_fence_syncpt_foreach_pt( + struct nvgpu_os_fence_syncpt *fence, + int (*iter)(struct nvhost_ctrl_sync_fence_info, void *), + void *data) { - - struct sync_fence *f = nvgpu_get_sync_fence(fence->fence); - struct sync_pt *pt = sync_pt_from_fence(f->cbs[n].sync_pt); - - *syncpt_id = nvgpu_nvhost_sync_pt_id(pt); - *syncpt_threshold = nvgpu_nvhost_sync_pt_thresh(pt); + return nvhost_fence_foreach_pt(fence->fence->priv, iter, data); } diff --git a/drivers/gpu/nvgpu/os/linux/os_fence_dma.c b/drivers/gpu/nvgpu/os/linux/os_fence_dma.c index b24b20b63..28c4bf450 100644 --- a/drivers/gpu/nvgpu/os/linux/os_fence_dma.c +++ b/drivers/gpu/nvgpu/os/linux/os_fence_dma.c @@ -38,11 +38,11 @@ static void nvgpu_os_fence_clear(struct nvgpu_os_fence *fence_out) void nvgpu_os_fence_init(struct nvgpu_os_fence *fence_out, struct gk20a *g, const struct nvgpu_os_fence_ops *fops, - struct dma_fence *fence) + void *fence) { fence_out->g = g; fence_out->ops = fops; - fence_out->priv = (void *)fence; + fence_out->priv = fence; } void nvgpu_os_fence_dma_drop_ref(struct nvgpu_os_fence *s) @@ -54,12 +54,17 @@ void nvgpu_os_fence_dma_drop_ref(struct nvgpu_os_fence *s) nvgpu_os_fence_clear(s); } -void nvgpu_os_fence_dma_install_fd(struct nvgpu_os_fence *s, int fd) +int nvgpu_os_fence_dma_install_fd(struct nvgpu_os_fence *s, int fd) { struct dma_fence *fence = nvgpu_get_dma_fence(s); struct sync_file *file = sync_file_create(fence); + if (file == NULL) { + return -ENOMEM; + } + fd_install(fd, file->file); + return 0; } int nvgpu_os_fence_fdget(struct nvgpu_os_fence *fence_out, diff --git a/drivers/gpu/nvgpu/os/linux/os_fence_dma_syncpt.c b/drivers/gpu/nvgpu/os/linux/os_fence_dma_syncpt.c index eea248d33..a917428b9 100644 --- a/drivers/gpu/nvgpu/os/linux/os_fence_dma_syncpt.c +++ b/drivers/gpu/nvgpu/os/linux/os_fence_dma_syncpt.c @@ -60,11 +60,11 @@ u32 nvgpu_os_fence_syncpt_get_num_syncpoints( return -EINVAL; } -void nvgpu_os_fence_syncpt_extract_nth_syncpt( - struct nvgpu_os_fence_syncpt *fence, u32 n, - u32 *syncpt_id, u32 *syncpt_threshold) +int nvgpu_os_fence_syncpt_foreach_pt( + struct nvgpu_os_fence_syncpt *fence, + int (*iter)(struct nvhost_ctrl_sync_fence_info, void *), + void *data) { WARN(1, "can't get here until nvhost support exists"); - *syncpt_id = 0; - *syncpt_threshold = 0; + return -EINVAL; }