From 010f818596028aaa64f4a0df60645373e7a3065f Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Mon, 10 Aug 2020 18:04:47 +0530 Subject: [PATCH] gpu: nvgpu: initialize gr struct in poweron path struct nvgpu_gr is right now initialized during probe and from OS specific code. To support multiple instances of graphics engine, nvgpu needs to initialize nvgpu_gr after number of engine instances have been enumerated in poweron path. Hence move nvgpu_gr_alloc() to poweron path and after gr manager has been initialized. Some of the members of nvgpu_gr are initialized in probe path and they too are in OS specific code. Move them to common code in nvgpu_gr_alloc() Add field fecs_feature_override_ecc_val to struct gk20a to store the override flag read from device tree. This flag is later copied to nvgpu_gr in poweron path. Update tpc_pg_mask_store() to check for g->gr being NULL before accessing golden image pointer. Update tpc_fs_mask_store() to return error if g->gr is not initialized. This path needs nvgpu_gr struct initialized. Also fix the incorrect NULL pointer check in tpc_fs_mask_store() which breaks the write path to this sysfs. Jira NVGPU-5648 Change-Id: Ifa2f66f3663dc2f7c8891cb03b25e997e148ab06 Signed-off-by: Deepak Nibade Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2397259 Reviewed-by: automaticguardword Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: Lakshmanan M Reviewed-by: mobile promotions GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/gr/gr.c | 18 +++++++------ drivers/gpu/nvgpu/common/init/nvgpu_init.c | 2 ++ .../gpu/nvgpu/common/vgpu/init/init_vgpu.c | 6 +++++ drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 1 + drivers/gpu/nvgpu/include/nvgpu/gr/gr.h | 11 -------- drivers/gpu/nvgpu/os/linux/driver_common.c | 6 ++--- drivers/gpu/nvgpu/os/linux/module.c | 8 +----- drivers/gpu/nvgpu/os/linux/pci.c | 6 ----- drivers/gpu/nvgpu/os/linux/sysfs.c | 25 +++++++++++++------ drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c | 7 ------ libs/dgpu/libnvgpu-drv-dgpu_safe.export | 1 - libs/igpu/libnvgpu-drv-igpu_safe.export | 1 - userspace/units/gr/nvgpu-gr.c | 2 -- 13 files changed, 40 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/gr.c b/drivers/gpu/nvgpu/common/gr/gr.c index fd3a2e582..42517c50a 100644 --- a/drivers/gpu/nvgpu/common/gr/gr.c +++ b/drivers/gpu/nvgpu/common/gr/gr.c @@ -35,6 +35,7 @@ #endif #include #include +#include #include #include #include @@ -159,11 +160,6 @@ u32 nvgpu_gr_rop_offset(struct gk20a *g, u32 rop) return rop_offset; } -void nvgpu_gr_init(struct gk20a *g) -{ - (void)nvgpu_cond_init(&g->gr->init_wq); -} - static void disable_gr_interrupts(struct gk20a *g) { /** Disable gr intr */ @@ -840,8 +836,14 @@ int nvgpu_gr_alloc(struct gk20a *g) if (gr == NULL) { return -ENOMEM; } + g->gr = gr; + nvgpu_cond_init(&gr->init_wq); +#ifdef CONFIG_NVGPU_NON_FUSA + nvgpu_gr_override_ecc_val(g, g->fecs_feature_override_ecc_val); +#endif + return 0; } @@ -950,14 +952,16 @@ ctxsw_already_enabled: void nvgpu_gr_remove_support(struct gk20a *g) { - if (g->gr->remove_support != NULL) { + if (g->gr != NULL && g->gr->remove_support != NULL) { g->gr->remove_support(g); } } void nvgpu_gr_sw_ready(struct gk20a *g, bool enable) { - g->gr->sw_ready = enable; + if (g->gr != NULL) { + g->gr->sw_ready = enable; + } } #ifdef CONFIG_NVGPU_HAL_NON_FUSA diff --git a/drivers/gpu/nvgpu/common/init/nvgpu_init.c b/drivers/gpu/nvgpu/common/init/nvgpu_init.c index ce21008ea..7b21166dc 100644 --- a/drivers/gpu/nvgpu/common/init/nvgpu_init.c +++ b/drivers/gpu/nvgpu/common/init/nvgpu_init.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #ifdef CONFIG_NVGPU_LS_PMU @@ -649,6 +650,7 @@ int nvgpu_finalize_poweron(struct gk20a *g) #endif NVGPU_INIT_TABLE_ENTRY(g->ops.grmgr.init_gr_manager, NO_FLAG), /* prepare portion of sw required for enable hw */ + NVGPU_INIT_TABLE_ENTRY(&nvgpu_gr_alloc, NO_FLAG), NVGPU_INIT_TABLE_ENTRY(g->ops.gr.gr_prepare_sw, NO_FLAG), NVGPU_INIT_TABLE_ENTRY(g->ops.gr.gr_enable_hw, NO_FLAG), NVGPU_INIT_TABLE_ENTRY(g->ops.acr.acr_construct_execute, diff --git a/drivers/gpu/nvgpu/common/vgpu/init/init_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/init/init_vgpu.c index 83b44c45e..637797cb3 100644 --- a/drivers/gpu/nvgpu/common/vgpu/init/init_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/init/init_vgpu.c @@ -215,6 +215,12 @@ int vgpu_finalize_poweron_common(struct gk20a *g) return err; } + err = nvgpu_gr_alloc(g); + if (err != 0) { + nvgpu_err(g, "couldn't allocate gr memory"); + return err; + } + err = vgpu_init_gr_support(g); if (err != 0) { nvgpu_err(g, "failed to init gk20a gr"); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index b3117d5c5..2a40d929b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -947,6 +947,7 @@ struct gk20a { #ifdef CONFIG_NVGPU_NON_FUSA u32 tpc_fs_mask_user; + u32 fecs_feature_override_ecc_val; #endif u32 tpc_pg_mask; diff --git a/drivers/gpu/nvgpu/include/nvgpu/gr/gr.h b/drivers/gpu/nvgpu/include/nvgpu/gr/gr.h index 7f80e9713..4d068b343 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gr/gr.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gr/gr.h @@ -140,17 +140,6 @@ int nvgpu_gr_alloc(struct gk20a *g); */ void nvgpu_gr_free(struct gk20a *g); -/** - * @brief Initialize GR struct fields - * - * @param g [in] Pointer to GPU driver struct. - * - * Calling this function ensures that various GR struct fields are - * initialized before they are referenced by other units or before - * GR initialization sequence is executed. - */ -void nvgpu_gr_init(struct gk20a *g); - /** * @brief Initialize the s/w required to enable h/w. * diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index e377b6f26..36fa15eb1 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -109,10 +109,8 @@ static void nvgpu_init_vars(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_HAS_SYNCPOINTS, platform->has_syncpoints); } -static void nvgpu_init_gr_vars(struct gk20a *g) +static void nvgpu_init_max_comptag(struct gk20a *g) { - nvgpu_gr_init(g); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) nvgpu_log_info(g, "total ram pages : %lu", totalram_pages()); #else @@ -264,7 +262,7 @@ int nvgpu_probe(struct gk20a *g, int err = 0; nvgpu_init_vars(g); - nvgpu_init_gr_vars(g); + nvgpu_init_max_comptag(g); nvgpu_init_timeout(g); nvgpu_init_timeslice(g); nvgpu_init_pm_vars(g); diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 6d16078c4..8287ed81f 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -1095,12 +1095,6 @@ static int gk20a_init_support(struct platform_device *pdev) if (err) goto fail_sim; - err = nvgpu_gr_alloc(g); - if (err != 0) { - nvgpu_err(g, "couldn't allocate gr memory"); - goto fail_sim; - } - nvgpu_init_usermode_support(g); return 0; @@ -1568,7 +1562,7 @@ static int nvgpu_read_fuse_overrides(struct gk20a *g) g->tpc_fs_mask_user = ~value; break; case GP10B_FUSE_OPT_ECC_EN: - nvgpu_gr_override_ecc_val(g, value); + g->fecs_feature_override_ecc_val = value; break; case GV11B_FUSE_OPT_TPC_DISABLE: if (platform->set_tpc_pg_mask != NULL) diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index a79685a03..5046d93f5 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c @@ -381,12 +381,6 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev) if (err) goto fail_sim; - err = nvgpu_gr_alloc(g); - if (err != 0) { - nvgpu_err(g, "couldn't allocate gr memory"); - goto fail_sim; - } - return 0; fail_sim: diff --git a/drivers/gpu/nvgpu/os/linux/sysfs.c b/drivers/gpu/nvgpu/os/linux/sysfs.c index 1a53a1596..4d92d902f 100644 --- a/drivers/gpu/nvgpu/os/linux/sysfs.c +++ b/drivers/gpu/nvgpu/os/linux/sysfs.c @@ -846,8 +846,7 @@ static ssize_t tpc_pg_mask_store(struct device *dev, { struct gk20a *g = get_gk20a(dev); unsigned long val = 0; - struct nvgpu_gr_obj_ctx_golden_image *gr_golden_image = - nvgpu_gr_get_golden_image_ptr(g); + struct nvgpu_gr_obj_ctx_golden_image *gr_golden_image = NULL; nvgpu_mutex_acquire(&g->tpc_pg_lock); @@ -862,6 +861,10 @@ static ssize_t tpc_pg_mask_store(struct device *dev, goto exit; } + if (g->gr != NULL) { + gr_golden_image = nvgpu_gr_get_golden_image_ptr(g); + } + if (gr_golden_image && nvgpu_gr_obj_ctx_get_golden_image_size(gr_golden_image) != 0) { @@ -892,17 +895,23 @@ static ssize_t tpc_fs_mask_store(struct device *dev, { #ifdef CONFIG_NVGPU_TEGRA_FUSE struct gk20a *g = get_gk20a(dev); - struct nvgpu_gr_config *gr_config = nvgpu_gr_get_config_ptr(g); - struct nvgpu_gr_obj_ctx_golden_image *gr_golden_image = - nvgpu_gr_get_golden_image_ptr(g); - struct nvgpu_gr_falcon *gr_falcon = - nvgpu_gr_get_falcon_ptr(g); + struct nvgpu_gr_config *gr_config; + struct nvgpu_gr_obj_ctx_golden_image *gr_golden_image; + struct nvgpu_gr_falcon *gr_falcon; unsigned long val = 0; if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; - if (nvgpu_gr_config_get_gpc_tpc_mask_base(gr_config) != NULL) + if (g->gr == NULL) { + return -ENODEV; + } + + gr_config = nvgpu_gr_get_config_ptr(g); + gr_golden_image = nvgpu_gr_get_golden_image_ptr(g); + gr_falcon = nvgpu_gr_get_falcon_ptr(g); + + if (nvgpu_gr_config_get_gpc_tpc_mask_base(gr_config) == NULL) return -ENODEV; if (val && val != nvgpu_gr_config_get_gpc_tpc_mask(gr_config, 0) && diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c index af4ceda34..b5537ae60 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c @@ -161,12 +161,6 @@ static int vgpu_init_support(struct platform_device *pdev) SZ_4K / sizeof(g->dbg_regops_tmp_buf[0]); #endif - err = nvgpu_gr_alloc(g); - if (err != 0) { - nvgpu_err(g, "couldn't allocate gr memory"); - goto fail; - } - g->remove_support = vgpu_remove_support; return 0; @@ -480,7 +474,6 @@ int vgpu_probe(struct platform_device *pdev) nvgpu_atomic_set(&gk20a->timeouts_disabled_refcount, 0); vgpu_create_sysfs(dev); - nvgpu_gr_init(gk20a); #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) nvgpu_log_info(gk20a, "total ram pages : %lu", totalram_pages()); diff --git a/libs/dgpu/libnvgpu-drv-dgpu_safe.export b/libs/dgpu/libnvgpu-drv-dgpu_safe.export index af9c99288..0f9f60321 100644 --- a/libs/dgpu/libnvgpu-drv-dgpu_safe.export +++ b/libs/dgpu/libnvgpu-drv-dgpu_safe.export @@ -484,7 +484,6 @@ nvgpu_gr_global_ctx_desc_free nvgpu_gr_global_ctx_init_local_golden_image nvgpu_gr_global_ctx_load_local_golden_image nvgpu_gr_global_ctx_set_size -nvgpu_gr_init nvgpu_gr_init_support nvgpu_gr_intr_init_support nvgpu_gr_intr_remove_support diff --git a/libs/igpu/libnvgpu-drv-igpu_safe.export b/libs/igpu/libnvgpu-drv-igpu_safe.export index 8c2fa155a..ff2f923a5 100644 --- a/libs/igpu/libnvgpu-drv-igpu_safe.export +++ b/libs/igpu/libnvgpu-drv-igpu_safe.export @@ -498,7 +498,6 @@ nvgpu_gr_global_ctx_desc_free nvgpu_gr_global_ctx_init_local_golden_image nvgpu_gr_global_ctx_load_local_golden_image nvgpu_gr_global_ctx_set_size -nvgpu_gr_init nvgpu_gr_init_support nvgpu_gr_intr_init_support nvgpu_gr_intr_remove_support diff --git a/userspace/units/gr/nvgpu-gr.c b/userspace/units/gr/nvgpu-gr.c index 89c10f2ed..280eed5eb 100644 --- a/userspace/units/gr/nvgpu-gr.c +++ b/userspace/units/gr/nvgpu-gr.c @@ -104,8 +104,6 @@ int test_gr_init_support(struct unit_module *m, struct gk20a *g, void *args) { int err; - nvgpu_gr_init(g); - g->ops.ecc.ecc_init_support(g); g->ops.ltc.init_ltc_support(g); g->ops.mm.init_mm_support(g);