From 6745b0685e4822c535a79dd72fd629b506c9dd20 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Tue, 25 Aug 2020 15:29:57 +0530 Subject: [PATCH] gpu: nvgpu: support resetting each GR instance Add a new header file that supports below macros to execute various functions for GR instances 1) nvgpu_gr_exec_for_each_instance Execute a function for each GR instance by configuring GR remap window for that instance. Function being executed returns void. 2) nvgpu_gr_exec_with_ret_for_each_instance Execute a function for each GR instance by configuring GR remap window for that instance. Function being executed returns an error. 3) nvgpu_gr_exec_for_all_instances Execute a function for all GR instances at once. For this GR remap window needs to be disabled temporarily. If CONFIG_NVGPU_MIG is disabled, all above macros will turn into simple funciton calls. If CONFIG_NVGPU_MIG is disabled or if runtime flag NVGPU_SUPPORT_MIG is disabled, all above macros will turn into simple function calls that configure single GR instance. Separate out GR engine reset code into new API gr_reset_engine() and execute it with nvgpu_gr_exec_with_ret_for_each_instance(). PROD values need to be loaded in legacy mode, hence call nvgpu_cg_init_gr_load_gating_prod() inside nvgpu_gr_exec_for_all_instances(). Rename gr_init_prepare_hw() to more appropriate gr_reset_hw_and_load_prod() Moe gops.gr.init.fifo_access() call to gr_init_reset_enable_hw(). Add new API nvgpu_grmgr_get_gr_syspipe_id() to query GR instance syspipe id from common.grmgr unit. Add nvgpu_gr_get_syspipe_id() that returns same value stored in nvgpu_gr struct. Add cur_gr_instance field to struct nvgpu_gr to track current GR instance being programmed under remap window. Jira NVGPU-5648 Change-Id: I86920303427a6e6547ebf195daa37438365bb38e Signed-off-by: Deepak Nibade Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2403550 Tested-by: mobile promotions Reviewed-by: mobile promotions --- arch/nvgpu-common.yaml | 1 + drivers/gpu/nvgpu/common/gr/gr.c | 50 ++++++++-- drivers/gpu/nvgpu/common/gr/gr_priv.h | 7 +- drivers/gpu/nvgpu/common/grmgr/grmgr.c | 17 ++++ drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 1 + drivers/gpu/nvgpu/include/nvgpu/gr/gr.h | 3 + .../gpu/nvgpu/include/nvgpu/gr/gr_instances.h | 93 +++++++++++++++++++ drivers/gpu/nvgpu/include/nvgpu/grmgr.h | 1 + userspace/units/acr/nvgpu-acr.c | 12 +++ userspace/units/gr/nvgpu-gr.c | 12 +++ userspace/units/ltc/nvgpu-ltc.c | 12 +++ userspace/units/pmu/nvgpu-pmu.c | 12 +++ 12 files changed, 210 insertions(+), 11 deletions(-) create mode 100644 drivers/gpu/nvgpu/include/nvgpu/gr/gr_instances.h diff --git a/arch/nvgpu-common.yaml b/arch/nvgpu-common.yaml index 9ade1a38e..33e51dcc7 100644 --- a/arch/nvgpu-common.yaml +++ b/arch/nvgpu-common.yaml @@ -449,6 +449,7 @@ gr: sources: [ common/gr/gr.c, common/gr/gr_priv.h, common/gr/gr_utils.c, + include/nvgpu/gr/gr_instances.h, include/nvgpu/gr/gr_utils.h, include/nvgpu/gops/gr.h, include/nvgpu/gr/gr.h ] diff --git a/drivers/gpu/nvgpu/common/gr/gr.c b/drivers/gpu/nvgpu/common/gr/gr.c index a9c94f436..b5068a012 100644 --- a/drivers/gpu/nvgpu/common/gr/gr.c +++ b/drivers/gpu/nvgpu/common/gr/gr.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_NVGPU_GRAPHICS @@ -571,6 +572,9 @@ static int gr_init_reset_enable_hw(struct gk20a *g) nvgpu_log_fn(g, " "); + /* enable fifo access */ + g->ops.gr.init.fifo_access(g, true); + enable_gr_interrupts(g); /* load non_ctx init */ @@ -606,14 +610,16 @@ out: return err; } -static int gr_init_prepare_hw(struct gk20a *g) +static int gr_reset_engine(struct gk20a *g) { #if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT) + struct nvgpu_gr *gr = &g->gr[g->cur_gr_instance]; int err; if (g->ops.gr.init.reset_gpcs != NULL) { const struct nvgpu_device *dev = - nvgpu_device_get(g, NVGPU_DEVTYPE_GRAPHICS, 0); + nvgpu_device_get(g, NVGPU_DEVTYPE_GRAPHICS, + nvgpu_gr_get_syspipe_id(gr)); g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_PERFMON)); @@ -637,21 +643,31 @@ static int gr_init_prepare_hw(struct gk20a *g) } } else { #endif - /* reset gr engine */ - g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_GRAPH) | - g->ops.mc.reset_mask(g, NVGPU_UNIT_BLG) | - g->ops.mc.reset_mask(g, NVGPU_UNIT_PERFMON)); + /* reset gr engine */ + g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_GRAPH) | + g->ops.mc.reset_mask(g, NVGPU_UNIT_BLG) | + g->ops.mc.reset_mask(g, NVGPU_UNIT_PERFMON)); #if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT) } #endif - nvgpu_cg_init_gr_load_gating_prod(g); + return 0; +} + +static int gr_reset_hw_and_load_prod(struct gk20a *g) +{ + int err; + + err = nvgpu_gr_exec_with_ret_for_each_instance(g, gr_reset_engine(g)); + if (err != 0) { + return err; + } + + nvgpu_gr_exec_for_all_instances(g, nvgpu_cg_init_gr_load_gating_prod(g)); /* Disable elcg until it gets enabled later in the init*/ nvgpu_cg_elcg_disable_no_wait(g); - /* enable fifo access */ - g->ops.gr.init.fifo_access(g, true); return 0; } @@ -661,7 +677,7 @@ int nvgpu_gr_enable_hw(struct gk20a *g) nvgpu_log_fn(g, " "); - err = gr_init_prepare_hw(g); + err = gr_reset_hw_and_load_prod(g); if (err != 0) { return err; } @@ -830,9 +846,18 @@ int nvgpu_gr_alloc(struct gk20a *g) return -ENOMEM; } + g->cur_gr_instance = 0U; /* default */ + for (i = 0U; i < g->num_gr_instances; i++) { gr = &g->gr[i]; + gr->syspipe_id = nvgpu_grmgr_get_gr_syspipe_id(g, i); + if (gr->syspipe_id == U32_MAX) { + nvgpu_err(g, "failed to get syspipe id"); + err = -EINVAL; + goto fail; + } + gr->falcon = nvgpu_gr_falcon_init_support(g); if (gr->falcon == NULL) { nvgpu_err(g, "failed to init gr falcon"); @@ -896,6 +921,11 @@ void nvgpu_gr_free(struct gk20a *g) g->gr = NULL; } +u32 nvgpu_gr_get_syspipe_id(struct nvgpu_gr *gr) +{ + return gr->syspipe_id; +} + #if defined(CONFIG_NVGPU_RECOVERY) || defined(CONFIG_NVGPU_DEBUGGER) /** * Stop processing (stall) context switches at FECS:- diff --git a/drivers/gpu/nvgpu/common/gr/gr_priv.h b/drivers/gpu/nvgpu/common/gr/gr_priv.h index 0ccfb61e9..65abc93b2 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_priv.h +++ b/drivers/gpu/nvgpu/common/gr/gr_priv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2020, 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"), @@ -65,6 +65,11 @@ struct nvgpu_gr { */ bool initialized; + /** + * Syspipe ID of the GR instance. + */ + u32 syspipe_id; + /** * Pointer to global context buffer descriptor structure. */ diff --git a/drivers/gpu/nvgpu/common/grmgr/grmgr.c b/drivers/gpu/nvgpu/common/grmgr/grmgr.c index 557205abf..a1ea605a2 100644 --- a/drivers/gpu/nvgpu/common/grmgr/grmgr.c +++ b/drivers/gpu/nvgpu/common/grmgr/grmgr.c @@ -249,3 +249,20 @@ u32 nvgpu_grmgr_get_num_gr_instances(struct gk20a *g) */ return g->mig.num_gr_sys_pipes_enabled; } + +u32 nvgpu_grmgr_get_gr_syspipe_id(struct gk20a *g, u32 gr_instance_id) +{ + struct nvgpu_gpu_instance *gpu_instance; + struct nvgpu_gr_syspipe *gr_syspipe; + u32 i; + + for (i = 0U; i < g->mig.num_gpu_instances; i++) { + gpu_instance = &g->mig.gpu_instance[i]; + gr_syspipe = &gpu_instance->gr_syspipe; + if (gr_instance_id == gr_syspipe->gr_instance_id) { + return gr_syspipe->gr_syspipe_id; + } + } + + return U32_MAX; +} diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 0edd01e81..e28ca1bac 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -335,6 +335,7 @@ struct gk20a { struct nvgpu_gr *gr; u32 num_gr_instances; + u32 cur_gr_instance; struct nvgpu_fbp *fbp; #ifdef CONFIG_NVGPU_SIM diff --git a/drivers/gpu/nvgpu/include/nvgpu/gr/gr.h b/drivers/gpu/nvgpu/include/nvgpu/gr/gr.h index 3ba7cd04b..f2967dd70 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gr/gr.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gr/gr.h @@ -116,6 +116,7 @@ * */ struct gk20a; +struct nvgpu_gr; struct nvgpu_gr_config; /** @@ -310,6 +311,8 @@ u32 nvgpu_gr_sm_offset(struct gk20a *g, u32 sm); */ u32 nvgpu_gr_rop_offset(struct gk20a *g, u32 rop); +u32 nvgpu_gr_get_syspipe_id(struct nvgpu_gr *gr); + #ifdef CONFIG_NVGPU_HAL_NON_FUSA /** * @brief Wait for GR engine to be initialized diff --git a/drivers/gpu/nvgpu/include/nvgpu/gr/gr_instances.h b/drivers/gpu/nvgpu/include/nvgpu/gr/gr_instances.h new file mode 100644 index 000000000..b2b757439 --- /dev/null +++ b/drivers/gpu/nvgpu/include/nvgpu/gr/gr_instances.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2020, 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_GR_INSTANCES_H +#define NVGPU_GR_INSTANCES_H + +#include +#include +#include + +#ifdef CONFIG_NVGPU_MIG +#define nvgpu_gr_exec_for_each_instance(g, func) \ + ({ \ + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG)) { \ + u32 gr_instance_id = 0U; \ + while (gr_instance_id < g->num_gr_instances) { \ + struct nvgpu_gr *gr = &g->gr[gr_instance_id]; \ + u32 gr_syspipe_id = nvgpu_gr_get_syspipe_id(gr); \ + nvgpu_grmgr_config_gr_remap_window(g, gr_syspipe_id, true); \ + g->cur_gr_instance = gr_instance_id; \ + (func); \ + nvgpu_grmgr_config_gr_remap_window(g, gr_syspipe_id, false); \ + } \ + } else { \ + (func); \ + } \ + }) +#else +#define nvgpu_gr_for_each_gr_instance(g, func) (func) +#endif + +#ifdef CONFIG_NVGPU_MIG +#define nvgpu_gr_exec_with_ret_for_each_instance(g, func) \ + ({ \ + int err = 0; \ + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG)) { \ + u32 gr_instance_id = 0U; \ + while (gr_instance_id < g->num_gr_instances) { \ + struct nvgpu_gr *gr = &g->gr[gr_instance_id]; \ + u32 gr_syspipe_id = nvgpu_gr_get_syspipe_id(gr); \ + nvgpu_grmgr_config_gr_remap_window(g, gr_syspipe_id, true); \ + g->cur_gr_instance = gr_instance_id; \ + err = (func); \ + if (err != 0) { \ + break; \ + } \ + nvgpu_grmgr_config_gr_remap_window(g, gr_syspipe_id, false); \ + } \ + } else { \ + err = (func); \ + } \ + err; \ + }) +#else +#define nvgpu_gr_exec_with_ret_for_each_instance(g, func) (func) +#endif + +#ifdef CONFIG_NVGPU_MIG +#define nvgpu_gr_exec_for_all_instances(g, func) \ + ({ \ + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG)) { \ + nvgpu_grmgr_config_gr_remap_window(g, NVGPU_MIG_INVALID_GR_SYSPIPE_ID, false); \ + g->cur_gr_instance = 0; \ + (func); \ + nvgpu_grmgr_config_gr_remap_window(g, NVGPU_MIG_INVALID_GR_SYSPIPE_ID, true); \ + } else { \ + (func); \ + } \ + }) +#else +#define nvgpu_gr_exec_for_all_instances(g, func) (func) +#endif + +#endif /* NVGPU_GR_INSTANCES_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/grmgr.h b/drivers/gpu/nvgpu/include/nvgpu/grmgr.h index 5cfd7b83a..7b569bbd7 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/grmgr.h +++ b/drivers/gpu/nvgpu/include/nvgpu/grmgr.h @@ -34,5 +34,6 @@ int nvgpu_init_gr_manager(struct gk20a *g); int nvgpu_grmgr_config_gr_remap_window(struct gk20a *g, u32 gr_syspipe_id, bool enable); u32 nvgpu_grmgr_get_num_gr_instances(struct gk20a *g); +u32 nvgpu_grmgr_get_gr_syspipe_id(struct gk20a *g, u32 gr_instance_id); #endif /* NVGPU_GRMGR_H */ diff --git a/userspace/units/acr/nvgpu-acr.c b/userspace/units/acr/nvgpu-acr.c index f2fcf9506..fce6e3fa1 100644 --- a/userspace/units/acr/nvgpu-acr.c +++ b/userspace/units/acr/nvgpu-acr.c @@ -174,6 +174,16 @@ static void utf_falcon_register_io(struct gk20a *g) nvgpu_posix_register_io(g, &utf_falcon_reg_callbacks); } +static void nvgpu_init_gr_manager(struct gk20a *g) +{ + struct nvgpu_gpu_instance *gpu_instance = &g->mig.gpu_instance[0]; + struct nvgpu_gr_syspipe *gr_syspipe = &gpu_instance->gr_syspipe; + + g->mig.num_gpu_instances = 1; + gr_syspipe->gr_instance_id = 0U; + gr_syspipe->gr_syspipe_id = 0U; +} + static int init_acr_falcon_test_env(struct unit_module *m, struct gk20a *g) { int err = 0; @@ -247,6 +257,8 @@ static int init_acr_falcon_test_env(struct unit_module *m, struct gk20a *g) unit_return_fail(m, "netlist init failed\n"); } + nvgpu_init_gr_manager(g); + nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true); err = nvgpu_gr_alloc(g); if (err != 0) { diff --git a/userspace/units/gr/nvgpu-gr.c b/userspace/units/gr/nvgpu-gr.c index c890204f1..77d2a8dd4 100644 --- a/userspace/units/gr/nvgpu-gr.c +++ b/userspace/units/gr/nvgpu-gr.c @@ -41,6 +41,16 @@ #include "nvgpu-gr.h" #include "nvgpu-gr-gv11b.h" +static void nvgpu_init_gr_manager(struct gk20a *g) +{ + struct nvgpu_gpu_instance *gpu_instance = &g->mig.gpu_instance[0]; + struct nvgpu_gr_syspipe *gr_syspipe = &gpu_instance->gr_syspipe; + + g->mig.num_gpu_instances = 1; + gr_syspipe->gr_instance_id = 0U; + gr_syspipe->gr_syspipe_id = 0U; +} + int test_gr_init_setup(struct unit_module *m, struct gk20a *g, void *args) { int err; @@ -62,6 +72,8 @@ int test_gr_init_setup(struct unit_module *m, struct gk20a *g, void *args) unit_return_fail(m, "netlist init failed\n"); } + nvgpu_init_gr_manager(g); + /* * Allocate gr unit */ diff --git a/userspace/units/ltc/nvgpu-ltc.c b/userspace/units/ltc/nvgpu-ltc.c index a68b74b79..52d48e85c 100644 --- a/userspace/units/ltc/nvgpu-ltc.c +++ b/userspace/units/ltc/nvgpu-ltc.c @@ -242,6 +242,16 @@ int test_ltc_init_support(struct unit_module *m, return UNIT_SUCCESS; } +static void nvgpu_init_gr_manager(struct gk20a *g) +{ + struct nvgpu_gpu_instance *gpu_instance = &g->mig.gpu_instance[0]; + struct nvgpu_gr_syspipe *gr_syspipe = &gpu_instance->gr_syspipe; + + g->mig.num_gpu_instances = 1; + gr_syspipe->gr_instance_id = 0U; + gr_syspipe->gr_syspipe_id = 0U; +} + int test_ltc_ecc_init_free(struct unit_module *m, struct gk20a *g, void *args) { int ret = UNIT_SUCCESS; @@ -261,6 +271,8 @@ int test_ltc_ecc_init_free(struct unit_module *m, struct gk20a *g, void *args) unit_return_fail(m, "netlist init failed\n"); } + nvgpu_init_gr_manager(g); + err = nvgpu_gr_alloc(g); if (err != 0) { unit_return_fail(m, "failed to init gr\n"); diff --git a/userspace/units/pmu/nvgpu-pmu.c b/userspace/units/pmu/nvgpu-pmu.c index 7d2502ba8..ce2456cdd 100644 --- a/userspace/units/pmu/nvgpu-pmu.c +++ b/userspace/units/pmu/nvgpu-pmu.c @@ -162,6 +162,16 @@ static int add_reg_space(struct unit_module *m, struct gk20a *g) return 0; } +static void nvgpu_init_gr_manager(struct gk20a *g) +{ + struct nvgpu_gpu_instance *gpu_instance = &g->mig.gpu_instance[0]; + struct nvgpu_gr_syspipe *gr_syspipe = &gpu_instance->gr_syspipe; + + g->mig.num_gpu_instances = 1; + gr_syspipe->gr_instance_id = 0U; + gr_syspipe->gr_syspipe_id = 0U; +} + static int init_pmu_falcon_test_env(struct unit_module *m, struct gk20a *g) { int err = 0; @@ -208,6 +218,8 @@ static int init_pmu_falcon_test_env(struct unit_module *m, struct gk20a *g) unit_return_fail(m, "netlist init failed\n"); } + nvgpu_init_gr_manager(g); + nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true); err = nvgpu_gr_alloc(g);