gpu: nvgpu: PMU NVRISCV BR failure HSI

- Add PMU NVRISCV BR failure HSI support.
- Created a falcon unit function to check for the
  BR competition status check and called from
  other units as needed.

Bug 3491596
Bug 3366818

Change-Id: I5c3c6a7e6aeaad68f77e6b24f21239e40d9a7f78
Signed-off-by: mkumbar <mkumbar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2686370
Reviewed-by: Rajesh Devaraj <rdevaraj@nvidia.com>
Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
mkumbar
2022-03-24 12:01:25 +05:30
committed by mobile promotions
parent f670687441
commit 8cce8dea70
5 changed files with 73 additions and 84 deletions

View File

@@ -320,9 +320,6 @@ err_free_ucode:
return err;
}
#define RISCV_BR_COMPLETION_TIMEOUT_NON_SILICON_MS 10000 /*in msec */
#define RISCV_BR_COMPLETION_TIMEOUT_SILICON_MS 100 /*in msec */
static void ga10b_riscv_release_firmware(struct gk20a *g, struct nvgpu_acr *acr)
{
nvgpu_release_firmware(g, acr->acr_asc.manifest_fw);
@@ -370,33 +367,6 @@ static int ga10b_load_riscv_acr_ucodes(struct gk20a *g, struct hs_acr *acr)
return err;
}
static int nvgpu_acr_wait_for_riscv_brom_completion(struct nvgpu_falcon *flcn,
signed int timeoutms)
{
u32 reg = 0;
do {
reg = flcn->g->ops.falcon.get_brom_retcode(flcn);
if (flcn->g->ops.falcon.check_brom_passed(reg)) {
break;
}
if (flcn->g->ops.falcon.check_brom_failed(reg)) {
return -ENOTRECOVERABLE;
}
if (timeoutms <= 0) {
return -ETIMEDOUT;
}
nvgpu_msleep(10);
timeoutms -= 10;
} while (true);
return 0;
}
int nvgpu_acr_bootstrap_hs_ucode_riscv(struct gk20a *g, struct nvgpu_acr *acr)
{
int err = 0;
@@ -436,26 +406,11 @@ int nvgpu_acr_bootstrap_hs_ucode_riscv(struct gk20a *g, struct nvgpu_acr *acr)
acr->acr_asc.data_fw,
acr_sysmem_desc_addr);
if (nvgpu_platform_is_silicon(g)) {
timeout = RISCV_BR_COMPLETION_TIMEOUT_SILICON_MS;
} else {
timeout = RISCV_BR_COMPLETION_TIMEOUT_NON_SILICON_MS;
}
err = nvgpu_acr_wait_for_riscv_brom_completion(flcn, (int)timeout);
if (err == 0x0) {
nvgpu_acr_dbg(g, "RISCV BROM passed");
nvgpu_riscv_dump_brom_stats(flcn);
} else {
err = nvgpu_falcon_wait_for_nvriscv_brom_completion(flcn);
if (err != 0) {
nvgpu_report_err_to_sdl(g, NVGPU_ERR_MODULE_GSP_ACR,
GPU_GSP_ACR_NVRISCV_BROM_FAILURE);
if (err == -ENOTRECOVERABLE) {
nvgpu_err(g, "RISCV BROM Failed");
} else {
nvgpu_err(g, "RISCV BROM timed out, limit: %d ms", timeout);
}
nvgpu_riscv_dump_brom_stats(flcn);
nvgpu_err(g, "ACR NVRISCV BROM FAILURE");
goto exit;
}

View File

@@ -23,6 +23,7 @@
#include <nvgpu/timers.h>
#include <nvgpu/falcon.h>
#include <nvgpu/io.h>
#include <nvgpu/soc.h>
#include <nvgpu/static_analysis.h>
#include "falcon_sw_gk20a.h"
@@ -183,6 +184,58 @@ int nvgpu_falcon_mem_scrub_wait(struct nvgpu_falcon *flcn)
return status;
}
int nvgpu_falcon_wait_for_nvriscv_brom_completion(struct nvgpu_falcon *flcn)
{
struct gk20a *g;
u32 timeoutms = 0;
u32 retcode = 0;
int err = 0;
if (!is_falcon_valid(flcn)) {
return -EINVAL;
}
g = flcn->g;
if (nvgpu_platform_is_silicon(g)) {
timeoutms = NVRISCV_BR_COMPLETION_TIMEOUT_SILICON_MS;
} else {
timeoutms = NVRISCV_BR_COMPLETION_TIMEOUT_NON_SILICON_MS;
}
do {
retcode = g->ops.falcon.get_brom_retcode(flcn);
if (g->ops.falcon.check_brom_passed(retcode)) {
break;
}
if (g->ops.falcon.check_brom_failed(retcode)) {
err = -ENOTRECOVERABLE;
nvgpu_err(g, "Falcon-%d RISCV BROM Failed", flcn->flcn_id);
goto exit;
}
if (timeoutms <= 0) {
nvgpu_err(g, "Falcon-%d RISCV BROM timed out, limit: %d ms",
flcn->flcn_id, timeoutms);
err = -ETIMEDOUT;
goto exit;
}
nvgpu_msleep(NVRISCV_BR_COMPLETION_POLLING_TIME_INTERVAL_MS);
timeoutms -= NVRISCV_BR_COMPLETION_POLLING_TIME_INTERVAL_MS;
} while (true);
nvgpu_falcon_dbg(flcn->g, "Falcon-%d RISCV BROM passed",
flcn->flcn_id);
exit:
g->ops.falcon.dump_brom_stats(flcn);
return err;
}
static int falcon_memcpy_params_check(struct nvgpu_falcon *flcn,
u32 offset, u32 size, enum falcon_mem_type mem_type, u8 port)
{

View File

@@ -149,40 +149,6 @@ exit:
return err;
}
static int gsp_check_for_brom_completion(struct nvgpu_falcon *flcn,
signed int timeoutms)
{
u32 reg = 0;
nvgpu_log_fn(flcn->g, " ");
do {
reg = flcn->g->ops.falcon.get_brom_retcode(flcn);
if (flcn->g->ops.falcon.check_brom_passed(reg)) {
break;
}
if (timeoutms <= 0) {
nvgpu_err(flcn->g, "gsp BROM execution check timedout");
goto exit;
}
nvgpu_msleep(10);
timeoutms -= 10;
} while (true);
if ((reg & 0x3) == 0x2) {
nvgpu_err(flcn->g, "gsp BROM execution failed");
goto exit;
}
return 0;
exit:
flcn->g->ops.falcon.dump_brom_stats(flcn);
return -1;
}
int nvgpu_gsp_wait_for_mailbox_update(struct nvgpu_gsp *gsp,
u32 mailbox_index, u32 exp_value, signed int timeoutms)
{
@@ -268,7 +234,7 @@ int nvgpu_gsp_bootstrap_ns(struct gk20a *g, struct nvgpu_gsp *gsp)
goto exit;
}
err = gsp_check_for_brom_completion(flcn, GSP_WAIT_TIME_MS);
err = nvgpu_falcon_wait_for_nvriscv_brom_completion(flcn);
if (err != 0) {
nvgpu_err(g, "gsp BROM failed");
}

View File

@@ -471,11 +471,19 @@ int nvgpu_pmu_rtos_init(struct gk20a *g)
nvgpu_pmu_fw_state_change(g, g->pmu, PMU_FW_STATE_STARTING, false);
#if defined(CONFIG_NVGPU_NON_FUSA)
if (nvgpu_is_enabled(g, NVGPU_PMU_NEXT_CORE_ENABLED)) {
err = nvgpu_falcon_wait_for_nvriscv_brom_completion(g->pmu->flcn);
if (err != 0) {
nvgpu_report_err_to_sdl(g, NVGPU_ERR_MODULE_PMU,
GPU_PMU_NVRISCV_BROM_FAILURE);
nvgpu_err(g, "PMU NVRISCV BROM FAILURE");
goto exit;
}
err = nvgpu_pmu_wait_for_priv_lockdown_release(g,
g->pmu->flcn, nvgpu_get_poll_timeout(g));
if(err != 0) {
nvgpu_err(g, "PRIV lockdown polling failed");
nvgpu_riscv_dump_brom_stats(g->pmu->flcn);
return err;
}
}

View File

@@ -141,6 +141,11 @@
/** Falcon IMEM block size in bytes */
#define FALCON_BLOCK_SIZE 0x100U
/** NVRISCV BR completion time check in ms*/
#define NVRISCV_BR_COMPLETION_TIMEOUT_NON_SILICON_MS 10000U
#define NVRISCV_BR_COMPLETION_TIMEOUT_SILICON_MS 100U
#define NVRISCV_BR_COMPLETION_POLLING_TIME_INTERVAL_MS 5U
#define GET_IMEM_TAG(IMEM_ADDR) ((IMEM_ADDR) >> 8U)
#define GET_NEXT_BLOCK(ADDR) \
@@ -711,6 +716,8 @@ bool nvgpu_falcon_is_falcon2_enabled(struct nvgpu_falcon *flcn);
bool nvgpu_falcon_is_feature_supported(struct nvgpu_falcon *flcn,
u32 feature);
int nvgpu_falcon_wait_for_nvriscv_brom_completion(struct nvgpu_falcon *flcn);
#ifdef CONFIG_NVGPU_DGPU
int nvgpu_falcon_copy_from_emem(struct nvgpu_falcon *flcn,
u32 src, u8 *dst, u32 size, u8 port);