From 8d5536271f989e01018a543016340a3d76a2fae2 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Tue, 13 Feb 2018 04:02:38 -0800 Subject: gpu: nvgpu: add user API to get a syncpoint Add new user API NVGPU_IOCTL_CHANNEL_GET_USER_SYNCPOINT which will expose per-channel allocated syncpoint to user space API will also return current value of the syncpoint On supported platforms, this API will also return a RW semaphore address (corresponding to syncpoint shim) to user space Add new characteristics flag NVGPU_GPU_FLAGS_SUPPORT_USER_SYNCPOINT to indicate support for this new API Add new flag NVGPU_SUPPORT_USER_SYNCPOINT for use of core driver Set this flag for GV11B and GP10B for now Add a new API (*syncpt_address) in struct gk20a_channel_sync to get GPU_VA address of a syncpoint Add new API nvgpu_nvhost_syncpt_read_maxval() which will read and return MAX value of syncpoint Bug 200326065 Jira NVGPU-179 Change-Id: I9da6f17b85996f4fc6731c0bf94fca6f3181c3e0 Signed-off-by: Deepak Nibade Reviewed-on: https://git-master.nvidia.com/r/1658009 Reviewed-by: svc-mobile-coverity GVS: Gerrit_Virtual_Submit Reviewed-by: Konsta Holtta Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/ioctl_channel.c | 67 ++++++++++++++++++++++++++ drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c | 2 + drivers/gpu/nvgpu/common/linux/nvhost.c | 6 +++ 3 files changed, 75 insertions(+) (limited to 'drivers/gpu/nvgpu/common') diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c index b7856ca0..ab6ac9b9 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "gk20a/gk20a.h" #include "gk20a/dbg_gpu_gk20a.h" @@ -948,6 +949,60 @@ static int nvgpu_ioctl_channel_set_preemption_mode(struct channel_gk20a *ch, return err; } +static int nvgpu_ioctl_channel_get_user_syncpoint(struct channel_gk20a *ch, + struct nvgpu_get_user_syncpoint_args *args) +{ +#ifdef CONFIG_TEGRA_GK20A_NVHOST + struct gk20a *g = ch->g; + int err; + + if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_USER_SYNCPOINT)) { + nvgpu_err(g, "user syncpoints not supported"); + return -EINVAL; + } + + if (!gk20a_platform_has_syncpoints(g)) { + nvgpu_err(g, "syncpoints not supported"); + return -EINVAL; + } + + if (g->aggressive_sync_destroy_thresh) { + nvgpu_err(g, "sufficient syncpoints not available"); + return -EINVAL; + } + + nvgpu_mutex_acquire(&ch->sync_lock); + if (ch->sync) { + nvgpu_mutex_release(&ch->sync_lock); + } else { + ch->sync = gk20a_channel_sync_create(ch); + if (!ch->sync) { + nvgpu_mutex_release(&ch->sync_lock); + return -ENOMEM; + } + nvgpu_mutex_release(&ch->sync_lock); + + if (g->ops.fifo.resetup_ramfc) { + err = g->ops.fifo.resetup_ramfc(ch); + if (err) + return err; + } + } + + args->syncpoint_id = ch->sync->syncpt_id(ch->sync); + args->syncpoint_max = nvgpu_nvhost_syncpt_read_maxval(g->nvhost_dev, + args->syncpoint_id); + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SYNCPOINT_ADDRESS)) + args->gpu_va = ch->sync->syncpt_address(ch->sync); + else + args->gpu_va = 0; + + return 0; +#else + return -EINVAL; +#endif +} + long gk20a_channel_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1239,6 +1294,18 @@ long gk20a_channel_ioctl(struct file *filp, err = -EINVAL; } break; + case NVGPU_IOCTL_CHANNEL_GET_USER_SYNCPOINT: + err = gk20a_busy(ch->g); + if (err) { + dev_err(dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + break; + } + err = nvgpu_ioctl_channel_get_user_syncpoint(ch, + (struct nvgpu_get_user_syncpoint_args *)buf); + gk20a_idle(ch->g); + break; default: dev_dbg(dev, "unrecognized ioctl cmd: 0x%x", cmd); err = -ENOTTY; diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c index 71a9bee6..257c04b2 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c @@ -158,6 +158,8 @@ static struct nvgpu_flags_mapping flags_mapping[] = { NVGPU_SUPPORT_DETERMINISTIC_OPTS}, {NVGPU_GPU_FLAGS_SUPPORT_SYNCPOINT_ADDRESS, NVGPU_SUPPORT_SYNCPOINT_ADDRESS}, + {NVGPU_GPU_FLAGS_SUPPORT_USER_SYNCPOINT, + NVGPU_SUPPORT_USER_SYNCPOINT}, {NVGPU_GPU_FLAGS_SUPPORT_IO_COHERENCE, NVGPU_SUPPORT_IO_COHERENCE}, {NVGPU_GPU_FLAGS_SUPPORT_RESCHEDULE_RUNLIST, diff --git a/drivers/gpu/nvgpu/common/linux/nvhost.c b/drivers/gpu/nvgpu/common/linux/nvhost.c index e0f83612..94bbfd70 100644 --- a/drivers/gpu/nvgpu/common/linux/nvhost.c +++ b/drivers/gpu/nvgpu/common/linux/nvhost.c @@ -152,6 +152,12 @@ int nvgpu_nvhost_syncpt_read_ext_check( return nvhost_syncpt_read_ext_check(nvhost_dev->host1x_pdev, id, val); } +u32 nvgpu_nvhost_syncpt_read_maxval( + struct nvgpu_nvhost_dev *nvhost_dev, u32 id) +{ + return nvhost_syncpt_read_maxval(nvhost_dev->host1x_pdev, id); +} + int nvgpu_nvhost_create_symlink(struct gk20a *g) { struct device *dev = dev_from_gk20a(g); -- cgit v1.2.2