From 99e808567ca358e0e6d03f4731b81854070266a3 Mon Sep 17 00:00:00 2001 From: Mahantesh Kumbar Date: Fri, 8 Dec 2017 00:11:13 +0530 Subject: gpu: nvgpu: gv100: BOOTSTRAP_GR_FALCONS using RPC - Created nv_pmu_rpc_struct_acr_bootstrap_gr_falcons struct - gv100_load_falcon_ucode() function to bootstrap GR flacons using RPC, wait for INIT_WPR_REGION before creating & executing BOOTSTRAP_GR_FALCONS RPC. - Added code to handle BOOTSTRAP_GR_FALCONS ack in RPC handler Change-Id: If70dc75bb2789970382853fb001d970a346b2915 Signed-off-by: Mahantesh Kumbar Reviewed-on: https://git-master.nvidia.com/r/1613316 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/pmu/pmu_ipc.c | 5 +++ drivers/gpu/nvgpu/gv100/hal_gv100.c | 2 +- drivers/gpu/nvgpu/gv100/pmu_gv100.c | 50 ++++++++++++++++++++++ drivers/gpu/nvgpu/gv100/pmu_gv100.h | 1 + drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuif_acr.h | 25 +++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c b/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c index 77acbafc..72337a1d 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_ipc.c @@ -1000,6 +1000,11 @@ static void pmu_rpc_handler(struct gk20a *g, struct pmu_msg *msg, "reply NV_PMU_RPC_ID_ACR_INIT_WPR_REGION"); g->pmu_lsf_pmu_wpr_init_done = 1; break; + case NV_PMU_RPC_ID_ACR_BOOTSTRAP_GR_FALCONS: + nvgpu_pmu_dbg(g, + "reply NV_PMU_RPC_ID_ACR_BOOTSTRAP_GR_FALCONS"); + g->pmu_lsf_loaded_falcon_id = 1; + break; } break; case PMU_UNIT_PERFMON_T18X: diff --git a/drivers/gpu/nvgpu/gv100/hal_gv100.c b/drivers/gpu/nvgpu/gv100/hal_gv100.c index cf9ca9d8..418ff45e 100644 --- a/drivers/gpu/nvgpu/gv100/hal_gv100.c +++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c @@ -574,7 +574,7 @@ static const struct gpu_ops gv100_ops = { }, .pmu = { .init_wpr_region = gv100_pmu_init_acr, - .load_lsfalcon_ucode = gp106_load_falcon_ucode, + .load_lsfalcon_ucode = gv100_load_falcon_ucode, .is_lazy_bootstrap = gp106_is_lazy_bootstrap, .is_priv_load = gp106_is_priv_load, .prepare_ucode = gp106_prepare_ucode_blob, diff --git a/drivers/gpu/nvgpu/gv100/pmu_gv100.c b/drivers/gpu/nvgpu/gv100/pmu_gv100.c index 339df6af..113e554b 100644 --- a/drivers/gpu/nvgpu/gv100/pmu_gv100.c +++ b/drivers/gpu/nvgpu/gv100/pmu_gv100.c @@ -43,3 +43,53 @@ int gv100_pmu_init_acr(struct gk20a *g) return status; } + +int gv100_load_falcon_ucode(struct gk20a *g, u32 falconidmask) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_acr_bootstrap_gr_falcons rpc; + u32 flags = PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES; + int status = 0; + + if (falconidmask == 0) + return -EINVAL; + + if (falconidmask & ~((1 << LSF_FALCON_ID_FECS) | + (1 << LSF_FALCON_ID_GPCCS))) + return -EINVAL; + + g->pmu_lsf_loaded_falcon_id = 0; + /* check whether pmu is ready to bootstrap lsf if not wait for it */ + if (!g->pmu_lsf_pmu_wpr_init_done) { + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &g->pmu_lsf_pmu_wpr_init_done, 1); + /* check again if it still not ready indicate an error */ + if (!g->pmu_lsf_pmu_wpr_init_done) { + nvgpu_err(g, "PMU not ready to load LSF"); + status = -ETIMEDOUT; + goto exit; + } + } + + memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_acr_bootstrap_gr_falcons)); + rpc.falcon_id_mask = falconidmask; + rpc.flags = flags; + rpc.falcon_va_mask = 0; + rpc.wpr_base_virtual.lo = 0; + rpc.wpr_base_virtual.hi = 0; + PMU_RPC_EXECUTE(status, pmu, ACR, BOOTSTRAP_GR_FALCONS, &rpc, 0); + if (status) { + nvgpu_err(g, "Failed to execute RPC, status=0x%x", status); + goto exit; + } + + pmu_wait_message_cond(&g->pmu, gk20a_get_gr_idle_timeout(g), + &g->pmu_lsf_loaded_falcon_id, 1); + + if (g->pmu_lsf_loaded_falcon_id != 1) + status = -ETIMEDOUT; + +exit: + return status; +} diff --git a/drivers/gpu/nvgpu/gv100/pmu_gv100.h b/drivers/gpu/nvgpu/gv100/pmu_gv100.h index 5ef34149..4c8b3541 100644 --- a/drivers/gpu/nvgpu/gv100/pmu_gv100.h +++ b/drivers/gpu/nvgpu/gv100/pmu_gv100.h @@ -28,5 +28,6 @@ struct gk20a; int gv100_pmu_init_acr(struct gk20a *g); +int gv100_load_falcon_ucode(struct gk20a *g, u32 falconidmask); #endif /*__PMU_GV100_H_*/ diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuif_acr.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuif_acr.h index bc3b1056..c1a4b360 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuif_acr.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuif_acr.h @@ -131,4 +131,29 @@ struct nv_pmu_rpc_struct_acr_init_wpr_region { u32 scratch[1]; }; +/* + * structure that holds data used to + * execute BOOTSTRAP_GR_FALCONS RPC. + */ +struct nv_pmu_rpc_struct_acr_bootstrap_gr_falcons { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + /* [IN] Mask of falcon IDs @ref LSF_FALCON_ID_ */ + u32 falcon_id_mask; + /* + * [IN] Boostrapping flags @ref + * PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_ + */ + u32 flags; + /* [IN] Indicate whether the particular falon uses VA */ + u32 falcon_va_mask; + /* + * [IN] WPR Base Address in VA. The Inst Block containing + * this VA should be bound to both PMU and GR falcons + * during the falcon boot + */ + struct falc_u64 wpr_base_virtual; + u32 scratch[1]; +}; + #endif /* _GPMUIFACR_H_ */ -- cgit v1.2.2