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/gk20a/dbg_gpu_gk20a.h | 9 +++++++ drivers/gpu/nvgpu/gk20a/gk20a.h | 3 ++- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 46 +++++++++++++++++++++++++-------- drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 2 +- 4 files changed, 47 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a') diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h index d9d07844..50002557 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h @@ -135,4 +135,13 @@ int gk20a_perfbuf_disable_locked(struct gk20a *g); void nvgpu_dbg_session_post_event(struct dbg_session_gk20a *dbg_s); u32 nvgpu_set_powergate_locked(struct dbg_session_gk20a *dbg_s, bool mode); + + /* PM Context Switch Mode */ +/*This mode says that the pms are not to be context switched. */ +#define NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW (0x00000000) +/* This mode says that the pms in Mode-B are to be context switched */ +#define NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW (0x00000001) +/* This mode says that the pms in Mode-E (stream out) are to be context switched. */ +#define NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW (0x00000002) + #endif /* DBG_GPU_GK20A_H */ diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 23ed2f15..ce0a6563 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -307,10 +307,11 @@ struct gpu_ops { int (*update_smpc_ctxsw_mode)(struct gk20a *g, struct channel_gk20a *c, bool enable); + u32 (*get_hw_accessor_stream_out_mode)(void); int (*update_hwpm_ctxsw_mode)(struct gk20a *g, struct channel_gk20a *c, u64 gpu_va, - bool enable); + u32 mode); int (*dump_gr_regs)(struct gk20a *g, struct gk20a_debug_output *o); 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 7a65f353..3f49fbf7 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -1684,14 +1684,14 @@ out: int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, struct channel_gk20a *c, u64 gpu_va, - bool enable_hwpm_ctxsw) + u32 mode) { struct tsg_gk20a *tsg; struct nvgpu_mem *gr_mem = NULL; struct nvgpu_gr_ctx *gr_ctx; struct pm_ctx_desc *pm_ctx; u32 data; - u64 virt_addr; + u64 virt_addr = 0; struct ctx_header_desc *ctx = &c->ctx_header; struct nvgpu_mem *ctxheader = &ctx->mem; int ret; @@ -1710,12 +1710,31 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, return -EFAULT; } - if (enable_hwpm_ctxsw) { - if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_ctxsw_f()) + if ((mode == NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW) && + (!g->ops.gr.get_hw_accessor_stream_out_mode)) { + nvgpu_err(g, "Mode-E hwpm context switch mode is not supported"); + return -EINVAL; + } + + switch (mode) { + case NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW: + if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_ctxsw_f()) { return 0; - } else { - if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_no_ctxsw_f()) + } + break; + case NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW: + if (pm_ctx->pm_mode == ctxsw_prog_main_image_pm_mode_no_ctxsw_f()) { + return 0; + } + break; + case NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW: + if (pm_ctx->pm_mode == g->ops.gr.get_hw_accessor_stream_out_mode()) { return 0; + } + break; + default: + nvgpu_err(g, "invalid hwpm context switch mode"); + return -EINVAL; } ret = gk20a_disable_channel_tsg(g, c); @@ -1735,7 +1754,7 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, Flush and invalidate before cpu update. */ g->ops.mm.l2_flush(g, true); - if (enable_hwpm_ctxsw) { + if (mode != NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW) { /* Allocate buffer if necessary */ if (pm_ctx->mem.gpu_va == 0) { ret = nvgpu_dma_alloc_sys(g, @@ -1768,11 +1787,16 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, data = nvgpu_mem_rd(g, gr_mem, ctxsw_prog_main_image_pm_o()); data = data & ~ctxsw_prog_main_image_pm_mode_m(); - if (enable_hwpm_ctxsw) { + switch (mode) { + case NVGPU_DBG_HWPM_CTXSW_MODE_CTXSW: pm_ctx->pm_mode = ctxsw_prog_main_image_pm_mode_ctxsw_f(); - virt_addr = pm_ctx->mem.gpu_va; - } else { + break; + case NVGPU_DBG_HWPM_CTXSW_MODE_STREAM_OUT_CTXSW: + pm_ctx->pm_mode = g->ops.gr.get_hw_accessor_stream_out_mode(); + virt_addr = pm_ctx->mem.gpu_va; + break; + case NVGPU_DBG_HWPM_CTXSW_MODE_NO_CTXSW: pm_ctx->pm_mode = ctxsw_prog_main_image_pm_mode_no_ctxsw_f(); virt_addr = 0; } @@ -1892,7 +1916,7 @@ int gr_gk20a_load_golden_ctx_image(struct gk20a *g, * for PM context switching, including mode and possibly a pointer to * the PM backing store. */ - if (gr_ctx->pm_ctx.pm_mode == ctxsw_prog_main_image_pm_mode_ctxsw_f()) { + if (gr_ctx->pm_ctx.pm_mode != ctxsw_prog_main_image_pm_mode_no_ctxsw_f()) { if (gr_ctx->pm_ctx.mem.gpu_va == 0) { nvgpu_err(g, "context switched pm with no pm buffer!"); diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index a77136a6..92e1dff5 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h @@ -655,7 +655,7 @@ int gr_gk20a_update_smpc_ctxsw_mode(struct gk20a *g, int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g, struct channel_gk20a *c, u64 gpu_va, - bool enable_hwpm_ctxsw); + u32 mode); struct nvgpu_gr_ctx; void gr_gk20a_ctx_patch_write(struct gk20a *g, struct nvgpu_gr_ctx *ch_ctx, -- cgit v1.2.2