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:
Mahantesh Kumbar
2019-09-11 12:56:32 +05:30
committed by Alex Waterman
parent e77a911568
commit 744cf2467d

View File

@@ -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: