mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
gpu: nvgpu: mem unlock ucode load & bootstrap changes
-Removed dependency from ACR unit to load mem unlock HS ucode on to FB Falcon using Falcon unit's HS ucode load bootstrap function. JIRA NVGPU-3811 Change-Id: I29977fb0391797b53ad577a011a01c03e1853b74 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2195017 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Alex Waterman
parent
e77a911568
commit
744cf2467d
@@ -39,7 +39,7 @@
|
|||||||
#include <nvgpu/timers.h>
|
#include <nvgpu/timers.h>
|
||||||
#include <nvgpu/gk20a.h>
|
#include <nvgpu/gk20a.h>
|
||||||
#include <nvgpu/unit.h>
|
#include <nvgpu/unit.h>
|
||||||
#include <nvgpu/acr.h>
|
#include <nvgpu/firmware.h>
|
||||||
|
|
||||||
#include "fb_gv100.h"
|
#include "fb_gv100.h"
|
||||||
|
|
||||||
@@ -52,6 +52,26 @@
|
|||||||
#define MEM_UNLOCK_PROD_BIN "mem_unlock.bin"
|
#define MEM_UNLOCK_PROD_BIN "mem_unlock.bin"
|
||||||
#define MEM_UNLOCK_DBG_BIN "mem_unlock_dbg.bin"
|
#define MEM_UNLOCK_DBG_BIN "mem_unlock_dbg.bin"
|
||||||
|
|
||||||
|
struct mem_unlock_bin_hdr {
|
||||||
|
u32 bin_magic;
|
||||||
|
u32 bin_ver;
|
||||||
|
u32 bin_size;
|
||||||
|
u32 header_offset;
|
||||||
|
u32 data_offset;
|
||||||
|
u32 data_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mem_unlock_fw_header {
|
||||||
|
u32 sig_dbg_offset;
|
||||||
|
u32 sig_dbg_size;
|
||||||
|
u32 sig_prod_offset;
|
||||||
|
u32 sig_prod_size;
|
||||||
|
u32 patch_loc;
|
||||||
|
u32 patch_sig;
|
||||||
|
u32 hdr_offset;
|
||||||
|
u32 hdr_size;
|
||||||
|
};
|
||||||
|
|
||||||
void gv100_fb_reset(struct gk20a *g)
|
void gv100_fb_reset(struct gk20a *g)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
@@ -75,9 +95,43 @@ void gv100_fb_reset(struct gk20a *g)
|
|||||||
gk20a_writel(g, fb_mmu_priv_level_mask_r(), val);
|
gk20a_writel(g, fb_mmu_priv_level_mask_r(), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Patch signatures into ucode image
|
||||||
|
*/
|
||||||
|
static int fb_ucode_patch_sig(struct gk20a *g,
|
||||||
|
unsigned int *p_img, unsigned int *p_prod_sig,
|
||||||
|
unsigned int *p_dbg_sig, unsigned int *p_patch_loc,
|
||||||
|
unsigned int *p_patch_ind, u32 sig_size)
|
||||||
|
{
|
||||||
|
unsigned int i, j, *p_sig;
|
||||||
|
|
||||||
|
if (!g->ops.pmu.is_debug_mode_enabled(g)) {
|
||||||
|
p_sig = p_prod_sig;
|
||||||
|
} else {
|
||||||
|
p_sig = p_dbg_sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Patching logic:*/
|
||||||
|
sig_size = sig_size / 4U;
|
||||||
|
for (i = 0U; i < sizeof(*p_patch_loc)>>2U; i++) {
|
||||||
|
for (j = 0U; j < sig_size; j++) {
|
||||||
|
p_img[nvgpu_safe_add_u32((p_patch_loc[i]>>2U), j)] =
|
||||||
|
p_sig[nvgpu_safe_add_u32((p_patch_ind[i]<<2U),
|
||||||
|
j)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int gv100_fb_memory_unlock(struct gk20a *g)
|
int gv100_fb_memory_unlock(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct nvgpu_firmware *mem_unlock_fw = NULL;
|
struct nvgpu_firmware *mem_unlock_fw = NULL;
|
||||||
|
struct mem_unlock_bin_hdr *hs_bin_hdr = NULL;
|
||||||
|
struct mem_unlock_fw_header *fw_hdr = NULL;
|
||||||
|
u32 *ucode_header = NULL;
|
||||||
|
u32 *ucode = NULL;
|
||||||
|
u32 data = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
nvgpu_log_fn(g, " ");
|
nvgpu_log_fn(g, " ");
|
||||||
@@ -100,10 +154,45 @@ int gv100_fb_memory_unlock(struct gk20a *g)
|
|||||||
/* Enable nvdec */
|
/* Enable nvdec */
|
||||||
g->ops.mc.enable(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_NVDEC));
|
g->ops.mc.enable(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_NVDEC));
|
||||||
|
|
||||||
err = nvgpu_acr_self_hs_load_bootstrap(g, &g->nvdec_flcn, mem_unlock_fw,
|
hs_bin_hdr = (struct mem_unlock_bin_hdr *)(void *)mem_unlock_fw->data;
|
||||||
MEM_UNLOCK_TIMEOUT );
|
fw_hdr = (struct mem_unlock_fw_header *)(void *)(mem_unlock_fw->data +
|
||||||
|
hs_bin_hdr->header_offset);
|
||||||
|
ucode_header = (u32 *)(void *)(mem_unlock_fw->data +
|
||||||
|
fw_hdr->hdr_offset);
|
||||||
|
ucode = (u32 *)(void *)(mem_unlock_fw->data + hs_bin_hdr->data_offset);
|
||||||
|
|
||||||
|
/* Patch Ucode signatures */
|
||||||
|
if (fb_ucode_patch_sig(g, ucode,
|
||||||
|
(u32 *)(void *)(mem_unlock_fw->data + fw_hdr->sig_prod_offset),
|
||||||
|
(u32 *)(void *)(mem_unlock_fw->data + fw_hdr->sig_dbg_offset),
|
||||||
|
(u32 *)(void *)(mem_unlock_fw->data + fw_hdr->patch_loc),
|
||||||
|
(u32 *)(void *)(mem_unlock_fw->data + fw_hdr->patch_sig),
|
||||||
|
fw_hdr->sig_dbg_size) < 0) {
|
||||||
|
nvgpu_err(g, "mem unlock ucode patch signatures fail");
|
||||||
|
err = -EPERM;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nvgpu_falcon_hs_ucode_load_bootstrap(&g->nvdec_flcn, ucode,
|
||||||
|
ucode_header);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
nvgpu_err(g, "mem unlock HS ucode failed, err-0x%x", err);
|
nvgpu_err(g, "mem unlock ucode load & bootstrap failed");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvgpu_falcon_wait_for_halt(&g->nvdec_flcn,
|
||||||
|
MEM_UNLOCK_TIMEOUT) != 0) {
|
||||||
|
nvgpu_err(g, "mem unlock ucode boot timed out");
|
||||||
|
#ifdef CONFIG_NVGPU_FALCON_DEBUG
|
||||||
|
nvgpu_falcon_dump_stats(&g->nvdec_flcn);
|
||||||
|
#endif
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = nvgpu_falcon_mailbox_read(&g->nvdec_flcn, FALCON_MAILBOX_0);
|
||||||
|
if (data != 0U) {
|
||||||
|
nvgpu_err(g, "mem unlock ucode boot failed, err %x", data);
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
|||||||
Reference in New Issue
Block a user