diff --git a/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c b/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c index 9707a2da6..4985e69ce 100644 --- a/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c +++ b/drivers/gpu/nvgpu/common/acr/acr_bootstrap.c @@ -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; } diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c index d41ab9ade..1d9adf666 100644 --- a/drivers/gpu/nvgpu/common/falcon/falcon.c +++ b/drivers/gpu/nvgpu/common/falcon/falcon.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #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) { diff --git a/drivers/gpu/nvgpu/common/gsp/gsp_bootstrap.c b/drivers/gpu/nvgpu/common/gsp/gsp_bootstrap.c index 20792f9f1..f79bb844a 100644 --- a/drivers/gpu/nvgpu/common/gsp/gsp_bootstrap.c +++ b/drivers/gpu/nvgpu/common/gsp/gsp_bootstrap.c @@ -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"); } diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c b/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c index 983c756c2..36f5a71cf 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_rtos_init.c @@ -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; } } diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h index 9977e5c59..bfe4018b5 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h +++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h @@ -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);