From e14fdcd8f1f4125da697433b1744b1e4e4f15b09 Mon Sep 17 00:00:00 2001 From: Vaibhav Kachore Date: Fri, 6 Jul 2018 15:10:03 +0530 Subject: gpu: nvgpu: enable HWPM Mode-E context switch - Write new pm mode to context buffer header. Ucode use this mode to enable mode-e context switch. This is Mode-B context switch of PMs with Mode-E streamout on one context. If this mode is set, Ucode makes sure that Mode-E pipe (perfmons, routers, pma) is idle before it context switches PMs. - This allows us to collect counters in a secure way (i.e. on context basis) with stream out. Bug 2106999 Change-Id: I5a7435f09d1bf053ca428e538b0a57f3a175ac37 Signed-off-by: Vaibhav Kachore Reviewed-on: https://git-master.nvidia.com/r/1760366 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/vgpu/gr_vgpu.c | 43 ++++++++++++++++++++++++++++------------ drivers/gpu/nvgpu/vgpu/gr_vgpu.h | 2 +- 2 files changed, 31 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/nvgpu/vgpu') diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c index 83d27f17..0077c537 100644 --- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c @@ -1066,7 +1066,7 @@ int vgpu_gr_update_smpc_ctxsw_mode(struct gk20a *g, } int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, - struct channel_gk20a *ch, u64 gpu_va, bool enable) + struct channel_gk20a *ch, u64 gpu_va, u32 mode) { struct tsg_gk20a *tsg; struct nvgpu_gr_ctx *ch_ctx; @@ -1089,16 +1089,33 @@ int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, ch_ctx = &tsg->gr_ctx; pm_ctx = &ch_ctx->pm_ctx; - if (enable) { + if (mode == NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW) { /* * send command to enable HWPM only once - otherwise server * will return an error due to using the same GPU VA twice. */ - if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_ctxsw_f()) - return 0; + if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_ctxsw_f()) { + return 0; + } p->mode = TEGRA_VGPU_CTXSW_MODE_CTXSW; + } else if (mode == NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW) { + if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_no_ctxsw_f()) { + return 0; + } + p->mode = TEGRA_VGPU_CTXSW_MODE_NO_CTXSW; + } else if ((mode == NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW) && + (g->ops.gr.get_hw_accessor_stream_out_mode)){ + if (pm_ctx->pm_mode == g->ops.gr.get_hw_accessor_stream_out_mode()) { + return 0; + } + p->mode = TEGRA_VGPU_CTXSW_MODE_STREAM_OUT_CTXSW; + } else { + nvgpu_err(g, "invalid hwpm context switch mode"); + return -EINVAL; + } + if (mode != NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW) { /* Allocate buffer if necessary */ if (pm_ctx->mem.gpu_va == 0) { pm_ctx->mem.gpu_va = __nvgpu_vm_alloc_va(ch->vm, @@ -1109,11 +1126,6 @@ int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, return -ENOMEM; pm_ctx->mem.size = g->gr.ctx_vars.pm_ctxsw_image_size; } - } else { - if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_no_ctxsw_f()) - return 0; - - p->mode = TEGRA_VGPU_CTXSW_MODE_NO_CTXSW; } msg.cmd = TEGRA_VGPU_CMD_CHANNEL_SET_HWPM_CTXSW_MODE; @@ -1124,10 +1136,15 @@ int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); WARN_ON(err || msg.ret); err = err ? err : msg.ret; - if (!err) - pm_ctx->pm_mode = enable ? - ctxsw_prog_main_image_pm_mode_ctxsw_f() : - ctxsw_prog_main_image_pm_mode_no_ctxsw_f(); + if (!err) { + if (mode == NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW) { + pm_ctx->pm_mode = ctxsw_prog_main_image_pm_mode_ctxsw_f(); + } else if (mode == NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW) { + pm_ctx->pm_mode = ctxsw_prog_main_image_pm_mode_no_ctxsw_f(); + } else { + pm_ctx->pm_mode = g->ops.gr.get_hw_accessor_stream_out_mode(); + } + } return err; } diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.h b/drivers/gpu/nvgpu/vgpu/gr_vgpu.h index c4b3944e..149bd17a 100644 --- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.h +++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.h @@ -58,7 +58,7 @@ int vgpu_gr_set_sm_debug_mode(struct gk20a *g, int vgpu_gr_update_smpc_ctxsw_mode(struct gk20a *g, struct channel_gk20a *ch, bool enable); int vgpu_gr_update_hwpm_ctxsw_mode(struct gk20a *g, - struct channel_gk20a *ch, u64 gpu_va, bool enable); + struct channel_gk20a *ch, u64 gpu_va, u32 mode); int vgpu_gr_clear_sm_error_state(struct gk20a *g, struct channel_gk20a *ch, u32 sm_id); int vgpu_gr_suspend_contexts(struct gk20a *g, -- cgit v1.2.2