diff --git a/drivers/gpu/nvgpu/common/gr/obj_ctx.c b/drivers/gpu/nvgpu/common/gr/obj_ctx.c index a30a0406c..61f093d71 100644 --- a/drivers/gpu/nvgpu/common/gr/obj_ctx.c +++ b/drivers/gpu/nvgpu/common/gr/obj_ctx.c @@ -24,8 +24,9 @@ #include #include #include -#ifdef CONFIG_NVGPU_LS_PMU +#ifdef CONFIG_NVGPU_POWER_PG #include +#include #endif #include #include @@ -792,13 +793,25 @@ int nvgpu_gr_obj_ctx_alloc(struct gk20a *g, nvgpu_gr_obj_ctx_commit_inst(g, inst_block, gr_ctx, subctx, nvgpu_gr_ctx_get_ctx_mem(gr_ctx)->gpu_va); - /* init golden image, ELPG enabled after this is done */ + /* init golden image */ err = nvgpu_gr_obj_ctx_alloc_golden_ctx_image(g, golden_image, global_ctx_buffer, config, gr_ctx, inst_block); if (err != 0) { nvgpu_err(g, "fail to init golden ctx image"); goto out; } +#ifdef CONFIG_NVGPU_POWER_PG + /* Re-enable ELPG now that golden image has been initialized. + * The PMU PG init code may already have tried to enable elpg, but + * would not have been able to complete this action since the golden + * image hadn't been initialized yet, so do this now. + */ + err = nvgpu_pmu_reenable_elpg(g); + if (err != 0) { + nvgpu_err(g, "fail to re-enable elpg"); + goto out; + } +#endif /* load golden image */ err = nvgpu_gr_ctx_load_golden_ctx_image(g, gr_ctx, diff --git a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c index 526e17cb5..815edcb5b 100644 --- a/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c +++ b/drivers/gpu/nvgpu/common/pmu/pg/pmu_pg.c @@ -468,6 +468,36 @@ exit_unlock: return ret; } +int nvgpu_pmu_reenable_elpg(struct gk20a *g) +{ + struct nvgpu_pmu *pmu = g->pmu; + int ret = 0; + + nvgpu_log_fn(g, " "); + + if (!is_pg_supported(g, pmu->pg)) { + return ret; + } + + /* If pmu enabled, re-enable by first disabling, then + * enabling. + */ + if (pmu->pg->elpg_refcnt != 0) { + ret = nvgpu_pmu_disable_elpg(g); + if (ret != 0) { + nvgpu_err(g, "failed disabling elpg"); + goto exit; + } + ret = nvgpu_pmu_enable_elpg(g); + if (ret != 0) { + nvgpu_err(g, "failed enabling elpg"); + goto exit; + } + } +exit: + return ret; +} + /* PG init */ static void pmu_handle_pg_stat_msg(struct gk20a *g, struct pmu_msg *msg, void *param, u32 status) diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h index fcf00ef7d..1249d376c 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmu_pg.h @@ -123,6 +123,7 @@ void nvgpu_pmu_pg_destroy(struct gk20a *g, struct nvgpu_pmu *pmu, struct nvgpu_pmu_pg *pg); /* PG enable/disable */ +int nvgpu_pmu_reenable_elpg(struct gk20a *g); int nvgpu_pmu_enable_elpg(struct gk20a *g); int nvgpu_pmu_disable_elpg(struct gk20a *g); int nvgpu_pmu_pg_global_enable(struct gk20a *g, bool enable_pg);