summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2016-09-20 11:48:16 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2016-10-09 16:03:35 -0400
commit697fe17dd612769633f8c93e37b65cc51966d7e7 (patch)
treecbf09661d91c10ca9149f40661aab119a7850302 /drivers/gpu/nvgpu
parent4cff26cd5b0096eeb26114cf36df8e2cb91821a8 (diff)
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 <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1223840 (cherry picked from commit cca44c3f010f15918cdd2259c15170ba1917828a) Reviewed-on: http://git-master/r/1233353 GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/cde_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c57
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h8
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c5
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c14
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gm206/acr_gm206.c5
-rw-r--r--drivers/gpu/nvgpu/gm206/bios_gm206.c5
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c18
-rw-r--r--drivers/gpu/nvgpu/nvgpu_common.c67
-rw-r--r--drivers/gpu/nvgpu/nvgpu_common.h7
12 files changed, 109 insertions, 85 deletions
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 @@
32#include "gr_gk20a.h" 32#include "gr_gk20a.h"
33#include "debug_gk20a.h" 33#include "debug_gk20a.h"
34#include "semaphore_gk20a.h" 34#include "semaphore_gk20a.h"
35#include "nvgpu_common.h"
35 36
36#include "hw_ccsr_gk20a.h" 37#include "hw_ccsr_gk20a.h"
37#include "hw_pbdma_gk20a.h" 38#include "hw_pbdma_gk20a.h"
@@ -1179,7 +1180,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx)
1179 int err = 0; 1180 int err = 0;
1180 u64 vaddr; 1181 u64 vaddr;
1181 1182
1182 img = gk20a_request_firmware(g, "gpu2cde.bin"); 1183 img = nvgpu_request_firmware(g, "gpu2cde.bin", 0);
1183 if (!img) { 1184 if (!img) {
1184 dev_err(cde_ctx->dev, "cde: could not fetch the firmware"); 1185 dev_err(cde_ctx->dev, "cde: could not fetch the firmware");
1185 return -ENOSYS; 1186 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 @@
22#include <linux/string.h> 22#include <linux/string.h>
23#include <linux/cdev.h> 23#include <linux/cdev.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/firmware.h>
26#include <linux/interrupt.h> 25#include <linux/interrupt.h>
27#include <linux/irq.h> 26#include <linux/irq.h>
28#include <linux/export.h> 27#include <linux/export.h>
@@ -706,8 +705,6 @@ void gk20a_remove_support(struct device *dev)
706 if (g->sim.remove_support) 705 if (g->sim.remove_support)
707 g->sim.remove_support(&g->sim); 706 g->sim.remove_support(&g->sim);
708 707
709 release_firmware(g->pmu_fw);
710
711 /* free mappings to registers, etc */ 708 /* free mappings to registers, etc */
712 709
713 if (g->regs) { 710 if (g->regs) {
@@ -2047,60 +2044,6 @@ int gk20a_init_gpu_characteristics(struct gk20a *g)
2047 return 0; 2044 return 0;
2048} 2045}
2049 2046
2050static const struct firmware *
2051do_request_firmware(struct device *dev, const char *prefix, const char *fw_name)
2052{
2053 const struct firmware *fw;
2054 char *fw_path = NULL;
2055 int path_len, err;
2056
2057 if (prefix) {
2058 path_len = strlen(prefix) + strlen(fw_name);
2059 path_len += 2; /* for the path separator and zero terminator*/
2060
2061 fw_path = kzalloc(sizeof(*fw_path) * path_len, GFP_KERNEL);
2062 if (!fw_path)
2063 return NULL;
2064
2065 sprintf(fw_path, "%s/%s", prefix, fw_name);
2066 fw_name = fw_path;
2067 }
2068
2069 err = request_firmware(&fw, fw_name, dev);
2070 kfree(fw_path);
2071 if (err)
2072 return NULL;
2073 return fw;
2074}
2075
2076/* This is a simple wrapper around request_firmware that takes 'fw_name' and
2077 * applies an IP specific relative path prefix to it. The caller is
2078 * responsible for calling release_firmware later. */
2079const struct firmware *
2080gk20a_request_firmware(struct gk20a *g, const char *fw_name)
2081{
2082 struct device *dev = g->dev;
2083 const struct firmware *fw;
2084
2085 /* current->fs is NULL when calling from SYS_EXIT.
2086 Add a check here to prevent crash in request_firmware */
2087 if (!current->fs || !fw_name)
2088 return NULL;
2089
2090 BUG_ON(!g->ops.name);
2091 fw = do_request_firmware(dev, g->ops.name, fw_name);
2092
2093#ifdef CONFIG_TEGRA_GK20A
2094 /* TO BE REMOVED - Support loading from legacy SOC specific path. */
2095 if (!fw) {
2096 struct gk20a_platform *platform = gk20a_get_platform(dev);
2097 fw = do_request_firmware(dev, platform->soc_name, fw_name);
2098 }
2099#endif
2100
2101 return fw;
2102}
2103
2104int gk20a_read_ptimer(struct gk20a *g, u64 *value) 2047int gk20a_read_ptimer(struct gk20a *g, u64 *value)
2105{ 2048{
2106 const unsigned int max_iterations = 3; 2049 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 {
762#ifdef CONFIG_DEBUG_FS 762#ifdef CONFIG_DEBUG_FS
763 struct railgate_stats pstats; 763 struct railgate_stats pstats;
764#endif 764#endif
765 /* Save pmu fw here so that it lives cross suspend/resume.
766 pmu suspend destroys all pmu sw/hw states. Loading pmu
767 fw in resume crashes when the resume is from sys_exit. */
768 const struct firmware *pmu_fw;
769
770 u32 gr_idle_timeout_default; 765 u32 gr_idle_timeout_default;
771#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0) 766#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0)
772 u32 timeouts_enabled; 767 u32 timeouts_enabled;
@@ -1178,9 +1173,6 @@ int gk20a_do_unidle(void);
1178int __gk20a_do_idle(struct device *dev, bool force_reset); 1173int __gk20a_do_idle(struct device *dev, bool force_reset);
1179int __gk20a_do_unidle(struct device *dev); 1174int __gk20a_do_unidle(struct device *dev);
1180 1175
1181const struct firmware *
1182gk20a_request_firmware(struct gk20a *g, const char *fw_name);
1183
1184#define NVGPU_GPU_ARCHITECTURE_SHIFT 4 1176#define NVGPU_GPU_ARCHITECTURE_SHIFT 4
1185 1177
1186/* constructs unique and compact GPUID from nvgpu_gpu_characteristics 1178/* 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 @@
24#include "gk20a.h" 24#include "gk20a.h"
25#include "gr_ctx_gk20a.h" 25#include "gr_ctx_gk20a.h"
26#include "hw_gr_gk20a.h" 26#include "hw_gr_gk20a.h"
27#include "nvgpu_common.h"
27 28
28static int gr_gk20a_alloc_load_netlist_u32(u32 *src, u32 len, 29static int gr_gk20a_alloc_load_netlist_u32(u32 *src, u32 len,
29 struct u32_list_gk20a *u32_list) 30 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)
135 continue; 136 continue;
136 } 137 }
137 138
138 netlist_fw = gk20a_request_firmware(g, name); 139 netlist_fw = nvgpu_request_firmware(g, name, 0);
139 if (!netlist_fw) { 140 if (!netlist_fw) {
140 gk20a_warn(d, "failed to load netlist %s", name); 141 gk20a_warn(d, "failed to load netlist %s", name);
141 continue; 142 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 @@
34#include "gk20a.h" 34#include "gk20a.h"
35#include "kind_gk20a.h" 35#include "kind_gk20a.h"
36#include "gr_ctx_gk20a.h" 36#include "gr_ctx_gk20a.h"
37#include "nvgpu_common.h"
37 38
38#include "hw_ccsr_gk20a.h" 39#include "hw_ccsr_gk20a.h"
39#include "hw_ctxsw_prog_gk20a.h" 40#include "hw_ctxsw_prog_gk20a.h"
@@ -2124,7 +2125,7 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
2124 u32 ucode_size; 2125 u32 ucode_size;
2125 int err = 0; 2126 int err = 0;
2126 2127
2127 fecs_fw = gk20a_request_firmware(g, GK20A_FECS_UCODE_IMAGE); 2128 fecs_fw = nvgpu_request_firmware(g, GK20A_FECS_UCODE_IMAGE, 0);
2128 if (!fecs_fw) { 2129 if (!fecs_fw) {
2129 gk20a_err(d, "failed to load fecs ucode!!"); 2130 gk20a_err(d, "failed to load fecs ucode!!");
2130 return -ENOENT; 2131 return -ENOENT;
@@ -2134,7 +2135,7 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
2134 fecs_boot_image = (void *)(fecs_fw->data + 2135 fecs_boot_image = (void *)(fecs_fw->data +
2135 sizeof(struct gk20a_ctxsw_bootloader_desc)); 2136 sizeof(struct gk20a_ctxsw_bootloader_desc));
2136 2137
2137 gpccs_fw = gk20a_request_firmware(g, GK20A_GPCCS_UCODE_IMAGE); 2138 gpccs_fw = nvgpu_request_firmware(g, GK20A_GPCCS_UCODE_IMAGE, 0);
2138 if (!gpccs_fw) { 2139 if (!gpccs_fw) {
2139 release_firmware(fecs_fw); 2140 release_firmware(fecs_fw);
2140 gk20a_err(d, "failed to load gpccs ucode!!"); 2141 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 @@
30#include "hw_mc_gk20a.h" 30#include "hw_mc_gk20a.h"
31#include "hw_pwr_gk20a.h" 31#include "hw_pwr_gk20a.h"
32#include "hw_top_gk20a.h" 32#include "hw_top_gk20a.h"
33#include "nvgpu_common.h"
33 34
34#ifdef CONFIG_ARCH_TEGRA_18x_SOC 35#ifdef CONFIG_ARCH_TEGRA_18x_SOC
35#include "nvgpu_gpuid_t18x.h" 36#include "nvgpu_gpuid_t18x.h"
@@ -2883,6 +2884,8 @@ void gk20a_remove_pmu_support(struct pmu_gk20a *pmu)
2883 2884
2884 if (gk20a_alloc_initialized(&pmu->dmem)) 2885 if (gk20a_alloc_initialized(&pmu->dmem))
2885 gk20a_alloc_destroy(&pmu->dmem); 2886 gk20a_alloc_destroy(&pmu->dmem);
2887
2888 release_firmware(pmu->fw);
2886} 2889}
2887 2890
2888static int gk20a_init_pmu_reset_enable_hw(struct gk20a *g) 2891static int gk20a_init_pmu_reset_enable_hw(struct gk20a *g)
@@ -2904,18 +2907,18 @@ static int gk20a_prepare_ucode(struct gk20a *g)
2904 struct mm_gk20a *mm = &g->mm; 2907 struct mm_gk20a *mm = &g->mm;
2905 struct vm_gk20a *vm = &mm->pmu.vm; 2908 struct vm_gk20a *vm = &mm->pmu.vm;
2906 2909
2907 if (g->pmu_fw) 2910 if (pmu->fw)
2908 return gk20a_init_pmu(pmu); 2911 return gk20a_init_pmu(pmu);
2909 2912
2910 g->pmu_fw = gk20a_request_firmware(g, GK20A_PMU_UCODE_IMAGE); 2913 pmu->fw = nvgpu_request_firmware(g, GK20A_PMU_UCODE_IMAGE, 0);
2911 if (!g->pmu_fw) { 2914 if (!pmu->fw) {
2912 gk20a_err(d, "failed to load pmu ucode!!"); 2915 gk20a_err(d, "failed to load pmu ucode!!");
2913 return err; 2916 return err;
2914 } 2917 }
2915 2918
2916 gk20a_dbg_fn("firmware loaded"); 2919 gk20a_dbg_fn("firmware loaded");
2917 2920
2918 pmu->desc = (struct pmu_ucode_desc *)g->pmu_fw->data; 2921 pmu->desc = (struct pmu_ucode_desc *)pmu->fw->data;
2919 pmu->ucode_image = (u32 *)((u8 *)pmu->desc + 2922 pmu->ucode_image = (u32 *)((u8 *)pmu->desc +
2920 pmu->desc->descriptor_size); 2923 pmu->desc->descriptor_size);
2921 2924
@@ -2930,7 +2933,8 @@ static int gk20a_prepare_ucode(struct gk20a *g)
2930 return gk20a_init_pmu(pmu); 2933 return gk20a_init_pmu(pmu);
2931 2934
2932 err_release_fw: 2935 err_release_fw:
2933 release_firmware(g->pmu_fw); 2936 release_firmware(pmu->fw);
2937 pmu->fw = NULL;
2934 2938
2935 return err; 2939 return err;
2936} 2940}
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 {
738 u32 falcon_id; 738 u32 falcon_id;
739 u32 aelpg_param[5]; 739 u32 aelpg_param[5];
740 u32 override_done; 740 u32 override_done;
741
742 const struct firmware *fw;
741}; 743};
742 744
743int gk20a_init_pmu_support(struct gk20a *g); 745int 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 @@
25#include "hw_pwr_gm206.h" 25#include "hw_pwr_gm206.h"
26#include "acr.h" 26#include "acr.h"
27#include "acr_gm206.h" 27#include "acr_gm206.h"
28#include "nvgpu_common.h"
28 29
29/*Defines*/ 30/*Defines*/
30#define gm206_dbg_pmu(fmt, arg...) \ 31#define gm206_dbg_pmu(fmt, arg...) \
@@ -226,7 +227,9 @@ static int gm206_bootstrap_hs_flcn(struct gk20a *g)
226 227
227 if (!acr_fw) { 228 if (!acr_fw) {
228 /*First time init case*/ 229 /*First time init case*/
229 acr_fw = gk20a_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE); 230 acr_fw = nvgpu_request_firmware(g,
231 GM20B_HSBIN_PMU_UCODE_IMAGE,
232 NVGPU_REQUEST_FIRMWARE_NO_SOC);
230 if (!acr_fw) { 233 if (!acr_fw) {
231 gk20a_err(dev_from_gk20a(g), "pmu ucode get fail"); 234 gk20a_err(dev_from_gk20a(g), "pmu ucode get fail");
232 return -ENOENT; 235 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 @@
24#include "hw_xve_gm206.h" 24#include "hw_xve_gm206.h"
25#include "hw_top_gm206.h" 25#include "hw_top_gm206.h"
26#include "bios_gm206.h" 26#include "bios_gm206.h"
27#include "nvgpu_common.h"
27 28
28#define BIT_HEADER_ID 0xb8ff 29#define BIT_HEADER_ID 0xb8ff
29#define BIT_HEADER_SIGNATURE 0x00544942 30#define BIT_HEADER_SIGNATURE 0x00544942
@@ -739,7 +740,9 @@ static int gm206_bios_init(struct gk20a *g)
739 740
740 snprintf(rom_name, sizeof(rom_name), BIOS_OVERLAY_NAME, pdev->device); 741 snprintf(rom_name, sizeof(rom_name), BIOS_OVERLAY_NAME, pdev->device);
741 gk20a_dbg_info("checking for VBIOS overlay %s", rom_name); 742 gk20a_dbg_info("checking for VBIOS overlay %s", rom_name);
742 bios_fw = gk20a_request_firmware(g, rom_name); 743 bios_fw = nvgpu_request_firmware(g, rom_name,
744 NVGPU_REQUEST_FIRMWARE_NO_WARN |
745 NVGPU_REQUEST_FIRMWARE_NO_SOC);
743 if (bios_fw) { 746 if (bios_fw) {
744 gk20a_dbg_info("using VBIOS overlay"); 747 gk20a_dbg_info("using VBIOS overlay");
745 g->bios.size = bios_fw->size - ROM_FILE_PAYLOAD_OFFSET; 748 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 @@
18#include <linux/debugfs.h> 18#include <linux/debugfs.h>
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include "../../../../arch/arm/mach-tegra/iomap.h" 21#include "nvgpu_common.h"
22 22
23#include <linux/platform/tegra/mc.h> 23#include <linux/platform/tegra/mc.h>
24 24
@@ -118,7 +118,7 @@ static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
118 struct lsf_ucode_desc *lsf_desc; 118 struct lsf_ucode_desc *lsf_desc;
119 int err; 119 int err;
120 gm20b_dbg_pmu("requesting PMU ucode in GM20B\n"); 120 gm20b_dbg_pmu("requesting PMU ucode in GM20B\n");
121 pmu_fw = gk20a_request_firmware(g, GM20B_PMU_UCODE_IMAGE); 121 pmu_fw = nvgpu_request_firmware(g, GM20B_PMU_UCODE_IMAGE, 0);
122 if (!pmu_fw) { 122 if (!pmu_fw) {
123 gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode!!"); 123 gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode!!");
124 return -ENOENT; 124 return -ENOENT;
@@ -127,13 +127,13 @@ static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
127 gm20b_dbg_pmu("Loaded PMU ucode in for blob preparation"); 127 gm20b_dbg_pmu("Loaded PMU ucode in for blob preparation");
128 128
129 gm20b_dbg_pmu("requesting PMU ucode desc in GM20B\n"); 129 gm20b_dbg_pmu("requesting PMU ucode desc in GM20B\n");
130 pmu_desc = gk20a_request_firmware(g, GM20B_PMU_UCODE_DESC); 130 pmu_desc = nvgpu_request_firmware(g, GM20B_PMU_UCODE_DESC, 0);
131 if (!pmu_desc) { 131 if (!pmu_desc) {
132 gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode desc!!"); 132 gk20a_err(dev_from_gk20a(g), "failed to load pmu ucode desc!!");
133 err = -ENOENT; 133 err = -ENOENT;
134 goto release_img_fw; 134 goto release_img_fw;
135 } 135 }
136 pmu_sig = gk20a_request_firmware(g, GM20B_PMU_UCODE_SIG); 136 pmu_sig = nvgpu_request_firmware(g, GM20B_PMU_UCODE_SIG, 0);
137 if (!pmu_sig) { 137 if (!pmu_sig) {
138 gk20a_err(dev_from_gk20a(g), "failed to load pmu sig!!"); 138 gk20a_err(dev_from_gk20a(g), "failed to load pmu sig!!");
139 err = -ENOENT; 139 err = -ENOENT;
@@ -181,7 +181,7 @@ static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
181 const struct firmware *fecs_sig; 181 const struct firmware *fecs_sig;
182 int err; 182 int err;
183 183
184 fecs_sig = gk20a_request_firmware(g, GM20B_FECS_UCODE_SIG); 184 fecs_sig = nvgpu_request_firmware(g, GM20B_FECS_UCODE_SIG, 0);
185 if (!fecs_sig) { 185 if (!fecs_sig) {
186 gk20a_err(dev_from_gk20a(g), "failed to load fecs sig"); 186 gk20a_err(dev_from_gk20a(g), "failed to load fecs sig");
187 return -ENOENT; 187 return -ENOENT;
@@ -251,7 +251,7 @@ static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
251 if (g->ops.securegpccs == false) 251 if (g->ops.securegpccs == false)
252 return -ENOENT; 252 return -ENOENT;
253 253
254 gpccs_sig = gk20a_request_firmware(g, T18x_GPCCS_UCODE_SIG); 254 gpccs_sig = nvgpu_request_firmware(g, T18x_GPCCS_UCODE_SIG, 0);
255 if (!gpccs_sig) { 255 if (!gpccs_sig) {
256 gk20a_err(dev_from_gk20a(g), "failed to load gpccs sig"); 256 gk20a_err(dev_from_gk20a(g), "failed to load gpccs sig");
257 return -ENOENT; 257 return -ENOENT;
@@ -1071,7 +1071,7 @@ static int gm20b_bootstrap_hs_flcn(struct gk20a *g)
1071 1071
1072 if (!acr_fw) { 1072 if (!acr_fw) {
1073 /*First time init case*/ 1073 /*First time init case*/
1074 acr_fw = gk20a_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE); 1074 acr_fw = nvgpu_request_firmware(g, GM20B_HSBIN_PMU_UCODE_IMAGE, 0);
1075 if (!acr_fw) { 1075 if (!acr_fw) {
1076 gk20a_err(dev_from_gk20a(g), "pmu ucode get fail"); 1076 gk20a_err(dev_from_gk20a(g), "pmu ucode get fail");
1077 return -ENOENT; 1077 return -ENOENT;
@@ -1382,8 +1382,8 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1382 gm20b_dbg_pmu(""); 1382 gm20b_dbg_pmu("");
1383 1383
1384 if (!hsbl_fw) { 1384 if (!hsbl_fw) {
1385 hsbl_fw = gk20a_request_firmware(g, 1385 hsbl_fw = nvgpu_request_firmware(g,
1386 GM20B_HSBIN_PMU_BL_UCODE_IMAGE); 1386 GM20B_HSBIN_PMU_BL_UCODE_IMAGE, 0);
1387 if (!hsbl_fw) { 1387 if (!hsbl_fw) {
1388 gk20a_err(dev_from_gk20a(g), "pmu ucode load fail"); 1388 gk20a_err(dev_from_gk20a(g), "pmu ucode load fail");
1389 return -ENOENT; 1389 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 @@
15 */ 15 */
16 16
17#include <linux/dma-mapping.h> 17#include <linux/dma-mapping.h>
18#include <linux/firmware.h>
18 19
19#include "gk20a/gk20a_scale.h" 20#include "gk20a/gk20a_scale.h"
20#include "gk20a/gk20a.h" 21#include "gk20a/gk20a.h"
22#include "nvgpu_common.h"
21 23
22#define EMC3D_DEFAULT_RATIO 750 24#define EMC3D_DEFAULT_RATIO 750
23 25
@@ -152,3 +154,68 @@ int nvgpu_probe(struct gk20a *g,
152 154
153 return 0; 155 return 0;
154} 156}
157
158static const struct firmware *do_request_firmware(struct device *dev,
159 const char *prefix, const char *fw_name, int flags)
160{
161 const struct firmware *fw;
162 char *fw_path = NULL;
163 int path_len, err;
164
165 if (prefix) {
166 path_len = strlen(prefix) + strlen(fw_name);
167 path_len += 2; /* for the path separator and zero terminator*/
168
169 fw_path = kzalloc(sizeof(*fw_path) * path_len, GFP_KERNEL);
170 if (!fw_path)
171 return NULL;
172
173 sprintf(fw_path, "%s/%s", prefix, fw_name);
174 fw_name = fw_path;
175 }
176
177#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
178 err = request_firmware(&fw, fw_name, dev);
179#else
180 if (flags & NVGPU_REQUEST_FIRMWARE_NO_WARN)
181 err = request_firmware_direct(&fw, fw_name, dev);
182 else
183 err = request_firmware(&fw, fw_name, dev);
184#endif
185
186 kfree(fw_path);
187 if (err)
188 return NULL;
189 return fw;
190}
191
192/* This is a simple wrapper around request_firmware that takes 'fw_name' and
193 * applies an IP specific relative path prefix to it. The caller is
194 * responsible for calling release_firmware later. */
195const struct firmware *nvgpu_request_firmware(struct gk20a *g,
196 const char *fw_name,
197 int flags)
198{
199 struct device *dev = g->dev;
200 const struct firmware *fw;
201
202 /* current->fs is NULL when calling from SYS_EXIT.
203 Add a check here to prevent crash in request_firmware */
204 if (!current->fs || !fw_name)
205 return NULL;
206
207 BUG_ON(!g->ops.name);
208 fw = do_request_firmware(dev, g->ops.name, fw_name, flags);
209
210#ifdef CONFIG_TEGRA_GK20A
211 /* TO BE REMOVED - Support loading from legacy SOC specific path. */
212 if (!fw && !(flags & NVGPU_REQUEST_FIRMWARE_NO_SOC)) {
213 struct gk20a_platform *platform = gk20a_get_platform(dev);
214 fw = do_request_firmware(dev,
215 platform->soc_name, fw_name, flags);
216 }
217#endif
218
219 return fw;
220}
221
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,
24 const char *interface_name, 24 const char *interface_name,
25 struct class *class); 25 struct class *class);
26 26
27#define NVGPU_REQUEST_FIRMWARE_NO_WARN BIT(0)
28#define NVGPU_REQUEST_FIRMWARE_NO_SOC BIT(1)
29
30const struct firmware *nvgpu_request_firmware(struct gk20a *g,
31 const char *fw_name,
32 int flags);
33
27#endif 34#endif