From cae5d380d8b465f4d1389ae80d6cec1458951e29 Mon Sep 17 00:00:00 2001 From: Lakshmanan M Date: Thu, 28 Jul 2016 16:53:31 +0530 Subject: gpu: nvgpu: Add preemption mode support for gp10x Added preemption mode (WFI, GFXP, CTA and CILP) support for gp10x family gr class (PASCAL_B and PASCAL_COMPUTE_B). Bug 200221149 Change-Id: Ia8b781c5baedba660db5997f190a0b363286ed7f Signed-off-by: Lakshmanan M Reviewed-on: http://git-master/r/1193209 Reviewed-by: Deepak Nibade GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu --- drivers/gpu/nvgpu/gp106/gr_gp106.c | 118 +++++++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gp10b/gr_gp10b.c | 24 ++++++-- 2 files changed, 136 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/nvgpu/gp106/gr_gp106.c b/drivers/gpu/nvgpu/gp106/gr_gp106.c index 9d6ce6ec..01d06975 100644 --- a/drivers/gpu/nvgpu/gp106/gr_gp106.c +++ b/drivers/gpu/nvgpu/gp106/gr_gp106.c @@ -102,6 +102,123 @@ static void gr_gp106_cb_size_default(struct gk20a *g) gr_gpc0_ppc0_cbm_alpha_cb_size_v_default_v(); } +static int gr_gp106_set_ctxsw_preemption_mode(struct gk20a *g, + struct gr_ctx_desc *gr_ctx, + struct vm_gk20a *vm, u32 class, + u32 graphics_preempt_mode, + u32 compute_preempt_mode) +{ + int err = 0; + + if (class == PASCAL_B && g->gr.t18x.ctx_vars.force_preemption_gfxp) + graphics_preempt_mode = NVGPU_GRAPHICS_PREEMPTION_MODE_GFXP; + + if (class == PASCAL_COMPUTE_B && + g->gr.t18x.ctx_vars.force_preemption_cilp) + compute_preempt_mode = NVGPU_COMPUTE_PREEMPTION_MODE_CILP; + + /* check for invalid combinations */ + if ((graphics_preempt_mode == 0) && (compute_preempt_mode == 0)) + return -EINVAL; + + if ((graphics_preempt_mode == NVGPU_GRAPHICS_PREEMPTION_MODE_GFXP) && + (compute_preempt_mode == NVGPU_COMPUTE_PREEMPTION_MODE_CILP)) + return -EINVAL; + + /* set preemption modes */ + switch (graphics_preempt_mode) { + case NVGPU_GRAPHICS_PREEMPTION_MODE_GFXP: + { + u32 spill_size = + gr_gpc0_swdx_rm_spill_buffer_size_256b_default_v() * + gr_gpc0_swdx_rm_spill_buffer_size_256b_byte_granularity_v(); + u32 pagepool_size = g->ops.gr.pagepool_default_size(g) * + gr_scc_pagepool_total_pages_byte_granularity_v(); + u32 betacb_size = g->gr.attrib_cb_default_size + + (gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v() - + gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v()); + u32 attrib_cb_size = (betacb_size + g->gr.alpha_cb_size) * + gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v() * + g->gr.max_tpc_count; + attrib_cb_size = ALIGN(attrib_cb_size, 128); + + gk20a_dbg_info("gfxp context spill_size=%d", spill_size); + gk20a_dbg_info("gfxp context pagepool_size=%d", pagepool_size); + gk20a_dbg_info("gfxp context attrib_cb_size=%d", + attrib_cb_size); + + err = gr_gp10b_alloc_buffer(vm, + g->gr.t18x.ctx_vars.preempt_image_size, + &gr_ctx->t18x.preempt_ctxsw_buffer); + if (err) { + gk20a_err(dev_from_gk20a(g), + "cannot allocate preempt buffer"); + goto fail; + } + + err = gr_gp10b_alloc_buffer(vm, + spill_size, + &gr_ctx->t18x.spill_ctxsw_buffer); + if (err) { + gk20a_err(dev_from_gk20a(g), + "cannot allocate spill buffer"); + goto fail_free_preempt; + } + + err = gr_gp10b_alloc_buffer(vm, + attrib_cb_size, + &gr_ctx->t18x.betacb_ctxsw_buffer); + if (err) { + gk20a_err(dev_from_gk20a(g), + "cannot allocate beta buffer"); + goto fail_free_spill; + } + + err = gr_gp10b_alloc_buffer(vm, + pagepool_size, + &gr_ctx->t18x.pagepool_ctxsw_buffer); + if (err) { + gk20a_err(dev_from_gk20a(g), + "cannot allocate page pool"); + goto fail_free_betacb; + } + + gr_ctx->graphics_preempt_mode = graphics_preempt_mode; + break; + } + + case NVGPU_GRAPHICS_PREEMPTION_MODE_WFI: + gr_ctx->graphics_preempt_mode = graphics_preempt_mode; + break; + + default: + break; + } + + if (class == PASCAL_COMPUTE_B) { + switch (compute_preempt_mode) { + case NVGPU_COMPUTE_PREEMPTION_MODE_WFI: + case NVGPU_COMPUTE_PREEMPTION_MODE_CTA: + case NVGPU_COMPUTE_PREEMPTION_MODE_CILP: + gr_ctx->compute_preempt_mode = compute_preempt_mode; + break; + default: + break; + } + } + + return 0; + +fail_free_betacb: + gk20a_gmmu_unmap_free(vm, &gr_ctx->t18x.betacb_ctxsw_buffer); +fail_free_spill: + gk20a_gmmu_unmap_free(vm, &gr_ctx->t18x.spill_ctxsw_buffer); +fail_free_preempt: + gk20a_gmmu_unmap_free(vm, &gr_ctx->t18x.preempt_ctxsw_buffer); +fail: + return err; +} + void gp106_init_gr(struct gpu_ops *gops) { gp10b_init_gr(gops); @@ -110,4 +227,5 @@ void gp106_init_gr(struct gpu_ops *gops) gops->gr.handle_sw_method = gr_gp106_handle_sw_method; gops->gr.cb_size_default = gr_gp106_cb_size_default; gops->gr.init_preemption_state = NULL; + gops->gr.set_ctxsw_preemption_mode = gr_gp106_set_ctxsw_preemption_mode; } diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c index 374242bf..ee73fed1 100644 --- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c @@ -992,9 +992,15 @@ static int gr_gp10b_alloc_gr_ctx(struct gk20a *g, compute_preempt_mode = NVGPU_COMPUTE_PREEMPTION_MODE_CILP; if (graphics_preempt_mode || compute_preempt_mode) { - err = gr_gp10b_set_ctxsw_preemption_mode(g, *gr_ctx, vm, + if (g->ops.gr.set_ctxsw_preemption_mode) { + err = g->ops.gr.set_ctxsw_preemption_mode(g, *gr_ctx, vm, class, graphics_preempt_mode, compute_preempt_mode); - if (err) + if (err) { + gk20a_err(dev_from_gk20a(g), + "set_ctxsw_preemption_mode failed"); + goto fail_free_gk20a_ctx; + } + } else goto fail_free_gk20a_ctx; } @@ -2067,10 +2073,15 @@ static int gr_gp10b_set_preemption_mode(struct channel_gk20a *ch, vm = ch->vm; } - err = gr_gp10b_set_ctxsw_preemption_mode(g, gr_ctx, vm, class, - graphics_preempt_mode, compute_preempt_mode); - if (err) - return err; + if (g->ops.gr.set_ctxsw_preemption_mode) { + err = g->ops.gr.set_ctxsw_preemption_mode(g, gr_ctx, vm, class, + graphics_preempt_mode, compute_preempt_mode); + if (err) { + gk20a_err(dev_from_gk20a(g), + "set_ctxsw_preemption_mode failed"); + return err; + } + } if (gk20a_mem_begin(g, mem)) return -ENOMEM; @@ -2225,6 +2236,7 @@ void gp10b_init_gr(struct gpu_ops *gops) gops->gr.get_lrf_tex_ltc_dram_override = get_ecc_override_val; gops->gr.suspend_contexts = gr_gp10b_suspend_contexts; gops->gr.set_preemption_mode = gr_gp10b_set_preemption_mode; + gops->gr.set_ctxsw_preemption_mode = gr_gp10b_set_ctxsw_preemption_mode; gops->gr.get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags; gops->gr.fuse_override = gp10b_gr_fuse_override; gops->gr.load_smid_config = gr_gp10b_load_smid_config; -- cgit v1.2.2