diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 40 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 12 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 2 |
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: | |||
1174 | clean_up_unmap: | 1199 | clean_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); |
1202 | clean_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 | } | ||
1177 | clean_up: | 1209 | clean_up: |
1178 | memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc)); | 1210 | memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc)); |
1179 | clean_up_idle: | 1211 | clean_up_idle: |
@@ -1187,6 +1219,12 @@ clean_up_idle: | |||
1187 | return err; | 1219 | return err; |
1188 | } | 1220 | } |
1189 | 1221 | ||
1222 | void 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. */ |
1191 | static inline u32 update_gp_get(struct gk20a *g, | 1229 | static 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 | ||
49 | struct nvgpu_gpfifo_args { | 50 | struct 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, | |||
361 | void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, | 367 | void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, |
362 | bool clean_all); | 368 | bool clean_all); |
363 | 369 | ||
370 | void gk20a_channel_free_usermode_buffers(struct channel_gk20a *c); | ||
364 | u32 nvgpu_get_gpfifo_entry_size(void); | 371 | u32 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) | |||
3916 | int gk20a_fifo_setup_userd(struct channel_gk20a *c) | 3916 | int 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); |