summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_channel.c67
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c2
-rw-r--r--drivers/gpu/nvgpu/common/linux/nvhost.c6
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c14
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gp10b/gp10b.c1
-rw-r--r--drivers/gpu/nvgpu/gv11b/gv11b.c2
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/enabled.h4
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/nvhost.h2
-rw-r--r--include/uapi/linux/nvgpu.h12
10 files changed, 111 insertions, 2 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;
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[] = {
158 NVGPU_SUPPORT_DETERMINISTIC_OPTS}, 158 NVGPU_SUPPORT_DETERMINISTIC_OPTS},
159 {NVGPU_GPU_FLAGS_SUPPORT_SYNCPOINT_ADDRESS, 159 {NVGPU_GPU_FLAGS_SUPPORT_SYNCPOINT_ADDRESS,
160 NVGPU_SUPPORT_SYNCPOINT_ADDRESS}, 160 NVGPU_SUPPORT_SYNCPOINT_ADDRESS},
161 {NVGPU_GPU_FLAGS_SUPPORT_USER_SYNCPOINT,
162 NVGPU_SUPPORT_USER_SYNCPOINT},
161 {NVGPU_GPU_FLAGS_SUPPORT_IO_COHERENCE, 163 {NVGPU_GPU_FLAGS_SUPPORT_IO_COHERENCE,
162 NVGPU_SUPPORT_IO_COHERENCE}, 164 NVGPU_SUPPORT_IO_COHERENCE},
163 {NVGPU_GPU_FLAGS_SUPPORT_RESCHEDULE_RUNLIST, 165 {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(
152 return nvhost_syncpt_read_ext_check(nvhost_dev->host1x_pdev, id, val); 152 return nvhost_syncpt_read_ext_check(nvhost_dev->host1x_pdev, id, val);
153} 153}
154 154
155u32 nvgpu_nvhost_syncpt_read_maxval(
156 struct nvgpu_nvhost_dev *nvhost_dev, u32 id)
157{
158 return nvhost_syncpt_read_maxval(nvhost_dev->host1x_pdev, id);
159}
160
155int nvgpu_nvhost_create_symlink(struct gk20a *g) 161int nvgpu_nvhost_create_symlink(struct gk20a *g)
156{ 162{
157 struct device *dev = dev_from_gk20a(g); 163 struct device *dev = dev_from_gk20a(g);
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
index 4a6b8162..e965a329 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
@@ -294,6 +294,13 @@ static int gk20a_channel_syncpt_id(struct gk20a_channel_sync *s)
294 return sp->id; 294 return sp->id;
295} 295}
296 296
297static u64 gk20a_channel_syncpt_address(struct gk20a_channel_sync *s)
298{
299 struct gk20a_channel_syncpt *sp =
300 container_of(s, struct gk20a_channel_syncpt, ops);
301 return sp->syncpt_buf.gpu_va;
302}
303
297static void gk20a_channel_syncpt_destroy(struct gk20a_channel_sync *s) 304static void gk20a_channel_syncpt_destroy(struct gk20a_channel_sync *s)
298{ 305{
299 struct gk20a_channel_syncpt *sp = 306 struct gk20a_channel_syncpt *sp =
@@ -345,6 +352,7 @@ gk20a_channel_syncpt_create(struct channel_gk20a *c)
345 sp->ops.set_min_eq_max = gk20a_channel_syncpt_set_min_eq_max; 352 sp->ops.set_min_eq_max = gk20a_channel_syncpt_set_min_eq_max;
346 sp->ops.signal_timeline = gk20a_channel_syncpt_signal_timeline; 353 sp->ops.signal_timeline = gk20a_channel_syncpt_signal_timeline;
347 sp->ops.syncpt_id = gk20a_channel_syncpt_id; 354 sp->ops.syncpt_id = gk20a_channel_syncpt_id;
355 sp->ops.syncpt_address = gk20a_channel_syncpt_address;
348 sp->ops.destroy = gk20a_channel_syncpt_destroy; 356 sp->ops.destroy = gk20a_channel_syncpt_destroy;
349 357
350 return &sp->ops; 358 return &sp->ops;
@@ -865,6 +873,11 @@ static int gk20a_channel_semaphore_syncpt_id(struct gk20a_channel_sync *s)
865 return -EINVAL; 873 return -EINVAL;
866} 874}
867 875
876static u64 gk20a_channel_semaphore_syncpt_address(struct gk20a_channel_sync *s)
877{
878 return 0;
879}
880
868static void gk20a_channel_semaphore_destroy(struct gk20a_channel_sync *s) 881static void gk20a_channel_semaphore_destroy(struct gk20a_channel_sync *s)
869{ 882{
870 struct gk20a_channel_semaphore *sema = 883 struct gk20a_channel_semaphore *sema =
@@ -916,6 +929,7 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c)
916 sema->ops.set_min_eq_max = gk20a_channel_semaphore_set_min_eq_max; 929 sema->ops.set_min_eq_max = gk20a_channel_semaphore_set_min_eq_max;
917 sema->ops.signal_timeline = gk20a_channel_semaphore_signal_timeline; 930 sema->ops.signal_timeline = gk20a_channel_semaphore_signal_timeline;
918 sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id; 931 sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id;
932 sema->ops.syncpt_address = gk20a_channel_semaphore_syncpt_address;
919 sema->ops.destroy = gk20a_channel_semaphore_destroy; 933 sema->ops.destroy = gk20a_channel_semaphore_destroy;
920 934
921 return &sema->ops; 935 return &sema->ops;
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h
index 2fd009df..fe1d8526 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h
@@ -102,6 +102,9 @@ struct gk20a_channel_sync {
102 /* Returns the sync point id or negative number if no syncpt*/ 102 /* Returns the sync point id or negative number if no syncpt*/
103 int (*syncpt_id)(struct gk20a_channel_sync *s); 103 int (*syncpt_id)(struct gk20a_channel_sync *s);
104 104
105 /* Returns the sync point address of sync point or 0 if not supported */
106 u64 (*syncpt_address)(struct gk20a_channel_sync *s);
107
105 /* Free the resources allocated by gk20a_channel_sync_create. */ 108 /* Free the resources allocated by gk20a_channel_sync_create. */
106 void (*destroy)(struct gk20a_channel_sync *s); 109 void (*destroy)(struct gk20a_channel_sync *s);
107}; 110};
diff --git a/drivers/gpu/nvgpu/gp10b/gp10b.c b/drivers/gpu/nvgpu/gp10b/gp10b.c
index 51dc4301..d0a21fe5 100644
--- a/drivers/gpu/nvgpu/gp10b/gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/gp10b.c
@@ -116,5 +116,6 @@ int gp10b_init_gpu_characteristics(struct gk20a *g)
116 gk20a_init_gpu_characteristics(g); 116 gk20a_init_gpu_characteristics(g);
117 gp10b_detect_ecc_enabled_units(g); 117 gp10b_detect_ecc_enabled_units(g);
118 __nvgpu_set_enabled(g, NVGPU_SUPPORT_RESCHEDULE_RUNLIST, true); 118 __nvgpu_set_enabled(g, NVGPU_SUPPORT_RESCHEDULE_RUNLIST, true);
119 __nvgpu_set_enabled(g, NVGPU_SUPPORT_USER_SYNCPOINT, true);
119 return 0; 120 return 0;
120} 121}
diff --git a/drivers/gpu/nvgpu/gv11b/gv11b.c b/drivers/gpu/nvgpu/gv11b/gv11b.c
index 2670c986..c1ad7944 100644
--- a/drivers/gpu/nvgpu/gv11b/gv11b.c
+++ b/drivers/gpu/nvgpu/gv11b/gv11b.c
@@ -155,5 +155,7 @@ int gv11b_init_gpu_characteristics(struct gk20a *g)
155 __nvgpu_set_enabled(g, NVGPU_SUPPORT_IO_COHERENCE, true); 155 __nvgpu_set_enabled(g, NVGPU_SUPPORT_IO_COHERENCE, true);
156 __nvgpu_set_enabled(g, NVGPU_SUPPORT_SCG, true); 156 __nvgpu_set_enabled(g, NVGPU_SUPPORT_SCG, true);
157 __nvgpu_set_enabled(g, NVGPU_SUPPORT_SYNCPOINT_ADDRESS, true); 157 __nvgpu_set_enabled(g, NVGPU_SUPPORT_SYNCPOINT_ADDRESS, true);
158 __nvgpu_set_enabled(g, NVGPU_SUPPORT_USER_SYNCPOINT, true);
159
158 return 0; 160 return 0;
159} 161}
diff --git a/drivers/gpu/nvgpu/include/nvgpu/enabled.h b/drivers/gpu/nvgpu/include/nvgpu/enabled.h
index e6f9525d..a3d9df24 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/enabled.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/enabled.h
@@ -157,11 +157,13 @@ struct gk20a;
157 157
158/* GPU_VA address of a syncpoint is supported */ 158/* GPU_VA address of a syncpoint is supported */
159#define NVGPU_SUPPORT_SYNCPOINT_ADDRESS 65 159#define NVGPU_SUPPORT_SYNCPOINT_ADDRESS 65
160/* Allocating per-channel syncpoint in user space is supported */
161#define NVGPU_SUPPORT_USER_SYNCPOINT 66
160 162
161/* 163/*
162 * Must be greater than the largest bit offset in the above list. 164 * Must be greater than the largest bit offset in the above list.
163 */ 165 */
164#define NVGPU_MAX_ENABLED_BITS 66 166#define NVGPU_MAX_ENABLED_BITS 67
165 167
166/** 168/**
167 * nvgpu_is_enabled - Check if the passed flag is enabled. 169 * nvgpu_is_enabled - Check if the passed flag is enabled.
diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvhost.h b/drivers/gpu/nvgpu/include/nvgpu/nvhost.h
index 6e92637a..cb70f436 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/nvhost.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/nvhost.h
@@ -50,6 +50,8 @@ void nvgpu_nvhost_syncpt_set_min_eq_max_ext(struct nvgpu_nvhost_dev *nvhost_dev,
50 u32 id); 50 u32 id);
51int nvgpu_nvhost_syncpt_read_ext_check(struct nvgpu_nvhost_dev *nvhost_dev, 51int nvgpu_nvhost_syncpt_read_ext_check(struct nvgpu_nvhost_dev *nvhost_dev,
52 u32 id, u32 *val); 52 u32 id, u32 *val);
53u32 nvgpu_nvhost_syncpt_read_maxval(struct nvgpu_nvhost_dev *nvhost_dev,
54 u32 id);
53 55
54int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev, 56int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev,
55 u32 id, u32 thresh, void (*callback)(void *, int), void *private_data); 57 u32 id, u32 thresh, void (*callback)(void *, int), void *private_data);
diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h
index f8211374..cf75595a 100644
--- a/include/uapi/linux/nvgpu.h
+++ b/include/uapi/linux/nvgpu.h
@@ -154,6 +154,8 @@ struct nvgpu_gpu_zbc_query_table_args {
154#define NVGPU_GPU_FLAGS_SUPPORT_SYNCPOINT_ADDRESS (1ULL << 26) 154#define NVGPU_GPU_FLAGS_SUPPORT_SYNCPOINT_ADDRESS (1ULL << 26)
155/* VPR is supported */ 155/* VPR is supported */
156#define NVGPU_GPU_FLAGS_SUPPORT_VPR (1ULL << 27) 156#define NVGPU_GPU_FLAGS_SUPPORT_VPR (1ULL << 27)
157/* Allocating per-channel syncpoint in user space is supported */
158#define NVGPU_GPU_FLAGS_SUPPORT_USER_SYNCPOINT (1ULL << 28)
157/* SM LRF ECC is enabled */ 159/* SM LRF ECC is enabled */
158#define NVGPU_GPU_FLAGS_ECC_ENABLED_SM_LRF (1ULL << 60) 160#define NVGPU_GPU_FLAGS_ECC_ENABLED_SM_LRF (1ULL << 60)
159/* SM SHM ECC is enabled */ 161/* SM SHM ECC is enabled */
@@ -1648,6 +1650,12 @@ struct nvgpu_boosted_ctx_args {
1648 __u32 padding; 1650 __u32 padding;
1649}; 1651};
1650 1652
1653struct nvgpu_get_user_syncpoint_args {
1654 __u64 gpu_va; /* out */
1655 __u32 syncpoint_id; /* out */
1656 __u32 syncpoint_max; /* out */
1657};
1658
1651#define NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD \ 1659#define NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD \
1652 _IOW(NVGPU_IOCTL_MAGIC, 5, struct nvgpu_set_nvmap_fd_args) 1660 _IOW(NVGPU_IOCTL_MAGIC, 5, struct nvgpu_set_nvmap_fd_args)
1653#define NVGPU_IOCTL_CHANNEL_SET_TIMEOUT \ 1661#define NVGPU_IOCTL_CHANNEL_SET_TIMEOUT \
@@ -1698,9 +1706,11 @@ struct nvgpu_boosted_ctx_args {
1698 _IOW(NVGPU_IOCTL_MAGIC, 124, struct nvgpu_boosted_ctx_args) 1706 _IOW(NVGPU_IOCTL_MAGIC, 124, struct nvgpu_boosted_ctx_args)
1699#define NVGPU_IOCTL_CHANNEL_GET_TIMESLICE \ 1707#define NVGPU_IOCTL_CHANNEL_GET_TIMESLICE \
1700 _IOW(NVGPU_IOCTL_MAGIC, 125, struct nvgpu_timeslice_args) 1708 _IOW(NVGPU_IOCTL_MAGIC, 125, struct nvgpu_timeslice_args)
1709#define NVGPU_IOCTL_CHANNEL_GET_USER_SYNCPOINT \
1710 _IOR(NVGPU_IOCTL_MAGIC, 126, struct nvgpu_get_user_syncpoint_args)
1701 1711
1702#define NVGPU_IOCTL_CHANNEL_LAST \ 1712#define NVGPU_IOCTL_CHANNEL_LAST \
1703 _IOC_NR(NVGPU_IOCTL_CHANNEL_GET_TIMESLICE) 1713 _IOC_NR(NVGPU_IOCTL_CHANNEL_GET_USER_SYNCPOINT)
1704#define NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvgpu_alloc_gpfifo_ex_args) 1714#define NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvgpu_alloc_gpfifo_ex_args)
1705 1715
1706/* 1716/*