From 4d8ad643d67ac4044f76976c4085a35fcc5d4095 Mon Sep 17 00:00:00 2001 From: Debarshi Dutta Date: Fri, 3 May 2019 14:11:52 +0530 Subject: gpu: nvgpu: wait for gr.initialized before changing cg/pg set gr.initialized to false in the beginning of gk20a_gr_reset() and set it to true at the end of successful execution of gk20a_gr_reset. Use gk20a_gr_wait_initialized() to enable/disable cg/pg functions to make sure engine is out of reset and initialized. Bug 2092051 Bug 2429295 Bug 2484211 Bug 1890287 Change-Id: Ic7b0b71382c6d852a625c603dad8609c43b7f20f Signed-off-by: Seema Khowala Signed-off-by: Debarshi Dutta (cherry-picked from 7e2f124fd12caf37172f12da8de65093622941a5 in dev-kernel) Reviewed-on: https://git-master.nvidia.com/r/2111038 GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/power_features/cg/cg.c | 50 ++++++++++++++++++++++ drivers/gpu/nvgpu/common/power_features/pg/pg.c | 6 +++ .../nvgpu/common/power_features/power_features.c | 4 ++ drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 14 ++++-- .../gpu/nvgpu/include/nvgpu/power_features/cg.h | 2 + 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/nvgpu/common/power_features/cg/cg.c b/drivers/gpu/nvgpu/common/power_features/cg/cg.c index 66b95226..a538c44b 100644 --- a/drivers/gpu/nvgpu/common/power_features/cg/cg.c +++ b/drivers/gpu/nvgpu/common/power_features/cg/cg.c @@ -54,6 +54,36 @@ static void nvgpu_cg_set_mode(struct gk20a *g, int cgmode, int mode_config) } } +void nvgpu_cg_elcg_enable_no_wait(struct gk20a *g) +{ + nvgpu_log_fn(g, " "); + + if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_ELCG)) { + return; + } + + nvgpu_mutex_acquire(&g->cg_pg_lock); + if (g->elcg_enabled) { + nvgpu_cg_set_mode(g, ELCG_MODE, ELCG_AUTO); + } + nvgpu_mutex_release(&g->cg_pg_lock); +} + +void nvgpu_cg_elcg_disable_no_wait(struct gk20a *g) +{ + nvgpu_log_fn(g, " "); + + if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_ELCG)) { + return; + } + + nvgpu_mutex_acquire(&g->cg_pg_lock); + if (g->elcg_enabled) { + nvgpu_cg_set_mode(g, ELCG_MODE, ELCG_RUN); + } + nvgpu_mutex_release(&g->cg_pg_lock); +} + void nvgpu_cg_elcg_enable(struct gk20a *g) { nvgpu_log_fn(g, " "); @@ -62,6 +92,8 @@ void nvgpu_cg_elcg_enable(struct gk20a *g) return; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (g->elcg_enabled) { nvgpu_cg_set_mode(g, ELCG_MODE, ELCG_AUTO); @@ -77,6 +109,8 @@ void nvgpu_cg_elcg_disable(struct gk20a *g) return; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (g->elcg_enabled) { nvgpu_cg_set_mode(g, ELCG_MODE, ELCG_RUN); @@ -93,6 +127,8 @@ void nvgpu_cg_blcg_mode_enable(struct gk20a *g) return; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (g->blcg_enabled) { nvgpu_cg_set_mode(g, BLCG_MODE, BLCG_AUTO); @@ -109,6 +145,8 @@ void nvgpu_cg_blcg_mode_disable(struct gk20a *g) return; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (g->blcg_enabled) { nvgpu_cg_set_mode(g, BLCG_MODE, BLCG_RUN); @@ -257,6 +295,9 @@ void nvgpu_cg_slcg_gr_perf_ltc_load_enable(struct gk20a *g) if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG)) { return; } + + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (!g->slcg_enabled) { goto done; @@ -281,6 +322,9 @@ void nvgpu_cg_slcg_gr_perf_ltc_load_disable(struct gk20a *g) if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG)) { return; } + + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (!g->slcg_enabled) { goto done; @@ -421,6 +465,8 @@ void nvgpu_cg_elcg_set_elcg_enabled(struct gk20a *g, bool enable) return; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_release(&g->cg_pg_lock); if (enable) { if (!g->elcg_enabled) { @@ -446,6 +492,8 @@ void nvgpu_cg_blcg_set_blcg_enabled(struct gk20a *g, bool enable) return; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (enable) { if (!g->blcg_enabled) { @@ -505,6 +553,8 @@ void nvgpu_cg_slcg_set_slcg_enabled(struct gk20a *g, bool enable) return; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (enable) { if (!g->slcg_enabled) { diff --git a/drivers/gpu/nvgpu/common/power_features/pg/pg.c b/drivers/gpu/nvgpu/common/power_features/pg/pg.c index fa31f4e3..394c0824 100644 --- a/drivers/gpu/nvgpu/common/power_features/pg/pg.c +++ b/drivers/gpu/nvgpu/common/power_features/pg/pg.c @@ -46,6 +46,8 @@ int nvgpu_pg_elpg_enable(struct gk20a *g) return 0; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (g->elpg_enabled) { err = nvgpu_pmu_pg_global_enable(g, true); @@ -64,6 +66,8 @@ int nvgpu_pg_elpg_disable(struct gk20a *g) return 0; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (g->elpg_enabled) { err = nvgpu_pmu_pg_global_enable(g, false); @@ -83,6 +87,8 @@ int nvgpu_pg_elpg_set_elpg_enabled(struct gk20a *g, bool enable) return 0; } + gk20a_gr_wait_initialized(g); + nvgpu_mutex_acquire(&g->cg_pg_lock); if (enable) { if (!g->elpg_enabled) { diff --git a/drivers/gpu/nvgpu/common/power_features/power_features.c b/drivers/gpu/nvgpu/common/power_features/power_features.c index 792fdc01..7f52ba8e 100644 --- a/drivers/gpu/nvgpu/common/power_features/power_features.c +++ b/drivers/gpu/nvgpu/common/power_features/power_features.c @@ -31,6 +31,8 @@ int nvgpu_cg_pg_disable(struct gk20a *g) nvgpu_log_fn(g, " "); + gk20a_gr_wait_initialized(g); + /* disable elpg before clock gating */ err = nvgpu_pg_elpg_disable(g); if (err != 0) { @@ -51,6 +53,8 @@ int nvgpu_cg_pg_enable(struct gk20a *g) nvgpu_log_fn(g, " "); + gk20a_gr_wait_initialized(g); + nvgpu_cg_elcg_enable(g); nvgpu_cg_blcg_mode_enable(g); diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 788ebf45..4f8006b2 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -4679,7 +4679,7 @@ static int gk20a_init_gr_prepare(struct gk20a *g) nvgpu_cg_init_gr_load_gating_prod(g); /* Disable elcg until it gets enabled later in the init*/ - nvgpu_cg_elcg_disable(g); + nvgpu_cg_elcg_disable_no_wait(g); /* enable fifo access */ gk20a_writel(g, gr_gpfifo_ctl_r(), @@ -4963,6 +4963,8 @@ int gk20a_init_gr_support(struct gk20a *g) nvgpu_log_fn(g, " "); + g->gr.initialized = false; + /* this is required before gr_gk20a_init_ctx_state */ err = nvgpu_mutex_init(&g->gr.fecs_mutex); if (err != 0) { @@ -4999,7 +5001,7 @@ int gk20a_init_gr_support(struct gk20a *g) } } - nvgpu_cg_elcg_enable(g); + nvgpu_cg_elcg_enable_no_wait(g); /* GR is inialized, signal possible waiters */ g->gr.initialized = true; nvgpu_cond_signal(&g->gr.init_wq); @@ -5091,6 +5093,8 @@ int gk20a_gr_reset(struct gk20a *g) int err; u32 size; + g->gr.initialized = false; + nvgpu_mutex_acquire(&g->gr.fecs_mutex); err = gk20a_enable_gr_hw(g); @@ -5143,7 +5147,11 @@ int gk20a_gr_reset(struct gk20a *g) } nvgpu_cg_init_gr_load_gating_prod(g); - nvgpu_cg_elcg_enable(g); + nvgpu_cg_elcg_enable_no_wait(g); + + /* GR is inialized, signal possible waiters */ + g->gr.initialized = true; + nvgpu_cond_signal(&g->gr.init_wq); return err; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h b/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h index 3bb86267..7b5fe265 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h @@ -32,6 +32,8 @@ struct fifo_gk20a; void nvgpu_cg_init_gr_load_gating_prod(struct gk20a *g); void nvgpu_cg_elcg_enable(struct gk20a *g); void nvgpu_cg_elcg_disable(struct gk20a *g); +void nvgpu_cg_elcg_enable_no_wait(struct gk20a *g); +void nvgpu_cg_elcg_disable_no_wait(struct gk20a *g); void nvgpu_cg_elcg_set_elcg_enabled(struct gk20a *g, bool enable); void nvgpu_cg_blcg_mode_enable(struct gk20a *g); -- cgit v1.2.2