summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/ioctl_channel.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2018-02-13 07:02:38 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-02-26 06:48:11 -0500
commit8d5536271f989e01018a543016340a3d76a2fae2 (patch)
treec4981034e75b1933862b35518157c0897027e2b7 /drivers/gpu/nvgpu/common/linux/ioctl_channel.c
parent180604fec0bde1710923e78a3877d49892cbf883 (diff)
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 <dnibade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1658009 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/ioctl_channel.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_channel.c67
1 files changed, 67 insertions, 0 deletions
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 @@
32#include <nvgpu/enabled.h> 32#include <nvgpu/enabled.h>
33#include <nvgpu/error_notifier.h> 33#include <nvgpu/error_notifier.h>
34#include <nvgpu/barrier.h> 34#include <nvgpu/barrier.h>
35#include <nvgpu/nvhost.h>
35 36
36#include "gk20a/gk20a.h" 37#include "gk20a/gk20a.h"
37#include "gk20a/dbg_gpu_gk20a.h" 38#include "gk20a/dbg_gpu_gk20a.h"
@@ -948,6 +949,60 @@ static int nvgpu_ioctl_channel_set_preemption_mode(struct channel_gk20a *ch,
948 return err; 949 return err;
949} 950}
950 951
952static int nvgpu_ioctl_channel_get_user_syncpoint(struct channel_gk20a *ch,
953 struct nvgpu_get_user_syncpoint_args *args)
954{
955#ifdef CONFIG_TEGRA_GK20A_NVHOST
956 struct gk20a *g = ch->g;
957 int err;
958
959 if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_USER_SYNCPOINT)) {
960 nvgpu_err(g, "user syncpoints not supported");
961 return -EINVAL;
962 }
963
964 if (!gk20a_platform_has_syncpoints(g)) {
965 nvgpu_err(g, "syncpoints not supported");
966 return -EINVAL;
967 }
968
969 if (g->aggressive_sync_destroy_thresh) {
970 nvgpu_err(g, "sufficient syncpoints not available");
971 return -EINVAL;
972 }
973
974 nvgpu_mutex_acquire(&ch->sync_lock);
975 if (ch->sync) {
976 nvgpu_mutex_release(&ch->sync_lock);
977 } else {
978 ch->sync = gk20a_channel_sync_create(ch);
979 if (!ch->sync) {
980 nvgpu_mutex_release(&ch->sync_lock);
981 return -ENOMEM;
982 }
983 nvgpu_mutex_release(&ch->sync_lock);
984
985 if (g->ops.fifo.resetup_ramfc) {
986 err = g->ops.fifo.resetup_ramfc(ch);
987 if (err)
988 return err;
989 }
990 }
991
992 args->syncpoint_id = ch->sync->syncpt_id(ch->sync);
993 args->syncpoint_max = nvgpu_nvhost_syncpt_read_maxval(g->nvhost_dev,
994 args->syncpoint_id);
995 if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SYNCPOINT_ADDRESS))
996 args->gpu_va = ch->sync->syncpt_address(ch->sync);
997 else
998 args->gpu_va = 0;
999
1000 return 0;
1001#else
1002 return -EINVAL;
1003#endif
1004}
1005
951long gk20a_channel_ioctl(struct file *filp, 1006long gk20a_channel_ioctl(struct file *filp,
952 unsigned int cmd, unsigned long arg) 1007 unsigned int cmd, unsigned long arg)
953{ 1008{
@@ -1239,6 +1294,18 @@ long gk20a_channel_ioctl(struct file *filp,
1239 err = -EINVAL; 1294 err = -EINVAL;
1240 } 1295 }
1241 break; 1296 break;
1297 case NVGPU_IOCTL_CHANNEL_GET_USER_SYNCPOINT:
1298 err = gk20a_busy(ch->g);
1299 if (err) {
1300 dev_err(dev,
1301 "%s: failed to host gk20a for ioctl cmd: 0x%x",
1302 __func__, cmd);
1303 break;
1304 }
1305 err = nvgpu_ioctl_channel_get_user_syncpoint(ch,
1306 (struct nvgpu_get_user_syncpoint_args *)buf);
1307 gk20a_idle(ch->g);
1308 break;
1242 default: 1309 default:
1243 dev_dbg(dev, "unrecognized ioctl cmd: 0x%x", cmd); 1310 dev_dbg(dev, "unrecognized ioctl cmd: 0x%x", cmd);
1244 err = -ENOTTY; 1311 err = -ENOTTY;