diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 57 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 8 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.c | 14 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/pmu_gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm206/acr_gm206.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm206/bios_gm206.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 18 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/nvgpu_common.c | 67 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/nvgpu_common.h | 7 |
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 | ||
2050 | static const struct firmware * | ||
2051 | do_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. */ | ||
2079 | const struct firmware * | ||
2080 | gk20a_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 | |||
2104 | int gk20a_read_ptimer(struct gk20a *g, u64 *value) | 2047 | int 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); | |||
1178 | int __gk20a_do_idle(struct device *dev, bool force_reset); | 1173 | int __gk20a_do_idle(struct device *dev, bool force_reset); |
1179 | int __gk20a_do_unidle(struct device *dev); | 1174 | int __gk20a_do_unidle(struct device *dev); |
1180 | 1175 | ||
1181 | const struct firmware * | ||
1182 | gk20a_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 | ||
28 | static int gr_gk20a_alloc_load_netlist_u32(u32 *src, u32 len, | 29 | static 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 | ||
2888 | static int gk20a_init_pmu_reset_enable_hw(struct gk20a *g) | 2891 | static 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 | ||
743 | int gk20a_init_pmu_support(struct gk20a *g); | 745 | 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 @@ | |||
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 | |||
158 | static 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. */ | ||
195 | const 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 | |||
30 | const struct firmware *nvgpu_request_firmware(struct gk20a *g, | ||
31 | const char *fw_name, | ||
32 | int flags); | ||
33 | |||
27 | #endif | 34 | #endif |