From 201b5c1c7f95a357ea0b883d8acb68f2ba619b99 Mon Sep 17 00:00:00 2001 From: Divya Date: Wed, 9 Mar 2022 09:32:04 +0000 Subject: [PATCH] gpu: nvgpu: add SLCG support for GSP and CTRL unit Add SLCG register programming for GSP and CTRL units Bug 3452217 Change-Id: I69e414a82b5c12f26ff3b6626c328b5c0aa9e04c Signed-off-by: Divya Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2678782 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/common/init/nvgpu_init.c | 10 +++++ .../gpu/nvgpu/common/power_features/cg/cg.c | 38 +++++++++++++++++++ drivers/gpu/nvgpu/hal/gsp/gsp_ga10b.c | 4 ++ drivers/gpu/nvgpu/hal/init/hal_ga10b.c | 2 + drivers/gpu/nvgpu/include/nvgpu/gops/cg.h | 6 ++- .../nvgpu/include/nvgpu/power_features/cg.h | 37 ++++++++++++++++++ 6 files changed, 96 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/nvgpu/common/init/nvgpu_init.c b/drivers/gpu/nvgpu/common/init/nvgpu_init.c index 22d45c1c0..7c9692332 100644 --- a/drivers/gpu/nvgpu/common/init/nvgpu_init.c +++ b/drivers/gpu/nvgpu/common/init/nvgpu_init.c @@ -660,6 +660,13 @@ static int nvgpu_init_cg_ltc_load_gating_prod(struct gk20a *g) return 0; } +static int nvgpu_init_cg_ctrl_load_gating_prod(struct gk20a *g) +{ + nvgpu_cg_slcg_ctrl_load_enable(g, true); + + return 0; +} + static int nvgpu_ipa_pa_rwsem_init(struct gk20a *g) { nvgpu_rwsem_init(&(g->ipa_pa_cache.ipa_pa_rw_lock)); @@ -910,6 +917,9 @@ int nvgpu_finalize_poweron(struct gk20a *g) */ NVGPU_INIT_TABLE_ENTRY(&nvgpu_init_cg_ltc_load_gating_prod, NO_FLAG), + /* Load SLCG for CTRL unit */ + NVGPU_INIT_TABLE_ENTRY(&nvgpu_init_cg_ctrl_load_gating_prod, + NO_FLAG), #ifdef CONFIG_NVGPU_DGPU NVGPU_INIT_TABLE_ENTRY(g->ops.sec2.init_sec2_support, NVGPU_SUPPORT_SEC2_RTOS), diff --git a/drivers/gpu/nvgpu/common/power_features/cg/cg.c b/drivers/gpu/nvgpu/common/power_features/cg/cg.c index e08c431d7..ff376c834 100644 --- a/drivers/gpu/nvgpu/common/power_features/cg/cg.c +++ b/drivers/gpu/nvgpu/common/power_features/cg/cg.c @@ -343,6 +343,38 @@ done: } #endif +void nvgpu_cg_slcg_gsp_load_enable(struct gk20a *g, bool enable) +{ + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&g->cg_pg_lock); + if (!g->slcg_enabled) { + goto done; + } + + if (g->ops.cg.slcg_gsp_load_gating_prod != NULL) { + g->ops.cg.slcg_gsp_load_gating_prod(g, enable); + } +done: + nvgpu_mutex_release(&g->cg_pg_lock); +} + +void nvgpu_cg_slcg_ctrl_load_enable(struct gk20a *g, bool enable) +{ + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&g->cg_pg_lock); + if (!g->slcg_enabled) { + goto done; + } + + if (g->ops.cg.slcg_ctrl_load_gating_prod != NULL) { + g->ops.cg.slcg_ctrl_load_gating_prod(g, enable); + } +done: + nvgpu_mutex_release(&g->cg_pg_lock); +} + static void cg_init_gr_slcg_load_gating_prod(struct gk20a *g) { if (g->ops.cg.slcg_bus_load_gating_prod != NULL) { @@ -656,6 +688,12 @@ void nvgpu_cg_slcg_set_slcg_enabled(struct gk20a *g, bool enable) if (g->ops.cg.slcg_hshub_load_gating_prod != NULL) { g->ops.cg.slcg_hshub_load_gating_prod(g, enable); } + if (g->ops.cg.slcg_ctrl_load_gating_prod != NULL) { + g->ops.cg.slcg_ctrl_load_gating_prod(g, enable); + } + if (g->ops.cg.slcg_gsp_load_gating_prod != NULL) { + g->ops.cg.slcg_gsp_load_gating_prod(g, enable); + } done: nvgpu_mutex_release(&g->cg_pg_lock); diff --git a/drivers/gpu/nvgpu/hal/gsp/gsp_ga10b.c b/drivers/gpu/nvgpu/hal/gsp/gsp_ga10b.c index 7f2229db6..0d89c5061 100644 --- a/drivers/gpu/nvgpu/hal/gsp/gsp_ga10b.c +++ b/drivers/gpu/nvgpu/hal/gsp/gsp_ga10b.c @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef CONFIG_NVGPU_GSP_SCHEDULER #include #include @@ -57,6 +58,9 @@ int ga10b_gsp_engine_reset(struct gk20a *g) gk20a_writel(g, pgsp_falcon_engine_r(), pgsp_falcon_engine_reset_false_f()); + /* Load SLCG prod values for GSP */ + nvgpu_cg_slcg_gsp_load_enable(g, true); + return 0; } diff --git a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c index 02c8575c7..394ed6fb0 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c @@ -983,6 +983,8 @@ static const struct gops_cg ga10b_ops_cg = { .slcg_xbar_load_gating_prod = ga10b_slcg_xbar_load_gating_prod, .slcg_hshub_load_gating_prod = ga10b_slcg_hshub_load_gating_prod, .slcg_timer_load_gating_prod = ga10b_slcg_timer_load_gating_prod, + .slcg_ctrl_load_gating_prod = ga10b_slcg_ctrl_load_gating_prod, + .slcg_gsp_load_gating_prod = ga10b_slcg_gsp_load_gating_prod, .blcg_bus_load_gating_prod = ga10b_blcg_bus_load_gating_prod, .blcg_ce_load_gating_prod = ga10b_blcg_ce_load_gating_prod, .blcg_fb_load_gating_prod = ga10b_blcg_fb_load_gating_prod, diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/cg.h b/drivers/gpu/nvgpu/include/nvgpu/gops/cg.h index 1b9d857ce..60c9001ed 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/cg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/cg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -74,6 +74,10 @@ struct gops_cg { void (*slcg_timer_load_gating_prod)(struct gk20a *g, bool prod); + void (*slcg_ctrl_load_gating_prod)(struct gk20a *g, bool prod); + + void (*slcg_gsp_load_gating_prod)(struct gk20a *g, bool prod); + void (*elcg_ce_load_gating_prod)(struct gk20a *g, bool prod); /** @endcond DOXYGEN_SHOULD_SKIP_THIS */ }; diff --git a/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h b/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h index 19b133867..f8a7f750c 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h @@ -515,6 +515,43 @@ void nvgpu_cg_slcg_ce2_load_enable(struct gk20a *g); */ void nvgpu_cg_elcg_ce_load_enable(struct gk20a *g); +/** + * @brief During nvgpu power-on, as part of GSP initialization, + * this function is called to load register configuration + * for SLCG for GSP. + * + * @param g [in] The GPU driver struct. + * + * Checks the platform software capability slcg_enabled and programs registers + * for configuring production gating values for SLCG for GSP. This is called + * in #nvgpu_gsp_sched_bootstrap_ns. + * + * Steps: + * - Acquire the mutex #cg_pg_lock. + * - Check if #slcg_enabled is set, else skip SLCG programming. + * - Load SLCG prod settings for GSP. + * - Release the mutex #cg_pg_lock. + */ +void nvgpu_cg_slcg_gsp_load_enable(struct gk20a *g, bool enable); + +/** + * @brief During nvgpu power-on, as part of GSP initialization, + * this function is called to load register configuration + * for SLCG for CTRL unit. + * + * @param g [in] The GPU driver struct. + * + * Checks the platform software capability slcg_enabled and programs registers + * for configuring production gating values for SLCG for CTRL. + * + * Steps: + * - Acquire the mutex #cg_pg_lock. + * - Check if #slcg_enabled is set, else skip SLCG programming. + * - Load SLCG prod settings for CTRL. + * - Release the mutex #cg_pg_lock. + */ +void nvgpu_cg_slcg_ctrl_load_enable(struct gk20a *g, bool enable); + #ifdef CONFIG_NVGPU_NON_FUSA void nvgpu_cg_elcg_enable(struct gk20a *g);