From 697fe17dd612769633f8c93e37b65cc51966d7e7 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Tue, 20 Sep 2016 08:48:16 -0700 Subject: gpu: nvgpu: Suppress error msg from VBIOS overlay Suppress error message when nvgpu tries to load VBIOS overlay, but one is not found. This situation is normal. This is done by moving gk20a_request_firmware() to be nvgpu generic function nvgpu_request_firmware(), and adding a NO_WARN flag to it. Introduce also a NO_SOC flag to suppress attempt to load firmware from SoC specific directory in addition to the chip specific directory. Use it for dGPU firmware files. Bug 200236777 Change-Id: I0294d3308f029a6a6d3c2effa579d5f69a91e418 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/1223840 (cherry picked from commit cca44c3f010f15918cdd2259c15170ba1917828a) Reviewed-on: http://git-master/r/1233353 GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 3 +- drivers/gpu/nvgpu/gk20a/gk20a.c | 57 ----------------------------- drivers/gpu/nvgpu/gk20a/gk20a.h | 8 ---- drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c | 3 +- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 5 ++- drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 14 ++++--- drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | 2 + drivers/gpu/nvgpu/gm206/acr_gm206.c | 5 ++- drivers/gpu/nvgpu/gm206/bios_gm206.c | 5 ++- drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 18 ++++----- drivers/gpu/nvgpu/nvgpu_common.c | 67 ++++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/nvgpu_common.h | 7 ++++ 12 files changed, 109 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c index 844718a7..ca785b19 100644 --- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c @@ -32,6 +32,7 @@ #include "gr_gk20a.h" #include "debug_gk20a.h" #include "semaphore_gk20a.h" +#include "nvgpu_common.h" #include "hw_ccsr_gk20a.h" #include "hw_pbdma_gk20a.h" @@ -1179,7 +1180,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx) int err = 0; u64 vaddr; - img = gk20a_request_firmware(g, "gpu2cde.bin"); + img = nvgpu_request_firmware(g, "gpu2cde.bin", 0); if (!img) { dev_err(cde_ctx->dev, "cde: could not fetch the firmware"); return -ENOSYS; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 51384933..721c44e3 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -706,8 +705,6 @@ void gk20a_remove_support(struct device *dev) if (g->sim.remove_support) g->sim.remove_support(&g->sim); - release_firmware(g->pmu_fw); - /* free mappings to registers, etc */ if (g->regs) { @@ -2047,60 +2044,6 @@ int gk20a_init_gpu_characteristics(struct gk20a *g) return 0; } -static const struct firmware * -do_request_firmware(struct device *dev, const char *prefix, const char *fw_name) -{ - const struct firmware *fw; - char *fw_path = NULL; - int path_len, err; - - if (prefix) { - path_len = strlen(prefix) + strlen(fw_name); - path_len += 2; /* for the path separator and zero terminator*/ - - fw_path = kzalloc(sizeof(*fw_path) * path_len, GFP_KERNEL); - if (!fw_path) - return NULL; - - sprintf(fw_path, "%s/%s", prefix, fw_name); - fw_name = fw_path; - } - - err = request_firmware(&fw, fw_name, dev); - kfree(fw_path); - if (err) - return NULL; - return fw; -} - -/* This is a simple wrapper around request_firmware that takes 'fw_name' and - * applies an IP specific relative path prefix to it. The caller is - * responsible for calling release_firmware later. */ -const struct firmware * -gk20a_request_firmware(struct gk20a *g, const char *fw_name) -{ - struct device *dev = g->dev; - const struct firmware *fw; - - /* current->fs is NULL when calling from SYS_EXIT. - Add a check here to prevent crash in request_firmware */ - if (!current->fs || !fw_name) - return NULL; - - BUG_ON(!g->ops.name); - fw = do_request_firmware(dev, g->ops.name, fw_name); - -#ifdef CONFIG_TEGRA_GK20A - /* TO BE REMOVED - Support loading from legacy SOC specific path. */ - if (!fw) { - struct gk20a_platform *platform = gk20a_get_platform(dev); - fw = do_request_firmware(dev, platform->soc_name, fw_name); - } -#endif - - return fw; -} - int gk20a_read_ptimer(struct gk20a *g, u64 *value) { const unsigned int max_iterations = 3; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 1cccaebe..2b55dd26 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -762,11 +762,6 @@ struct gk20a { #ifdef CONFIG_DEBUG_FS struct railgate_stats pstats; #endif - /* Save pmu fw here so that it lives cross suspend/resume. - pmu suspend destroys all pmu sw/hw states. Loading pmu - fw in resume crashes when the resume is from sys_exit. */ - const struct firmware *pmu_fw; - u32 gr_idle_timeout_default; #if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0) u32 timeouts_enabled; @@ -1178,9 +1173,6 @@ int gk20a_do_unidle(void); int __gk20a_do_idle(struct device *dev, bool force_reset); int __gk20a_do_unidle(struct device *dev); -const struct firmware * -gk20a_request_firmware(struct gk20a *g, const char *fw_name); - #define NVGPU_GPU_ARCHITECTURE_SHIFT 4 /* constructs unique and compact GPUID from nvgpu_gpu_characteristics diff --git a/drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c index 5b76eee2..5a1152d5 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c @@ -24,6 +24,7 @@ #include "gk20a.h" #include "gr_ctx_gk20a.h" #include "hw_gr_gk20a.h" +#include "nvgpu_common.h" static int gr_gk20a_alloc_load_netlist_u32(u32 *src, u32 len, struct u32_list_gk20a *u32_list) @@ -135,7 +136,7 @@ static int gr_gk20a_init_ctx_vars_fw(struct gk20a *g, struct gr_gk20a *gr) continue; } - netlist_fw = gk20a_request_firmware(g, name); + netlist_fw = nvgpu_request_firmware(g, name, 0); if (!netlist_fw) { gk20a_warn(d, "failed to load netlist %s", name); continue; diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 883cacdc..9a201cb6 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -34,6 +34,7 @@ #include "gk20a.h" #include "kind_gk20a.h" #include "gr_ctx_gk20a.h" +#include "nvgpu_common.h" #include "hw_ccsr_gk20a.h" #include "hw_ctxsw_prog_gk20a.h" @@ -2124,7 +2125,7 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g) u32 ucode_size; int err = 0; - fecs_fw = gk20a_request_firmware(g, GK20A_FECS_UCODE_IMAGE); + fecs_fw = nvgpu_request_firmware(g, GK20A_FECS_UCODE_IMAGE, 0); if (!fecs_fw) { gk20a_err(d, "failed to load fecs ucode!!"); return -ENOENT; @@ -2134,7 +2135,7 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g) fecs_boot_image = (void *)(fecs_fw->data + sizeof(struct gk20a_ctxsw_bootloader_desc)); - gpccs_fw = gk20a_request_firmware(g, GK20A_GPCCS_UCODE_IMAGE); + gpccs_fw = nvgpu_request_firmware(g, GK20A_GPCCS_UCODE_IMAGE, 0); if (!gpccs_fw) { release_firmware(fecs_fw); gk20a_err(d, "failed to load gpccs ucode!!"); diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index ca9f2e15..fc95b5bc 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -30,6 +30,7 @@ #include "hw_mc_gk20a.h" #include "hw_pwr_gk20a.h" #include "hw_top_gk20a.h" +#include "nvgpu_common.h" #ifdef CONFIG_ARCH_TEGRA_18x_SOC #include "nvgpu_gpuid_t18x.h" @@ -2883,6 +2884,8 @@ void gk20a_remove_pmu_support(struct pmu_gk20a *pmu) if (gk20a_alloc_initialized(&pmu->dmem)) gk20a_alloc_destroy(&pmu->dmem); + + release_firmware(pmu->fw); } static int gk20a_init_pmu_reset_enable_hw(struct gk20a *g) @@ -2904,18 +2907,18 @@ static int gk20a_prepare_ucode(struct gk20a *g) struct mm_gk20a *mm = &g->mm; struct vm_gk20a *vm = &mm->pmu.vm; - if (g->pmu_fw) + if (pmu->fw) return gk20a_init_pmu(pmu); - g->pmu_fw = gk20a_request_firmware(g, GK20A_PMU_UCODE_IMAGE); - if (!g->pmu_fw) { + pmu->fw = nvgpu_request_firmware(g, GK20A_PMU_UCODE_IMAGE, 0); + if (!pmu->fw) { gk20a_err(d, "failed to load pmu ucode!!"); return err; } gk20a_dbg_fn("firmware loaded"); - pmu->desc = (struct pmu_ucode_desc *)g->pmu_fw->data; + pmu->desc = (struct pmu_ucode_desc *)pmu->fw->data; pmu->ucode_image = (u32 *)((u8 *)pmu->desc + pmu->desc->descriptor_size); @@ -2930,7 +2933,8 @@ static int gk20a_prepare_ucode(struct gk20a *g) return gk20a_init_pmu(pmu); err_release_fw: - release_firmware(g->pmu_fw); + release_firmware(pmu->fw); + pmu->fw = NULL; return err; } diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h index fe82eca4..b28fd597 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h @@ -738,6 +738,8 @@ struct pmu_gk20a { u32 falcon_id; u32 aelpg_param[5]; u32 override_done; + + const struct firmware *fw; }; int gk20a_init_pmu_support(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/gm206/acr_gm206.c b/drivers/gpu/nvgpu/gm206/acr_gm206.c index 39b30ea6..872ff601 100644 --- a/drivers/gpu/nvgpu/gm206/acr_gm206.c +++ b/drivers/gpu/nvgpu/gm206/acr_gm206.c @@ -25,6 +25,7 @@ #include "hw_pwr_gm206.h" #include "acr.h" #include "acr_gm206.h" +#include "nvgpu_common.h" /*Defines*/ #define gm206_dbg_pmu(fmt, arg...) \ @@ -226,7 +227,9 @@ static int gm206_bootstrap_hs_flcn(struct gk20a *g) if (!acr_fw) { /*First time init case*/ - acr_fw = gk20a_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE); + acr_fw = nvgpu_request_firmware(g, + GM20B_HSBIN_PMU_UCODE_IMAGE, + NVGPU_REQUEST_FIRMWARE_NO_SOC); if (!acr_fw) { gk20a_err(dev_from_gk20a(g), "pmu ucode get fail"); return -ENOENT; diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c index 6a509b04..a8f3f1d5 100644 --- a/drivers/gpu/nvgpu/gm206/bios_gm206.c +++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c @@ -24,6 +24,7 @@ #include "hw_xve_gm206.h" #include "hw_top_gm206.h" #include "bios_gm206.h" +#include "nvgpu_common.h" #define BIT_HEADER_ID 0xb8ff #define BIT_HEADER_SIGNATURE 0x00544942 @@ -739,7 +740,9 @@ static int gm206_bios_init(struct gk20a *g) snprintf(rom_name, sizeof(rom_name), BIOS_OVERLAY_NAME, pdev->device); gk20a_dbg_info("checking for VBIOS overlay %s", rom_name); - bios_fw = gk20a_request_firmware(g, rom_name); + bios_fw = nvgpu_request_firmware(g, rom_name, + NVGPU_REQUEST_FIRMWARE_NO_WARN | + NVGPU_REQUEST_FIRMWARE_NO_SOC); if (bios_fw) { gk20a_dbg_info("using VBIOS overlay"); g->bios.size = bios_fw->size - ROM_FILE_PAYLOAD_OFFSET; diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c index c4a188ff..310a3bc8 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c @@ -18,7 +18,7 @@ #include #include #include -#include "../../../../arch/arm/mach-tegra/iomap.h" +#include "nvgpu_common.h" #include @@ -118,7 +118,7 @@ static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) struct lsf_ucode_desc *lsf_desc; int err; gm20b_dbg_pmu("requesting PMU ucode in GM20B\n"); - pmu_fw = gk20a_request_firmware(g, GM20B_PMU_UCODE_IMAGE); + pmu_fw = nvgpu_request_firmware(g, GM20B_PMU_UCODE_IMAGE, 0); if (!pmu_fw) { gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode!!"); return -ENOENT; @@ -127,13 +127,13 @@ static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) gm20b_dbg_pmu("Loaded PMU ucode in for blob preparation"); gm20b_dbg_pmu("requesting PMU ucode desc in GM20B\n"); - pmu_desc = gk20a_request_firmware(g, GM20B_PMU_UCODE_DESC); + pmu_desc = nvgpu_request_firmware(g, GM20B_PMU_UCODE_DESC, 0); if (!pmu_desc) { gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode desc!!"); err = -ENOENT; goto release_img_fw; } - pmu_sig = gk20a_request_firmware(g, GM20B_PMU_UCODE_SIG); + pmu_sig = nvgpu_request_firmware(g, GM20B_PMU_UCODE_SIG, 0); if (!pmu_sig) { gk20a_err(dev_from_gk20a(g), "failed to load pmu sig!!"); err = -ENOENT; @@ -181,7 +181,7 @@ static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) const struct firmware *fecs_sig; int err; - fecs_sig = gk20a_request_firmware(g, GM20B_FECS_UCODE_SIG); + fecs_sig = nvgpu_request_firmware(g, GM20B_FECS_UCODE_SIG, 0); if (!fecs_sig) { gk20a_err(dev_from_gk20a(g), "failed to load fecs sig"); return -ENOENT; @@ -251,7 +251,7 @@ static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) if (g->ops.securegpccs == false) return -ENOENT; - gpccs_sig = gk20a_request_firmware(g, T18x_GPCCS_UCODE_SIG); + gpccs_sig = nvgpu_request_firmware(g, T18x_GPCCS_UCODE_SIG, 0); if (!gpccs_sig) { gk20a_err(dev_from_gk20a(g), "failed to load gpccs sig"); return -ENOENT; @@ -1071,7 +1071,7 @@ static int gm20b_bootstrap_hs_flcn(struct gk20a *g) if (!acr_fw) { /*First time init case*/ - acr_fw = gk20a_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE); + acr_fw = nvgpu_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE, 0); if (!acr_fw) { gk20a_err(dev_from_gk20a(g), "pmu ucode get fail"); return -ENOENT; @@ -1382,8 +1382,8 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt) gm20b_dbg_pmu(""); if (!hsbl_fw) { - hsbl_fw = gk20a_request_firmware(g, - GM20B_HSBIN_PMU_BL_UCODE_IMAGE); + hsbl_fw = nvgpu_request_firmware(g, + GM20B_HSBIN_PMU_BL_UCODE_IMAGE, 0); if (!hsbl_fw) { gk20a_err(dev_from_gk20a(g), "pmu ucode load fail"); return -ENOENT; diff --git a/drivers/gpu/nvgpu/nvgpu_common.c b/drivers/gpu/nvgpu/nvgpu_common.c index bdc07e50..fac818a2 100644 --- a/drivers/gpu/nvgpu/nvgpu_common.c +++ b/drivers/gpu/nvgpu/nvgpu_common.c @@ -15,9 +15,11 @@ */ #include +#include #include "gk20a/gk20a_scale.h" #include "gk20a/gk20a.h" +#include "nvgpu_common.h" #define EMC3D_DEFAULT_RATIO 750 @@ -152,3 +154,68 @@ int nvgpu_probe(struct gk20a *g, return 0; } + +static const struct firmware *do_request_firmware(struct device *dev, + const char *prefix, const char *fw_name, int flags) +{ + const struct firmware *fw; + char *fw_path = NULL; + int path_len, err; + + if (prefix) { + path_len = strlen(prefix) + strlen(fw_name); + path_len += 2; /* for the path separator and zero terminator*/ + + fw_path = kzalloc(sizeof(*fw_path) * path_len, GFP_KERNEL); + if (!fw_path) + return NULL; + + sprintf(fw_path, "%s/%s", prefix, fw_name); + fw_name = fw_path; + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) + err = request_firmware(&fw, fw_name, dev); +#else + if (flags & NVGPU_REQUEST_FIRMWARE_NO_WARN) + err = request_firmware_direct(&fw, fw_name, dev); + else + err = request_firmware(&fw, fw_name, dev); +#endif + + kfree(fw_path); + if (err) + return NULL; + return fw; +} + +/* This is a simple wrapper around request_firmware that takes 'fw_name' and + * applies an IP specific relative path prefix to it. The caller is + * responsible for calling release_firmware later. */ +const struct firmware *nvgpu_request_firmware(struct gk20a *g, + const char *fw_name, + int flags) +{ + struct device *dev = g->dev; + const struct firmware *fw; + + /* current->fs is NULL when calling from SYS_EXIT. + Add a check here to prevent crash in request_firmware */ + if (!current->fs || !fw_name) + return NULL; + + BUG_ON(!g->ops.name); + fw = do_request_firmware(dev, g->ops.name, fw_name, flags); + +#ifdef CONFIG_TEGRA_GK20A + /* TO BE REMOVED - Support loading from legacy SOC specific path. */ + if (!fw && !(flags & NVGPU_REQUEST_FIRMWARE_NO_SOC)) { + struct gk20a_platform *platform = gk20a_get_platform(dev); + fw = do_request_firmware(dev, + platform->soc_name, fw_name, flags); + } +#endif + + return fw; +} + diff --git a/drivers/gpu/nvgpu/nvgpu_common.h b/drivers/gpu/nvgpu/nvgpu_common.h index c9914089..8c159012 100644 --- a/drivers/gpu/nvgpu/nvgpu_common.h +++ b/drivers/gpu/nvgpu/nvgpu_common.h @@ -24,4 +24,11 @@ int nvgpu_probe(struct gk20a *g, const char *interface_name, struct class *class); +#define NVGPU_REQUEST_FIRMWARE_NO_WARN BIT(0) +#define NVGPU_REQUEST_FIRMWARE_NO_SOC BIT(1) + +const struct firmware *nvgpu_request_firmware(struct gk20a *g, + const char *fw_name, + int flags); + #endif -- cgit v1.2.2