summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c40
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h7
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.c12
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h2
4 files changed, 58 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 83c49d52..a68968fe 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -376,6 +376,13 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force)
376 if(g->ops.fifo.free_channel_ctx_header) 376 if(g->ops.fifo.free_channel_ctx_header)
377 g->ops.fifo.free_channel_ctx_header(ch); 377 g->ops.fifo.free_channel_ctx_header(ch);
378 378
379 if (ch->usermode_submit_enabled) {
380 gk20a_channel_free_usermode_buffers(ch);
381 ch->userd_iova = nvgpu_mem_get_addr(g, &f->userd) +
382 ch->chid * f->userd_entry_size;
383 ch->usermode_submit_enabled = false;
384 }
385
379 gk20a_gr_flush_channel_tlb(gr); 386 gk20a_gr_flush_channel_tlb(gr);
380 387
381 nvgpu_dma_unmap_free(ch_vm, &ch->gpfifo.mem); 388 nvgpu_dma_unmap_free(ch_vm, &ch->gpfifo.mem);
@@ -1086,12 +1093,30 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c,
1086 goto clean_up_idle; 1093 goto clean_up_idle;
1087 } 1094 }
1088 1095
1096 if (gpfifo_args->flags & NVGPU_GPFIFO_FLAGS_USERMODE_SUPPORT) {
1097 if (g->ops.fifo.alloc_usermode_buffers) {
1098 err = g->ops.fifo.alloc_usermode_buffers(c,
1099 gpfifo_args);
1100 if (err) {
1101 nvgpu_err(g, "Usermode buffer alloc failed");
1102 goto clean_up;
1103 }
1104 c->userd_iova = nvgpu_mem_get_addr(g,
1105 &c->usermode_userd);
1106 c->usermode_submit_enabled = true;
1107 } else {
1108 nvgpu_err(g, "Usermode submit not supported");
1109 err = -EINVAL;
1110 goto clean_up;
1111 }
1112 }
1113
1089 err = nvgpu_dma_alloc_map_sys(ch_vm, 1114 err = nvgpu_dma_alloc_map_sys(ch_vm,
1090 gpfifo_size * gpfifo_entry_size, 1115 gpfifo_size * gpfifo_entry_size,
1091 &c->gpfifo.mem); 1116 &c->gpfifo.mem);
1092 if (err) { 1117 if (err) {
1093 nvgpu_err(g, "%s: memory allocation failed", __func__); 1118 nvgpu_err(g, "%s: memory allocation failed", __func__);
1094 goto clean_up; 1119 goto clean_up_usermode;
1095 } 1120 }
1096 1121
1097 if (c->gpfifo.mem.aperture == APERTURE_VIDMEM || g->mm.force_pramin) { 1122 if (c->gpfifo.mem.aperture == APERTURE_VIDMEM || g->mm.force_pramin) {
@@ -1174,6 +1199,13 @@ clean_up_sync:
1174clean_up_unmap: 1199clean_up_unmap:
1175 nvgpu_big_free(g, c->gpfifo.pipe); 1200 nvgpu_big_free(g, c->gpfifo.pipe);
1176 nvgpu_dma_unmap_free(ch_vm, &c->gpfifo.mem); 1201 nvgpu_dma_unmap_free(ch_vm, &c->gpfifo.mem);
1202clean_up_usermode:
1203 if (c->usermode_submit_enabled) {
1204 gk20a_channel_free_usermode_buffers(c);
1205 c->userd_iova = nvgpu_mem_get_addr(g, &g->fifo.userd) +
1206 c->chid * g->fifo.userd_entry_size;
1207 c->usermode_submit_enabled = false;
1208 }
1177clean_up: 1209clean_up:
1178 memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc)); 1210 memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc));
1179clean_up_idle: 1211clean_up_idle:
@@ -1187,6 +1219,12 @@ clean_up_idle:
1187 return err; 1219 return err;
1188} 1220}
1189 1221
1222void gk20a_channel_free_usermode_buffers(struct channel_gk20a *c)
1223{
1224 if (nvgpu_mem_is_valid(&c->usermode_userd))
1225 nvgpu_dma_free(c->g, &c->usermode_userd);
1226}
1227
1190/* Update with this periodically to determine how the gpfifo is draining. */ 1228/* Update with this periodically to determine how the gpfifo is draining. */
1191static inline u32 update_gp_get(struct gk20a *g, 1229static inline u32 update_gp_get(struct gk20a *g,
1192 struct channel_gk20a *c) 1230 struct channel_gk20a *c)
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index eaa5f81b..cd5bf7d7 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -45,10 +45,14 @@ struct fifo_profile_gk20a;
45#define NVGPU_GPFIFO_FLAGS_SUPPORT_VPR (1 << 0) 45#define NVGPU_GPFIFO_FLAGS_SUPPORT_VPR (1 << 0)
46#define NVGPU_GPFIFO_FLAGS_SUPPORT_DETERMINISTIC (1 << 1) 46#define NVGPU_GPFIFO_FLAGS_SUPPORT_DETERMINISTIC (1 << 1)
47#define NVGPU_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE (1 << 2) 47#define NVGPU_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE (1 << 2)
48#define NVGPU_GPFIFO_FLAGS_USERMODE_SUPPORT (1 << 3)
48 49
49struct nvgpu_gpfifo_args { 50struct nvgpu_gpfifo_args {
50 u32 num_entries; 51 u32 num_entries;
51 u32 num_inflight_jobs; 52 u32 num_inflight_jobs;
53 u32 userd_dmabuf_fd;
54 u32 gpfifo_dmabuf_fd;
55 u32 work_submit_token;
52 u32 flags; 56 u32 flags;
53}; 57};
54 58
@@ -184,6 +188,7 @@ struct channel_gk20a {
184 /* deterministic, but explicitly idle and submits disallowed */ 188 /* deterministic, but explicitly idle and submits disallowed */
185 bool deterministic_railgate_allowed; 189 bool deterministic_railgate_allowed;
186 bool cde; 190 bool cde;
191 bool usermode_submit_enabled;
187 pid_t pid; 192 pid_t pid;
188 pid_t tgid; 193 pid_t tgid;
189 struct nvgpu_mutex ioctl_lock; 194 struct nvgpu_mutex ioctl_lock;
@@ -198,6 +203,7 @@ struct channel_gk20a {
198 203
199 struct gpfifo_desc gpfifo; 204 struct gpfifo_desc gpfifo;
200 205
206 struct nvgpu_mem usermode_userd; /* Used for Usermode Submission */
201 struct nvgpu_mem inst_block; 207 struct nvgpu_mem inst_block;
202 208
203 u64 userd_iova; 209 u64 userd_iova;
@@ -361,6 +367,7 @@ void free_priv_cmdbuf(struct channel_gk20a *c,
361void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, 367void gk20a_channel_clean_up_jobs(struct channel_gk20a *c,
362 bool clean_all); 368 bool clean_all);
363 369
370void gk20a_channel_free_usermode_buffers(struct channel_gk20a *c);
364u32 nvgpu_get_gpfifo_entry_size(void); 371u32 nvgpu_get_gpfifo_entry_size(void);
365 372
366#endif /* CHANNEL_GK20A_H */ 373#endif /* CHANNEL_GK20A_H */
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index fd7faa22..c446e3ea 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -3916,11 +3916,19 @@ void gk20a_fifo_setup_ramfc_for_privileged_channel(struct channel_gk20a *c)
3916int gk20a_fifo_setup_userd(struct channel_gk20a *c) 3916int gk20a_fifo_setup_userd(struct channel_gk20a *c)
3917{ 3917{
3918 struct gk20a *g = c->g; 3918 struct gk20a *g = c->g;
3919 struct nvgpu_mem *mem = &g->fifo.userd; 3919 struct nvgpu_mem *mem;
3920 u32 offset = c->chid * g->fifo.userd_entry_size / sizeof(u32); 3920 u32 offset;
3921 3921
3922 gk20a_dbg_fn(""); 3922 gk20a_dbg_fn("");
3923 3923
3924 if (nvgpu_mem_is_valid(&c->usermode_userd)) {
3925 mem = &c->usermode_userd;
3926 offset = 0;
3927 } else {
3928 mem = &g->fifo.userd;
3929 offset = c->chid * g->fifo.userd_entry_size / sizeof(u32);
3930 }
3931
3924 nvgpu_mem_wr32(g, mem, offset + ram_userd_put_w(), 0); 3932 nvgpu_mem_wr32(g, mem, offset + ram_userd_put_w(), 0);
3925 nvgpu_mem_wr32(g, mem, offset + ram_userd_get_w(), 0); 3933 nvgpu_mem_wr32(g, mem, offset + ram_userd_get_w(), 0);
3926 nvgpu_mem_wr32(g, mem, offset + ram_userd_ref_w(), 0); 3934 nvgpu_mem_wr32(g, mem, offset + ram_userd_ref_w(), 0);
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index d61423d1..4a1c2f75 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -637,6 +637,8 @@ struct gpu_ops {
637 int (*channel_suspend)(struct gk20a *g); 637 int (*channel_suspend)(struct gk20a *g);
638 int (*channel_resume)(struct gk20a *g); 638 int (*channel_resume)(struct gk20a *g);
639 void (*set_error_notifier)(struct channel_gk20a *ch, u32 error); 639 void (*set_error_notifier)(struct channel_gk20a *ch, u32 error);
640 int (*alloc_usermode_buffers)(struct channel_gk20a *c,
641 struct nvgpu_gpfifo_args *gpfifo_args);
640#ifdef CONFIG_TEGRA_GK20A_NVHOST 642#ifdef CONFIG_TEGRA_GK20A_NVHOST
641 int (*alloc_syncpt_buf)(struct channel_gk20a *c, 643 int (*alloc_syncpt_buf)(struct channel_gk20a *c,
642 u32 syncpt_id, struct nvgpu_mem *syncpt_buf); 644 u32 syncpt_id, struct nvgpu_mem *syncpt_buf);