mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 09:57:08 +03:00
gpu: nvgpu: Add abstraction for firmware loading
Add nvgpu_firmware data structure, and return it instead of Linux struct firmare from nvgpu_request_firmware. Also add abstraction for releasing firmware: nvgpu_release_firmware. JIRA NVGPU-16 Change-Id: I6dae8262957c0d4506f710289e3a43a6c1729fc7 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1463538 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
7eb59ff8d3
commit
a9c66768db
@@ -36,6 +36,7 @@ nvgpu-y := \
|
|||||||
common/linux/dma.o \
|
common/linux/dma.o \
|
||||||
common/linux/soc.o \
|
common/linux/soc.o \
|
||||||
common/linux/driver_common.o \
|
common/linux/driver_common.o \
|
||||||
|
common/linux/firmware.o \
|
||||||
common/mm/nvgpu_allocator.o \
|
common/mm/nvgpu_allocator.o \
|
||||||
common/mm/bitmap_allocator.o \
|
common/mm/bitmap_allocator.o \
|
||||||
common/mm/buddy_allocator.o \
|
common/mm/buddy_allocator.o \
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
* more details.
|
* more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/firmware.h>
|
|
||||||
|
|
||||||
#include <nvgpu/kmem.h>
|
#include <nvgpu/kmem.h>
|
||||||
#include <nvgpu/nvgpu_common.h>
|
#include <nvgpu/nvgpu_common.h>
|
||||||
@@ -201,71 +200,6 @@ int nvgpu_probe(struct gk20a *g,
|
|||||||
return 0;
|
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 = nvgpu_kzalloc(get_gk20a(dev),
|
|
||||||
sizeof(*fw_path) * path_len);
|
|
||||||
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
|
|
||||||
|
|
||||||
nvgpu_kfree(get_gk20a(dev), 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->name);
|
|
||||||
fw = do_request_firmware(dev, g->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cyclic_delta - Returns delta of cyclic integers a and b.
|
* cyclic_delta - Returns delta of cyclic integers a and b.
|
||||||
*
|
*
|
||||||
|
|||||||
114
drivers/gpu/nvgpu/common/linux/firmware.c
Normal file
114
drivers/gpu/nvgpu/common/linux/firmware.c
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/firmware.h>
|
||||||
|
|
||||||
|
#include <nvgpu/kmem.h>
|
||||||
|
#include <nvgpu/bug.h>
|
||||||
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
|
#include "gk20a/gk20a.h"
|
||||||
|
|
||||||
|
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 = nvgpu_kzalloc(get_gk20a(dev),
|
||||||
|
sizeof(*fw_path) * path_len);
|
||||||
|
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
|
||||||
|
|
||||||
|
nvgpu_kfree(get_gk20a(dev), 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 nvgpu_release_firmware later. */
|
||||||
|
struct nvgpu_firmware *nvgpu_request_firmware(struct gk20a *g,
|
||||||
|
const char *fw_name,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
struct device *dev = g->dev;
|
||||||
|
struct nvgpu_firmware *fw;
|
||||||
|
const struct firmware *linux_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;
|
||||||
|
|
||||||
|
fw = nvgpu_kzalloc(g, sizeof(*fw));
|
||||||
|
if (!fw)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
linux_fw = do_request_firmware(dev, g->name, fw_name, flags);
|
||||||
|
|
||||||
|
#ifdef CONFIG_TEGRA_GK20A
|
||||||
|
/* TO BE REMOVED - Support loading from legacy SOC specific path. */
|
||||||
|
if (!linux_fw && !(flags & NVGPU_REQUEST_FIRMWARE_NO_SOC)) {
|
||||||
|
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||||
|
linux_fw = do_request_firmware(dev,
|
||||||
|
platform->soc_name, fw_name, flags);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!linux_fw)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
fw->data = nvgpu_kmalloc(g, linux_fw->size);
|
||||||
|
if (!fw->data)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
memcpy(fw->data, linux_fw->data, linux_fw->size);
|
||||||
|
fw->size = linux_fw->size;
|
||||||
|
|
||||||
|
release_firmware(linux_fw);
|
||||||
|
|
||||||
|
return fw;
|
||||||
|
|
||||||
|
err:
|
||||||
|
nvgpu_kfree(g, fw);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nvgpu_release_firmware(struct gk20a *g, struct nvgpu_firmware *fw)
|
||||||
|
{
|
||||||
|
nvgpu_kfree(g, fw->data);
|
||||||
|
nvgpu_kfree(g, fw);
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/firmware.h>
|
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/dma-buf.h>
|
#include <linux/dma-buf.h>
|
||||||
@@ -30,6 +29,7 @@
|
|||||||
#include <nvgpu/kmem.h>
|
#include <nvgpu/kmem.h>
|
||||||
#include <nvgpu/log.h>
|
#include <nvgpu/log.h>
|
||||||
#include <nvgpu/bug.h>
|
#include <nvgpu/bug.h>
|
||||||
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
#include "gk20a.h"
|
#include "gk20a.h"
|
||||||
#include "channel_gk20a.h"
|
#include "channel_gk20a.h"
|
||||||
@@ -226,7 +226,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gk20a_init_cde_buf(struct gk20a_cde_ctx *cde_ctx,
|
static int gk20a_init_cde_buf(struct gk20a_cde_ctx *cde_ctx,
|
||||||
const struct firmware *img,
|
struct nvgpu_firmware *img,
|
||||||
struct gk20a_cde_hdr_buf *buf)
|
struct gk20a_cde_hdr_buf *buf)
|
||||||
{
|
{
|
||||||
struct nvgpu_mem *mem;
|
struct nvgpu_mem *mem;
|
||||||
@@ -314,7 +314,7 @@ static int gk20a_replace_data(struct gk20a_cde_ctx *cde_ctx, void *target,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gk20a_init_cde_replace(struct gk20a_cde_ctx *cde_ctx,
|
static int gk20a_init_cde_replace(struct gk20a_cde_ctx *cde_ctx,
|
||||||
const struct firmware *img,
|
struct nvgpu_firmware *img,
|
||||||
struct gk20a_cde_hdr_replace *replace)
|
struct gk20a_cde_hdr_replace *replace)
|
||||||
{
|
{
|
||||||
struct nvgpu_mem *source_mem;
|
struct nvgpu_mem *source_mem;
|
||||||
@@ -454,7 +454,7 @@ static int gk20a_cde_patch_params(struct gk20a_cde_ctx *cde_ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gk20a_init_cde_param(struct gk20a_cde_ctx *cde_ctx,
|
static int gk20a_init_cde_param(struct gk20a_cde_ctx *cde_ctx,
|
||||||
const struct firmware *img,
|
struct nvgpu_firmware *img,
|
||||||
struct gk20a_cde_hdr_param *param)
|
struct gk20a_cde_hdr_param *param)
|
||||||
{
|
{
|
||||||
struct nvgpu_mem *target_mem;
|
struct nvgpu_mem *target_mem;
|
||||||
@@ -497,7 +497,7 @@ static int gk20a_init_cde_param(struct gk20a_cde_ctx *cde_ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gk20a_init_cde_required_class(struct gk20a_cde_ctx *cde_ctx,
|
static int gk20a_init_cde_required_class(struct gk20a_cde_ctx *cde_ctx,
|
||||||
const struct firmware *img,
|
struct nvgpu_firmware *img,
|
||||||
u32 required_class)
|
u32 required_class)
|
||||||
{
|
{
|
||||||
struct gk20a *g = cde_ctx->g;
|
struct gk20a *g = cde_ctx->g;
|
||||||
@@ -521,7 +521,7 @@ static int gk20a_init_cde_required_class(struct gk20a_cde_ctx *cde_ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gk20a_init_cde_command(struct gk20a_cde_ctx *cde_ctx,
|
static int gk20a_init_cde_command(struct gk20a_cde_ctx *cde_ctx,
|
||||||
const struct firmware *img,
|
struct nvgpu_firmware *img,
|
||||||
u32 op,
|
u32 op,
|
||||||
struct gk20a_cde_cmd_elem *cmd_elem,
|
struct gk20a_cde_cmd_elem *cmd_elem,
|
||||||
u32 num_elems)
|
u32 num_elems)
|
||||||
@@ -622,7 +622,7 @@ static int gk20a_cde_pack_cmdbufs(struct gk20a_cde_ctx *cde_ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gk20a_init_cde_img(struct gk20a_cde_ctx *cde_ctx,
|
static int gk20a_init_cde_img(struct gk20a_cde_ctx *cde_ctx,
|
||||||
const struct firmware *img)
|
struct nvgpu_firmware *img)
|
||||||
{
|
{
|
||||||
struct gk20a *g = cde_ctx->g;
|
struct gk20a *g = cde_ctx->g;
|
||||||
struct gk20a_cde_app *cde_app = &cde_ctx->g->cde_app;
|
struct gk20a_cde_app *cde_app = &cde_ctx->g->cde_app;
|
||||||
@@ -1202,7 +1202,7 @@ __releases(&cde_app->mutex)
|
|||||||
static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx)
|
static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx)
|
||||||
{
|
{
|
||||||
struct gk20a *g = cde_ctx->g;
|
struct gk20a *g = cde_ctx->g;
|
||||||
const struct firmware *img;
|
struct nvgpu_firmware *img;
|
||||||
struct channel_gk20a *ch;
|
struct channel_gk20a *ch;
|
||||||
struct gr_gk20a *gr = &g->gr;
|
struct gr_gk20a *gr = &g->gr;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@@ -1265,7 +1265,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* initialisation done */
|
/* initialisation done */
|
||||||
release_firmware(img);
|
nvgpu_release_firmware(g, img);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -1276,7 +1276,7 @@ err_alloc_gpfifo:
|
|||||||
gk20a_vm_put(ch->vm);
|
gk20a_vm_put(ch->vm);
|
||||||
err_commit_va:
|
err_commit_va:
|
||||||
err_get_gk20a_channel:
|
err_get_gk20a_channel:
|
||||||
release_firmware(img);
|
nvgpu_release_firmware(g, img);
|
||||||
nvgpu_err(g, "cde: couldn't initialise buffer converter: %d", err);
|
nvgpu_err(g, "cde: couldn't initialise buffer converter: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,10 @@
|
|||||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
|
||||||
|
|
||||||
#include <nvgpu/nvgpu_common.h>
|
#include <nvgpu/nvgpu_common.h>
|
||||||
#include <nvgpu/kmem.h>
|
#include <nvgpu/kmem.h>
|
||||||
#include <nvgpu/log.h>
|
#include <nvgpu/log.h>
|
||||||
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
#include "gk20a.h"
|
#include "gk20a.h"
|
||||||
#include "gr_ctx_gk20a.h"
|
#include "gr_ctx_gk20a.h"
|
||||||
@@ -112,7 +111,7 @@ static bool gr_gk20a_is_firmware_defined(void)
|
|||||||
|
|
||||||
static int gr_gk20a_init_ctx_vars_fw(struct gk20a *g, struct gr_gk20a *gr)
|
static int gr_gk20a_init_ctx_vars_fw(struct gk20a *g, struct gr_gk20a *gr)
|
||||||
{
|
{
|
||||||
const struct firmware *netlist_fw;
|
struct nvgpu_firmware *netlist_fw;
|
||||||
struct netlist_image *netlist = NULL;
|
struct netlist_image *netlist = NULL;
|
||||||
char name[MAX_NETLIST_NAME];
|
char name[MAX_NETLIST_NAME];
|
||||||
u32 i, major_v = ~0, major_v_hw, netlist_num;
|
u32 i, major_v = ~0, major_v_hw, netlist_num;
|
||||||
@@ -392,7 +391,7 @@ static int gr_gk20a_init_ctx_vars_fw(struct gk20a *g, struct gr_gk20a *gr)
|
|||||||
g->gr.ctx_vars.valid = true;
|
g->gr.ctx_vars.valid = true;
|
||||||
g->gr.netlist = net;
|
g->gr.netlist = net;
|
||||||
|
|
||||||
release_firmware(netlist_fw);
|
nvgpu_release_firmware(g, netlist_fw);
|
||||||
gk20a_dbg_fn("done");
|
gk20a_dbg_fn("done");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -427,7 +426,7 @@ clean_up:
|
|||||||
nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.perf_pma.l);
|
nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.perf_pma.l);
|
||||||
nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_rop.l);
|
nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_rop.l);
|
||||||
nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_ucgpc.l);
|
nvgpu_kfree(g, g->gr.ctx_vars.ctxsw_regs.pm_ucgpc.l);
|
||||||
release_firmware(netlist_fw);
|
nvgpu_release_firmware(g, netlist_fw);
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
|
||||||
#include <trace/events/gk20a.h>
|
#include <trace/events/gk20a.h>
|
||||||
|
|
||||||
#include <nvgpu/dma.h>
|
#include <nvgpu/dma.h>
|
||||||
@@ -28,6 +27,7 @@
|
|||||||
#include <nvgpu/bsearch.h>
|
#include <nvgpu/bsearch.h>
|
||||||
#include <nvgpu/sort.h>
|
#include <nvgpu/sort.h>
|
||||||
#include <nvgpu/bug.h>
|
#include <nvgpu/bug.h>
|
||||||
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
#include "gk20a.h"
|
#include "gk20a.h"
|
||||||
#include "kind_gk20a.h"
|
#include "kind_gk20a.h"
|
||||||
@@ -2272,8 +2272,8 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
|
|||||||
struct vm_gk20a *vm = &mm->pmu.vm;
|
struct vm_gk20a *vm = &mm->pmu.vm;
|
||||||
struct gk20a_ctxsw_bootloader_desc *fecs_boot_desc;
|
struct gk20a_ctxsw_bootloader_desc *fecs_boot_desc;
|
||||||
struct gk20a_ctxsw_bootloader_desc *gpccs_boot_desc;
|
struct gk20a_ctxsw_bootloader_desc *gpccs_boot_desc;
|
||||||
const struct firmware *fecs_fw;
|
struct nvgpu_firmware *fecs_fw;
|
||||||
const struct firmware *gpccs_fw;
|
struct nvgpu_firmware *gpccs_fw;
|
||||||
u32 *fecs_boot_image;
|
u32 *fecs_boot_image;
|
||||||
u32 *gpccs_boot_image;
|
u32 *gpccs_boot_image;
|
||||||
struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info;
|
struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info;
|
||||||
@@ -2292,7 +2292,7 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
|
|||||||
|
|
||||||
gpccs_fw = nvgpu_request_firmware(g, GK20A_GPCCS_UCODE_IMAGE, 0);
|
gpccs_fw = nvgpu_request_firmware(g, GK20A_GPCCS_UCODE_IMAGE, 0);
|
||||||
if (!gpccs_fw) {
|
if (!gpccs_fw) {
|
||||||
release_firmware(fecs_fw);
|
nvgpu_release_firmware(g, fecs_fw);
|
||||||
nvgpu_err(g, "failed to load gpccs ucode!!");
|
nvgpu_err(g, "failed to load gpccs ucode!!");
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@@ -2321,7 +2321,7 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
|
|||||||
g->gr.ctx_vars.ucode.fecs.inst.l,
|
g->gr.ctx_vars.ucode.fecs.inst.l,
|
||||||
g->gr.ctx_vars.ucode.fecs.data.l);
|
g->gr.ctx_vars.ucode.fecs.data.l);
|
||||||
|
|
||||||
release_firmware(fecs_fw);
|
nvgpu_release_firmware(g, fecs_fw);
|
||||||
fecs_fw = NULL;
|
fecs_fw = NULL;
|
||||||
|
|
||||||
gr_gk20a_copy_ctxsw_ucode_segments(g, &ucode_info->surface_desc,
|
gr_gk20a_copy_ctxsw_ucode_segments(g, &ucode_info->surface_desc,
|
||||||
@@ -2330,7 +2330,7 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
|
|||||||
g->gr.ctx_vars.ucode.gpccs.inst.l,
|
g->gr.ctx_vars.ucode.gpccs.inst.l,
|
||||||
g->gr.ctx_vars.ucode.gpccs.data.l);
|
g->gr.ctx_vars.ucode.gpccs.data.l);
|
||||||
|
|
||||||
release_firmware(gpccs_fw);
|
nvgpu_release_firmware(g, gpccs_fw);
|
||||||
gpccs_fw = NULL;
|
gpccs_fw = NULL;
|
||||||
|
|
||||||
err = gr_gk20a_init_ctxsw_ucode_vaspace(g);
|
err = gr_gk20a_init_ctxsw_ucode_vaspace(g);
|
||||||
@@ -2345,9 +2345,9 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
|
|||||||
ucode_info->surface_desc.size, gk20a_mem_flag_none);
|
ucode_info->surface_desc.size, gk20a_mem_flag_none);
|
||||||
nvgpu_dma_free(g, &ucode_info->surface_desc);
|
nvgpu_dma_free(g, &ucode_info->surface_desc);
|
||||||
|
|
||||||
release_firmware(gpccs_fw);
|
nvgpu_release_firmware(g, gpccs_fw);
|
||||||
gpccs_fw = NULL;
|
gpccs_fw = NULL;
|
||||||
release_firmware(fecs_fw);
|
nvgpu_release_firmware(g, fecs_fw);
|
||||||
fecs_fw = NULL;
|
fecs_fw = NULL;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
@@ -27,6 +26,7 @@
|
|||||||
#include <nvgpu/dma.h>
|
#include <nvgpu/dma.h>
|
||||||
#include <nvgpu/log.h>
|
#include <nvgpu/log.h>
|
||||||
#include <nvgpu/bug.h>
|
#include <nvgpu/bug.h>
|
||||||
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
#include "gk20a.h"
|
#include "gk20a.h"
|
||||||
#include "gr_gk20a.h"
|
#include "gr_gk20a.h"
|
||||||
@@ -3099,12 +3099,14 @@ static int pmu_queue_close(struct pmu_gk20a *pmu,
|
|||||||
|
|
||||||
void gk20a_remove_pmu_support(struct pmu_gk20a *pmu)
|
void gk20a_remove_pmu_support(struct pmu_gk20a *pmu)
|
||||||
{
|
{
|
||||||
|
struct gk20a *g = gk20a_from_pmu(pmu);
|
||||||
|
|
||||||
gk20a_dbg_fn("");
|
gk20a_dbg_fn("");
|
||||||
|
|
||||||
if (nvgpu_alloc_initialized(&pmu->dmem))
|
if (nvgpu_alloc_initialized(&pmu->dmem))
|
||||||
nvgpu_alloc_destroy(&pmu->dmem);
|
nvgpu_alloc_destroy(&pmu->dmem);
|
||||||
|
|
||||||
release_firmware(pmu->fw);
|
nvgpu_release_firmware(g, pmu->fw);
|
||||||
|
|
||||||
nvgpu_mutex_destroy(&pmu->elpg_mutex);
|
nvgpu_mutex_destroy(&pmu->elpg_mutex);
|
||||||
nvgpu_mutex_destroy(&pmu->pg_mutex);
|
nvgpu_mutex_destroy(&pmu->pg_mutex);
|
||||||
@@ -3157,7 +3159,7 @@ static int gk20a_prepare_ucode(struct gk20a *g)
|
|||||||
return gk20a_init_pmu(pmu);
|
return gk20a_init_pmu(pmu);
|
||||||
|
|
||||||
err_release_fw:
|
err_release_fw:
|
||||||
release_firmware(pmu->fw);
|
nvgpu_release_firmware(g, pmu->fw);
|
||||||
pmu->fw = NULL;
|
pmu->fw = NULL;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#include <nvgpu/flcnif_cmn.h>
|
#include <nvgpu/flcnif_cmn.h>
|
||||||
#include <nvgpu/pmuif/nvgpu_gpmu_cmdif.h>
|
#include <nvgpu/pmuif/nvgpu_gpmu_cmdif.h>
|
||||||
|
|
||||||
|
struct nvgpu_firmware;
|
||||||
|
|
||||||
/* defined by pmu hw spec */
|
/* defined by pmu hw spec */
|
||||||
#define GK20A_PMU_VA_SIZE (512 * 1024 * 1024)
|
#define GK20A_PMU_VA_SIZE (512 * 1024 * 1024)
|
||||||
#define GK20A_PMU_UCODE_SIZE_MAX (256 * 1024)
|
#define GK20A_PMU_UCODE_SIZE_MAX (256 * 1024)
|
||||||
@@ -394,7 +396,7 @@ struct pmu_gk20a {
|
|||||||
u32 aelpg_param[5];
|
u32 aelpg_param[5];
|
||||||
u32 override_done;
|
u32 override_done;
|
||||||
|
|
||||||
const struct firmware *fw;
|
struct nvgpu_firmware *fw;
|
||||||
};
|
};
|
||||||
|
|
||||||
int gk20a_init_pmu_support(struct gk20a *g);
|
int gk20a_init_pmu_support(struct gk20a *g);
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
* more details.
|
* more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
|
|
||||||
#include <nvgpu/bios.h>
|
#include <nvgpu/bios.h>
|
||||||
#include <nvgpu/kmem.h>
|
#include <nvgpu/kmem.h>
|
||||||
#include <nvgpu/nvgpu_common.h>
|
#include <nvgpu/nvgpu_common.h>
|
||||||
#include <nvgpu/timers.h>
|
#include <nvgpu/timers.h>
|
||||||
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
#include "gk20a/gk20a.h"
|
#include "gk20a/gk20a.h"
|
||||||
#include "gm20b/fifo_gm20b.h"
|
#include "gm20b/fifo_gm20b.h"
|
||||||
@@ -249,7 +249,7 @@ int gm206_bios_init(struct gk20a *g)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct gk20a_platform *platform = dev_get_drvdata(g->dev);
|
struct gk20a_platform *platform = dev_get_drvdata(g->dev);
|
||||||
struct dentry *d;
|
struct dentry *d;
|
||||||
const struct firmware *bios_fw;
|
struct nvgpu_firmware *bios_fw;
|
||||||
int err;
|
int err;
|
||||||
struct pci_dev *pdev = to_pci_dev(g->dev);
|
struct pci_dev *pdev = to_pci_dev(g->dev);
|
||||||
char rom_name[sizeof(BIOS_OVERLAY_NAME_FORMATTED)];
|
char rom_name[sizeof(BIOS_OVERLAY_NAME_FORMATTED)];
|
||||||
@@ -273,7 +273,7 @@ int gm206_bios_init(struct gk20a *g)
|
|||||||
memcpy(g->bios.data, &bios_fw->data[ROM_FILE_PAYLOAD_OFFSET],
|
memcpy(g->bios.data, &bios_fw->data[ROM_FILE_PAYLOAD_OFFSET],
|
||||||
g->bios.size);
|
g->bios.size);
|
||||||
|
|
||||||
release_firmware(bios_fw);
|
nvgpu_release_firmware(g, bios_fw);
|
||||||
} else {
|
} else {
|
||||||
gk20a_dbg_info("reading bios from EEPROM");
|
gk20a_dbg_info("reading bios from EEPROM");
|
||||||
g->bios.size = BIOS_SIZE;
|
g->bios.size = BIOS_SIZE;
|
||||||
@@ -336,7 +336,7 @@ int gm206_bios_init(struct gk20a *g)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_firmware:
|
free_firmware:
|
||||||
release_firmware(bios_fw);
|
nvgpu_release_firmware(g, bios_fw);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
* more details.
|
* more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
|
||||||
#include <linux/platform/tegra/mc.h>
|
#include <linux/platform/tegra/mc.h>
|
||||||
@@ -21,6 +20,7 @@
|
|||||||
#include <nvgpu/nvgpu_common.h>
|
#include <nvgpu/nvgpu_common.h>
|
||||||
#include <nvgpu/kmem.h>
|
#include <nvgpu/kmem.h>
|
||||||
#include <nvgpu/acr/nvgpu_acr.h>
|
#include <nvgpu/acr/nvgpu_acr.h>
|
||||||
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
#include "gk20a/gk20a.h"
|
#include "gk20a/gk20a.h"
|
||||||
#include "gk20a/pmu_gk20a.h"
|
#include "gk20a/pmu_gk20a.h"
|
||||||
@@ -123,7 +123,7 @@ void gm20b_init_secure_pmu(struct gpu_ops *gops)
|
|||||||
|
|
||||||
static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
||||||
{
|
{
|
||||||
const struct firmware *pmu_fw, *pmu_desc, *pmu_sig;
|
struct nvgpu_firmware *pmu_fw, *pmu_desc, *pmu_sig;
|
||||||
struct pmu_gk20a *pmu = &g->pmu;
|
struct pmu_gk20a *pmu = &g->pmu;
|
||||||
struct lsf_ucode_desc *lsf_desc;
|
struct lsf_ucode_desc *lsf_desc;
|
||||||
int err;
|
int err;
|
||||||
@@ -174,21 +174,21 @@ static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
|||||||
p_img->header = NULL;
|
p_img->header = NULL;
|
||||||
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
||||||
gm20b_dbg_pmu("requesting PMU ucode in GM20B exit\n");
|
gm20b_dbg_pmu("requesting PMU ucode in GM20B exit\n");
|
||||||
release_firmware(pmu_sig);
|
nvgpu_release_firmware(g, pmu_sig);
|
||||||
return 0;
|
return 0;
|
||||||
release_sig:
|
release_sig:
|
||||||
release_firmware(pmu_sig);
|
nvgpu_release_firmware(g, pmu_sig);
|
||||||
release_desc:
|
release_desc:
|
||||||
release_firmware(pmu_desc);
|
nvgpu_release_firmware(g, pmu_desc);
|
||||||
release_img_fw:
|
release_img_fw:
|
||||||
release_firmware(pmu_fw);
|
nvgpu_release_firmware(g, pmu_fw);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
||||||
{
|
{
|
||||||
struct lsf_ucode_desc *lsf_desc;
|
struct lsf_ucode_desc *lsf_desc;
|
||||||
const struct firmware *fecs_sig;
|
struct nvgpu_firmware *fecs_sig;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
fecs_sig = nvgpu_request_firmware(g, GM20B_FECS_UCODE_SIG, 0);
|
fecs_sig = nvgpu_request_firmware(g, GM20B_FECS_UCODE_SIG, 0);
|
||||||
@@ -244,18 +244,18 @@ static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
|||||||
p_img->header = NULL;
|
p_img->header = NULL;
|
||||||
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
||||||
gm20b_dbg_pmu("fecs fw loaded\n");
|
gm20b_dbg_pmu("fecs fw loaded\n");
|
||||||
release_firmware(fecs_sig);
|
nvgpu_release_firmware(g, fecs_sig);
|
||||||
return 0;
|
return 0;
|
||||||
free_lsf_desc:
|
free_lsf_desc:
|
||||||
nvgpu_kfree(g, lsf_desc);
|
nvgpu_kfree(g, lsf_desc);
|
||||||
rel_sig:
|
rel_sig:
|
||||||
release_firmware(fecs_sig);
|
nvgpu_release_firmware(g, fecs_sig);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
||||||
{
|
{
|
||||||
struct lsf_ucode_desc *lsf_desc;
|
struct lsf_ucode_desc *lsf_desc;
|
||||||
const struct firmware *gpccs_sig;
|
struct nvgpu_firmware *gpccs_sig;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (g->ops.securegpccs == false)
|
if (g->ops.securegpccs == false)
|
||||||
@@ -315,12 +315,12 @@ static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img)
|
|||||||
p_img->header = NULL;
|
p_img->header = NULL;
|
||||||
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc;
|
||||||
gm20b_dbg_pmu("gpccs fw loaded\n");
|
gm20b_dbg_pmu("gpccs fw loaded\n");
|
||||||
release_firmware(gpccs_sig);
|
nvgpu_release_firmware(g, gpccs_sig);
|
||||||
return 0;
|
return 0;
|
||||||
free_lsf_desc:
|
free_lsf_desc:
|
||||||
nvgpu_kfree(g, lsf_desc);
|
nvgpu_kfree(g, lsf_desc);
|
||||||
rel_sig:
|
rel_sig:
|
||||||
release_firmware(gpccs_sig);
|
nvgpu_release_firmware(g, gpccs_sig);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1070,7 +1070,7 @@ static int gm20b_bootstrap_hs_flcn(struct gk20a *g)
|
|||||||
u32 status, size;
|
u32 status, size;
|
||||||
u64 start;
|
u64 start;
|
||||||
struct acr_desc *acr = &g->acr;
|
struct acr_desc *acr = &g->acr;
|
||||||
const struct firmware *acr_fw = acr->acr_fw;
|
struct nvgpu_firmware *acr_fw = acr->acr_fw;
|
||||||
struct flcn_bl_dmem_desc *bl_dmem_desc = &acr->bl_dmem_desc;
|
struct flcn_bl_dmem_desc *bl_dmem_desc = &acr->bl_dmem_desc;
|
||||||
u32 *acr_ucode_header_t210_load;
|
u32 *acr_ucode_header_t210_load;
|
||||||
u32 *acr_ucode_data_t210_load;
|
u32 *acr_ucode_data_t210_load;
|
||||||
@@ -1169,7 +1169,7 @@ static int gm20b_bootstrap_hs_flcn(struct gk20a *g)
|
|||||||
err_free_ucode_map:
|
err_free_ucode_map:
|
||||||
nvgpu_dma_unmap_free(vm, &acr->acr_ucode);
|
nvgpu_dma_unmap_free(vm, &acr->acr_ucode);
|
||||||
err_release_acr_fw:
|
err_release_acr_fw:
|
||||||
release_firmware(acr_fw);
|
nvgpu_release_firmware(g, acr_fw);
|
||||||
acr->acr_fw = NULL;
|
acr->acr_fw = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1385,7 +1385,7 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
u32 bl_sz;
|
u32 bl_sz;
|
||||||
struct acr_desc *acr = &g->acr;
|
struct acr_desc *acr = &g->acr;
|
||||||
const struct firmware *hsbl_fw = acr->hsbl_fw;
|
struct nvgpu_firmware *hsbl_fw = acr->hsbl_fw;
|
||||||
struct hsflcn_bl_desc *pmu_bl_gm10x_desc;
|
struct hsflcn_bl_desc *pmu_bl_gm10x_desc;
|
||||||
u32 *pmu_bl_gm10x = NULL;
|
u32 *pmu_bl_gm10x = NULL;
|
||||||
gm20b_dbg_pmu("");
|
gm20b_dbg_pmu("");
|
||||||
@@ -1472,7 +1472,7 @@ err_unmap_bl:
|
|||||||
err_free_ucode:
|
err_free_ucode:
|
||||||
nvgpu_dma_free(g, &acr->hsbl_ucode);
|
nvgpu_dma_free(g, &acr->hsbl_ucode);
|
||||||
err_done:
|
err_done:
|
||||||
release_firmware(hsbl_fw);
|
nvgpu_release_firmware(g, hsbl_fw);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
* more details.
|
* more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/firmware.h>
|
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
|
|
||||||
#include <nvgpu/nvgpu_common.h>
|
#include <nvgpu/nvgpu_common.h>
|
||||||
#include <nvgpu/kmem.h>
|
#include <nvgpu/kmem.h>
|
||||||
#include <nvgpu/dma.h>
|
#include <nvgpu/dma.h>
|
||||||
#include <nvgpu/acr/nvgpu_acr.h>
|
#include <nvgpu/acr/nvgpu_acr.h>
|
||||||
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
#include "gk20a/gk20a.h"
|
#include "gk20a/gk20a.h"
|
||||||
#include "gk20a/pmu_gk20a.h"
|
#include "gk20a/pmu_gk20a.h"
|
||||||
@@ -137,7 +137,7 @@ void gp106_init_secure_pmu(struct gpu_ops *gops)
|
|||||||
|
|
||||||
static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img_v1 *p_img)
|
static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img_v1 *p_img)
|
||||||
{
|
{
|
||||||
const struct firmware *pmu_fw, *pmu_desc, *pmu_sig;
|
struct nvgpu_firmware *pmu_fw, *pmu_desc, *pmu_sig;
|
||||||
struct pmu_gk20a *pmu = &g->pmu;
|
struct pmu_gk20a *pmu = &g->pmu;
|
||||||
struct lsf_ucode_desc_v1 *lsf_desc;
|
struct lsf_ucode_desc_v1 *lsf_desc;
|
||||||
int err;
|
int err;
|
||||||
@@ -194,14 +194,14 @@ static int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img_v1 *p_img)
|
|||||||
p_img->lsf_desc = (struct lsf_ucode_desc_v1 *)lsf_desc;
|
p_img->lsf_desc = (struct lsf_ucode_desc_v1 *)lsf_desc;
|
||||||
gp106_dbg_pmu("requesting PMU ucode in GM20B exit\n");
|
gp106_dbg_pmu("requesting PMU ucode in GM20B exit\n");
|
||||||
|
|
||||||
release_firmware(pmu_sig);
|
nvgpu_release_firmware(g, pmu_sig);
|
||||||
return 0;
|
return 0;
|
||||||
release_sig:
|
release_sig:
|
||||||
release_firmware(pmu_sig);
|
nvgpu_release_firmware(g, pmu_sig);
|
||||||
release_desc:
|
release_desc:
|
||||||
release_firmware(pmu_desc);
|
nvgpu_release_firmware(g, pmu_desc);
|
||||||
release_img_fw:
|
release_img_fw:
|
||||||
release_firmware(pmu_fw);
|
nvgpu_release_firmware(g, pmu_fw);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img_v1 *p_img)
|
|||||||
{
|
{
|
||||||
u32 ver = g->gpu_characteristics.arch + g->gpu_characteristics.impl;
|
u32 ver = g->gpu_characteristics.arch + g->gpu_characteristics.impl;
|
||||||
struct lsf_ucode_desc_v1 *lsf_desc;
|
struct lsf_ucode_desc_v1 *lsf_desc;
|
||||||
const struct firmware *fecs_sig = NULL;
|
struct nvgpu_firmware *fecs_sig = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
switch (ver) {
|
switch (ver) {
|
||||||
@@ -279,12 +279,12 @@ static int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img_v1 *p_img)
|
|||||||
p_img->header = NULL;
|
p_img->header = NULL;
|
||||||
p_img->lsf_desc = (struct lsf_ucode_desc_v1 *)lsf_desc;
|
p_img->lsf_desc = (struct lsf_ucode_desc_v1 *)lsf_desc;
|
||||||
gp106_dbg_pmu("fecs fw loaded\n");
|
gp106_dbg_pmu("fecs fw loaded\n");
|
||||||
release_firmware(fecs_sig);
|
nvgpu_release_firmware(g, fecs_sig);
|
||||||
return 0;
|
return 0;
|
||||||
free_lsf_desc:
|
free_lsf_desc:
|
||||||
nvgpu_kfree(g, lsf_desc);
|
nvgpu_kfree(g, lsf_desc);
|
||||||
rel_sig:
|
rel_sig:
|
||||||
release_firmware(fecs_sig);
|
nvgpu_release_firmware(g, fecs_sig);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img_v1 *p_img)
|
|||||||
{
|
{
|
||||||
u32 ver = g->gpu_characteristics.arch + g->gpu_characteristics.impl;
|
u32 ver = g->gpu_characteristics.arch + g->gpu_characteristics.impl;
|
||||||
struct lsf_ucode_desc_v1 *lsf_desc;
|
struct lsf_ucode_desc_v1 *lsf_desc;
|
||||||
const struct firmware *gpccs_sig = NULL;
|
struct nvgpu_firmware *gpccs_sig = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (g->ops.securegpccs == false)
|
if (g->ops.securegpccs == false)
|
||||||
@@ -366,12 +366,12 @@ static int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img_v1 *p_img)
|
|||||||
p_img->header = NULL;
|
p_img->header = NULL;
|
||||||
p_img->lsf_desc = (struct lsf_ucode_desc_v1 *)lsf_desc;
|
p_img->lsf_desc = (struct lsf_ucode_desc_v1 *)lsf_desc;
|
||||||
gp106_dbg_pmu("gpccs fw loaded\n");
|
gp106_dbg_pmu("gpccs fw loaded\n");
|
||||||
release_firmware(gpccs_sig);
|
nvgpu_release_firmware(g, gpccs_sig);
|
||||||
return 0;
|
return 0;
|
||||||
free_lsf_desc:
|
free_lsf_desc:
|
||||||
nvgpu_kfree(g, lsf_desc);
|
nvgpu_kfree(g, lsf_desc);
|
||||||
rel_sig:
|
rel_sig:
|
||||||
release_firmware(gpccs_sig);
|
nvgpu_release_firmware(g, gpccs_sig);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1048,7 +1048,7 @@ static int gp106_bootstrap_hs_flcn(struct gk20a *g)
|
|||||||
u32 img_size_in_bytes = 0;
|
u32 img_size_in_bytes = 0;
|
||||||
u32 status;
|
u32 status;
|
||||||
struct acr_desc *acr = &g->acr;
|
struct acr_desc *acr = &g->acr;
|
||||||
const struct firmware *acr_fw = acr->acr_fw;
|
struct nvgpu_firmware *acr_fw = acr->acr_fw;
|
||||||
struct flcn_bl_dmem_desc_v1 *bl_dmem_desc = &acr->bl_dmem_desc_v1;
|
struct flcn_bl_dmem_desc_v1 *bl_dmem_desc = &acr->bl_dmem_desc_v1;
|
||||||
u32 *acr_ucode_header_t210_load;
|
u32 *acr_ucode_header_t210_load;
|
||||||
u32 *acr_ucode_data_t210_load;
|
u32 *acr_ucode_data_t210_load;
|
||||||
@@ -1167,7 +1167,7 @@ static int gp106_bootstrap_hs_flcn(struct gk20a *g)
|
|||||||
err_free_ucode_map:
|
err_free_ucode_map:
|
||||||
nvgpu_dma_unmap_free(vm, &acr->acr_ucode);
|
nvgpu_dma_unmap_free(vm, &acr->acr_ucode);
|
||||||
err_release_acr_fw:
|
err_release_acr_fw:
|
||||||
release_firmware(acr_fw);
|
nvgpu_release_firmware(g, acr_fw);
|
||||||
acr->acr_fw = NULL;
|
acr->acr_fw = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#include "acr_objlsfm.h"
|
#include "acr_objlsfm.h"
|
||||||
#include "acr_objflcn.h"
|
#include "acr_objflcn.h"
|
||||||
|
|
||||||
|
struct nvgpu_firmware;
|
||||||
|
|
||||||
#define MAX_SUPPORTED_LSFM 3 /*PMU, FECS, GPCCS*/
|
#define MAX_SUPPORTED_LSFM 3 /*PMU, FECS, GPCCS*/
|
||||||
|
|
||||||
#define ACR_COMPLETION_TIMEOUT_MS 10000 /*in msec */
|
#define ACR_COMPLETION_TIMEOUT_MS 10000 /*in msec */
|
||||||
@@ -74,20 +76,20 @@ struct acr_desc {
|
|||||||
struct bin_hdr *hsbin_hdr;
|
struct bin_hdr *hsbin_hdr;
|
||||||
struct acr_fw_header *fw_hdr;
|
struct acr_fw_header *fw_hdr;
|
||||||
u32 pmu_args;
|
u32 pmu_args;
|
||||||
const struct firmware *acr_fw;
|
struct nvgpu_firmware *acr_fw;
|
||||||
union{
|
union{
|
||||||
struct flcn_acr_desc *acr_dmem_desc;
|
struct flcn_acr_desc *acr_dmem_desc;
|
||||||
struct flcn_acr_desc_v1 *acr_dmem_desc_v1;
|
struct flcn_acr_desc_v1 *acr_dmem_desc_v1;
|
||||||
};
|
};
|
||||||
struct nvgpu_mem acr_ucode;
|
struct nvgpu_mem acr_ucode;
|
||||||
const struct firmware *hsbl_fw;
|
struct nvgpu_firmware *hsbl_fw;
|
||||||
struct nvgpu_mem hsbl_ucode;
|
struct nvgpu_mem hsbl_ucode;
|
||||||
union {
|
union {
|
||||||
struct flcn_bl_dmem_desc bl_dmem_desc;
|
struct flcn_bl_dmem_desc bl_dmem_desc;
|
||||||
struct flcn_bl_dmem_desc_v1 bl_dmem_desc_v1;
|
struct flcn_bl_dmem_desc_v1 bl_dmem_desc_v1;
|
||||||
};
|
};
|
||||||
const struct firmware *pmu_fw;
|
struct nvgpu_firmware *pmu_fw;
|
||||||
const struct firmware *pmu_desc;
|
struct nvgpu_firmware *pmu_desc;
|
||||||
u32 capabilities;
|
u32 capabilities;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
66
drivers/gpu/nvgpu/include/nvgpu/firmware.h
Normal file
66
drivers/gpu/nvgpu/include/nvgpu/firmware.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NVGPU_FIRMWARE_H_
|
||||||
|
#define _NVGPU_FIRMWARE_H_
|
||||||
|
|
||||||
|
struct gk20a;
|
||||||
|
|
||||||
|
#define NVGPU_REQUEST_FIRMWARE_NO_WARN (1UL << 0)
|
||||||
|
#define NVGPU_REQUEST_FIRMWARE_NO_SOC (1UL << 1)
|
||||||
|
|
||||||
|
struct nvgpu_firmware {
|
||||||
|
u8 *data;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nvgpu_request_firmware - load a firmware blob from filesystem.
|
||||||
|
*
|
||||||
|
* @g The GPU driver struct for device to load firmware for
|
||||||
|
* @fw_name The base name of the firmware file.
|
||||||
|
* @flags Flags for loading;
|
||||||
|
*
|
||||||
|
* NVGPU_REQUEST_FIRMWARE_NO_WARN: Do not display warning on
|
||||||
|
* failed load.
|
||||||
|
*
|
||||||
|
* NVGPU_REQUEST_FIRMWARE_NO_SOC: Do not attempt loading from
|
||||||
|
* path <SOC_NAME>.
|
||||||
|
*
|
||||||
|
* nvgpu_request_firmware() will load firmware from:
|
||||||
|
*
|
||||||
|
* <system firmware load path>/<GPU name>/<fw_name>
|
||||||
|
*
|
||||||
|
* If that fails and NO_SOC is not enabled, it'll try next from:
|
||||||
|
*
|
||||||
|
* <system firmware load path>/<SOC name>/<fw_name>
|
||||||
|
*
|
||||||
|
* It'll allocate a nvgpu_firmware structure and initializes it and returns
|
||||||
|
* it to caller.
|
||||||
|
*/
|
||||||
|
struct nvgpu_firmware *nvgpu_request_firmware(struct gk20a *g,
|
||||||
|
const char *fw_name,
|
||||||
|
int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nvgpu_release_firmware - free firmware and associated nvgpu_firmware blob
|
||||||
|
*
|
||||||
|
* @g The GPU driver struct for device to free firmware for
|
||||||
|
* @fw The firmware to free. fw blob will also be freed.
|
||||||
|
*/
|
||||||
|
void nvgpu_release_firmware(struct gk20a *g, struct nvgpu_firmware *fw);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -25,11 +25,4 @@ int nvgpu_probe(struct gk20a *g,
|
|||||||
const char *interface_name,
|
const char *interface_name,
|
||||||
struct class *class);
|
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
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user