summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Daifuku <pdaifuku@nvidia.com>2016-03-23 12:43:43 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-04-08 15:34:50 -0400
commit6eeabfbdd08e48f924885952c80ff41aa2b534b7 (patch)
tree5cdba48865faa0b76e20d0994fa9de9e4c12deed
parente8bac374c0ed24f05bf389e1e8b5aca47f61bd3a (diff)
gpu: nvgpu: vgpu: virtualized SMPC/HWPM ctx switch
Add support for SMPC and HWPM context switching when virtualized Bug 1648200 JIRASW EVLR-219 JIRASW EVLR-253 Change-Id: I80a1613eaad87d8510f00d9aef001400d642ecdf Signed-off-by: Peter Daifuku <pdaifuku@nvidia.com> Reviewed-on: http://git-master/r/1122034 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c8
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h6
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c2
-rw-r--r--drivers/gpu/nvgpu/vgpu/gr_vgpu.c83
-rw-r--r--include/linux/tegra_vgpu.h25
7 files changed, 122 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
index 321cebb2..309fe75a 100644
--- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
@@ -891,8 +891,8 @@ static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s,
891 goto clean_up; 891 goto clean_up;
892 } 892 }
893 893
894 err = gr_gk20a_update_smpc_ctxsw_mode(g, ch_gk20a, 894 err = g->ops.gr.update_smpc_ctxsw_mode(g, ch_gk20a,
895 args->mode == NVGPU_DBG_GPU_SMPC_CTXSW_MODE_CTXSW); 895 args->mode == NVGPU_DBG_GPU_SMPC_CTXSW_MODE_CTXSW);
896 if (err) { 896 if (err) {
897 gk20a_err(dev_from_gk20a(g), 897 gk20a_err(dev_from_gk20a(g),
898 "error (%d) during smpc ctxsw mode update\n", err); 898 "error (%d) during smpc ctxsw mode update\n", err);
@@ -927,8 +927,8 @@ static int nvgpu_dbg_gpu_ioctl_hwpm_ctxsw_mode(struct dbg_session_gk20a *dbg_s,
927 goto clean_up; 927 goto clean_up;
928 } 928 }
929 929
930 err = gr_gk20a_update_hwpm_ctxsw_mode(g, ch_gk20a, 930 err = g->ops.gr.update_hwpm_ctxsw_mode(g, ch_gk20a,
931 args->mode == NVGPU_DBG_GPU_HWPM_CTXSW_MODE_CTXSW); 931 args->mode == NVGPU_DBG_GPU_HWPM_CTXSW_MODE_CTXSW);
932 if (err) 932 if (err)
933 gk20a_err(dev_from_gk20a(g), 933 gk20a_err(dev_from_gk20a(g),
934 "error (%d) during pm ctxsw mode update\n", err); 934 "error (%d) during pm ctxsw mode update\n", err);
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 9d8dc5f7..d9cc3d4f 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -172,6 +172,12 @@ struct gpu_ops {
172 void (*update_ctxsw_preemption_mode)(struct gk20a *g, 172 void (*update_ctxsw_preemption_mode)(struct gk20a *g,
173 struct channel_ctx_gk20a *ch_ctx, 173 struct channel_ctx_gk20a *ch_ctx,
174 void *ctx_ptr); 174 void *ctx_ptr);
175 int (*update_smpc_ctxsw_mode)(struct gk20a *g,
176 struct channel_gk20a *c,
177 bool enable);
178 int (*update_hwpm_ctxsw_mode)(struct gk20a *g,
179 struct channel_gk20a *c,
180 bool enable);
175 int (*dump_gr_regs)(struct gk20a *g, 181 int (*dump_gr_regs)(struct gk20a *g,
176 struct gk20a_debug_output *o); 182 struct gk20a_debug_output *o);
177 int (*update_pc_sampling)(struct channel_gk20a *ch, 183 int (*update_pc_sampling)(struct channel_gk20a *ch,
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index b0b5571f..ada67edd 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -8308,4 +8308,6 @@ void gk20a_init_gr_ops(struct gpu_ops *gops)
8308 gops->gr.handle_sm_exception = gr_gk20a_handle_sm_exception; 8308 gops->gr.handle_sm_exception = gr_gk20a_handle_sm_exception;
8309 gops->gr.handle_tex_exception = gr_gk20a_handle_tex_exception; 8309 gops->gr.handle_tex_exception = gr_gk20a_handle_tex_exception;
8310 gops->gr.get_lrf_tex_ltc_dram_override = NULL; 8310 gops->gr.get_lrf_tex_ltc_dram_override = NULL;
8311 gops->gr.update_smpc_ctxsw_mode = gr_gk20a_update_smpc_ctxsw_mode;
8312 gops->gr.update_hwpm_ctxsw_mode = gr_gk20a_update_hwpm_ctxsw_mode;
8311} 8313}
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index 52d6c4e5..5390536e 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -76,6 +76,7 @@ struct zcull_ctx_desc {
76struct pm_ctx_desc { 76struct pm_ctx_desc {
77 struct mem_desc mem; 77 struct mem_desc mem;
78 u32 pm_mode; 78 u32 pm_mode;
79 bool ctx_was_enabled; /* Used in the virtual case only */
79}; 80};
80 81
81struct gk20a; 82struct gk20a;
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index 67654cba..6a79b1ac 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -1233,4 +1233,6 @@ void gm20b_init_gr(struct gpu_ops *gops)
1233 gops->gr.handle_sm_exception = gr_gk20a_handle_sm_exception; 1233 gops->gr.handle_sm_exception = gr_gk20a_handle_sm_exception;
1234 gops->gr.handle_tex_exception = gr_gk20a_handle_tex_exception; 1234 gops->gr.handle_tex_exception = gr_gk20a_handle_tex_exception;
1235 gops->gr.get_lrf_tex_ltc_dram_override = NULL; 1235 gops->gr.get_lrf_tex_ltc_dram_override = NULL;
1236 gops->gr.update_smpc_ctxsw_mode = gr_gk20a_update_smpc_ctxsw_mode;
1237 gops->gr.update_hwpm_ctxsw_mode = gr_gk20a_update_hwpm_ctxsw_mode;
1236} 1238}
diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
index 32e451ed..16d51ad3 100644
--- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
@@ -402,12 +402,36 @@ static void vgpu_gr_free_channel_patch_ctx(struct channel_gk20a *c)
402 } 402 }
403} 403}
404 404
405static void vgpu_gr_free_channel_pm_ctx(struct channel_gk20a *c)
406{
407 struct gk20a_platform *platform = gk20a_get_platform(c->g->dev);
408 struct tegra_vgpu_cmd_msg msg;
409 struct tegra_vgpu_channel_free_hwpm_ctx *p = &msg.params.free_hwpm_ctx;
410 struct channel_ctx_gk20a *ch_ctx = &c->ch_ctx;
411 int err;
412
413 gk20a_dbg_fn("");
414
415 /* check if hwpm was ever initialized. If not, nothing to do */
416 if (ch_ctx->pm_ctx.ctx_was_enabled == false)
417 return;
418
419 msg.cmd = TEGRA_VGPU_CMD_CHANNEL_FREE_HWPM_CTX;
420 msg.handle = platform->virt_handle;
421 p->handle = c->virt_ctx;
422 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
423 WARN_ON(err || msg.ret);
424
425 ch_ctx->pm_ctx.ctx_was_enabled = false;
426}
427
405static void vgpu_gr_free_channel_ctx(struct channel_gk20a *c) 428static void vgpu_gr_free_channel_ctx(struct channel_gk20a *c)
406{ 429{
407 gk20a_dbg_fn(""); 430 gk20a_dbg_fn("");
408 431
409 vgpu_gr_unmap_global_ctx_buffers(c); 432 vgpu_gr_unmap_global_ctx_buffers(c);
410 vgpu_gr_free_channel_patch_ctx(c); 433 vgpu_gr_free_channel_patch_ctx(c);
434 vgpu_gr_free_channel_pm_ctx(c);
411 if (!gk20a_is_channel_marked_as_tsg(c)) 435 if (!gk20a_is_channel_marked_as_tsg(c))
412 vgpu_gr_free_channel_gr_ctx(c); 436 vgpu_gr_free_channel_gr_ctx(c);
413 437
@@ -950,6 +974,63 @@ static int vgpu_gr_set_sm_debug_mode(struct gk20a *g,
950 return err ? err : msg.ret; 974 return err ? err : msg.ret;
951} 975}
952 976
977static int vgpu_gr_update_smpc_ctxsw_mode(struct gk20a *g,
978 struct channel_gk20a *ch, bool enable)
979{
980 struct gk20a_platform *platform = gk20a_get_platform(g->dev);
981 struct tegra_vgpu_cmd_msg msg;
982 struct tegra_vgpu_channel_set_ctxsw_mode *p = &msg.params.set_ctxsw_mode;
983 int err;
984
985 gk20a_dbg_fn("");
986
987 msg.cmd = TEGRA_VGPU_CMD_CHANNEL_SET_SMPC_CTXSW_MODE;
988 msg.handle = platform->virt_handle;
989 p->handle = ch->virt_ctx;
990
991 if (enable)
992 p->mode = TEGRA_VGPU_CTXSW_MODE_CTXSW;
993 else
994 p->mode = TEGRA_VGPU_CTXSW_MODE_NO_CTXSW;
995
996 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
997 WARN_ON(err || msg.ret);
998
999 return err ? err : msg.ret;
1000}
1001
1002static int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g,
1003 struct channel_gk20a *ch, bool enable)
1004{
1005 struct gk20a_platform *platform = gk20a_get_platform(g->dev);
1006 struct tegra_vgpu_cmd_msg msg;
1007 struct tegra_vgpu_channel_set_ctxsw_mode *p = &msg.params.set_ctxsw_mode;
1008 int err;
1009
1010 gk20a_dbg_fn("");
1011
1012 msg.cmd = TEGRA_VGPU_CMD_CHANNEL_SET_HWPM_CTXSW_MODE;
1013 msg.handle = platform->virt_handle;
1014 p->handle = ch->virt_ctx;
1015
1016 /* If we just enabled HWPM context switching, flag this
1017 * so we know we need to free the buffer when channel contexts
1018 * are cleaned up.
1019 */
1020 if (enable) {
1021 struct channel_ctx_gk20a *ch_ctx = &ch->ch_ctx;
1022 ch_ctx->pm_ctx.ctx_was_enabled = true;
1023
1024 p->mode = TEGRA_VGPU_CTXSW_MODE_CTXSW;
1025 } else
1026 p->mode = TEGRA_VGPU_CTXSW_MODE_NO_CTXSW;
1027
1028 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
1029 WARN_ON(err || msg.ret);
1030
1031 return err ? err : msg.ret;
1032}
1033
953void vgpu_init_gr_ops(struct gpu_ops *gops) 1034void vgpu_init_gr_ops(struct gpu_ops *gops)
954{ 1035{
955 gops->gr.free_channel_ctx = vgpu_gr_free_channel_ctx; 1036 gops->gr.free_channel_ctx = vgpu_gr_free_channel_ctx;
@@ -969,4 +1050,6 @@ void vgpu_init_gr_ops(struct gpu_ops *gops)
969 gops->gr.zbc_query_table = vgpu_gr_query_zbc; 1050 gops->gr.zbc_query_table = vgpu_gr_query_zbc;
970 gops->gr.init_ctx_state = vgpu_gr_init_ctx_state; 1051 gops->gr.init_ctx_state = vgpu_gr_init_ctx_state;
971 gops->gr.set_sm_debug_mode = vgpu_gr_set_sm_debug_mode; 1052 gops->gr.set_sm_debug_mode = vgpu_gr_set_sm_debug_mode;
1053 gops->gr.update_smpc_ctxsw_mode = vgpu_gr_update_smpc_ctxsw_mode;
1054 gops->gr.update_hwpm_ctxsw_mode = vgpu_gr_update_hwpm_ctxsw_mode;
972} 1055}
diff --git a/include/linux/tegra_vgpu.h b/include/linux/tegra_vgpu.h
index c4dd81dd..979d454e 100644
--- a/include/linux/tegra_vgpu.h
+++ b/include/linux/tegra_vgpu.h
@@ -76,7 +76,14 @@ enum {
76 TEGRA_VGPU_CMD_REG_OPS, 76 TEGRA_VGPU_CMD_REG_OPS,
77 TEGRA_VGPU_CMD_CHANNEL_SET_PRIORITY, 77 TEGRA_VGPU_CMD_CHANNEL_SET_PRIORITY,
78 TEGRA_VGPU_CMD_CHANNEL_SET_RUNLIST_INTERLEAVE, 78 TEGRA_VGPU_CMD_CHANNEL_SET_RUNLIST_INTERLEAVE,
79 TEGRA_VGPU_CMD_CHANNEL_SET_TIMESLICE 79 TEGRA_VGPU_CMD_CHANNEL_SET_TIMESLICE,
80 RESVD1,
81 RESVD2,
82 RESVD3,
83 RESVD4,
84 TEGRA_VGPU_CMD_CHANNEL_SET_SMPC_CTXSW_MODE,
85 TEGRA_VGPU_CMD_CHANNEL_SET_HWPM_CTXSW_MODE,
86 TEGRA_VGPU_CMD_CHANNEL_FREE_HWPM_CTX,
80}; 87};
81 88
82struct tegra_vgpu_connect_params { 89struct tegra_vgpu_connect_params {
@@ -312,6 +319,20 @@ struct tegra_vgpu_channel_timeslice_params {
312 u32 timeslice_us; 319 u32 timeslice_us;
313}; 320};
314 321
322enum {
323 TEGRA_VGPU_CTXSW_MODE_NO_CTXSW = 0,
324 TEGRA_VGPU_CTXSW_MODE_CTXSW,
325};
326
327struct tegra_vgpu_channel_set_ctxsw_mode {
328 u64 handle;
329 u32 mode;
330};
331
332struct tegra_vgpu_channel_free_hwpm_ctx {
333 u64 handle;
334};
335
315struct tegra_vgpu_cmd_msg { 336struct tegra_vgpu_cmd_msg {
316 u32 cmd; 337 u32 cmd;
317 int ret; 338 int ret;
@@ -342,6 +363,8 @@ struct tegra_vgpu_cmd_msg {
342 struct tegra_vgpu_channel_priority_params channel_priority; 363 struct tegra_vgpu_channel_priority_params channel_priority;
343 struct tegra_vgpu_channel_runlist_interleave_params channel_interleave; 364 struct tegra_vgpu_channel_runlist_interleave_params channel_interleave;
344 struct tegra_vgpu_channel_timeslice_params channel_timeslice; 365 struct tegra_vgpu_channel_timeslice_params channel_timeslice;
366 struct tegra_vgpu_channel_set_ctxsw_mode set_ctxsw_mode;
367 struct tegra_vgpu_channel_free_hwpm_ctx free_hwpm_ctx;
345 char padding[192]; 368 char padding[192];
346 } params; 369 } params;
347}; 370};