diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2018-02-13 07:02:38 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-02-26 06:48:11 -0500 |
commit | 8d5536271f989e01018a543016340a3d76a2fae2 (patch) | |
tree | c4981034e75b1933862b35518157c0897027e2b7 /drivers/gpu/nvgpu/common/linux/ioctl_channel.c | |
parent | 180604fec0bde1710923e78a3877d49892cbf883 (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.c | 67 |
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 | ||
952 | static 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 | |||
951 | long gk20a_channel_ioctl(struct file *filp, | 1006 | long 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; |