summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gv100/pmu_gv100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gv100/pmu_gv100.c')
-rw-r--r--drivers/gpu/nvgpu/gv100/pmu_gv100.c50
1 files changed, 50 insertions, 0 deletions
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)
43 43
44 return status; 44 return status;
45} 45}
46
47int gv100_load_falcon_ucode(struct gk20a *g, u32 falconidmask)
48{
49 struct nvgpu_pmu *pmu = &g->pmu;
50 struct nv_pmu_rpc_struct_acr_bootstrap_gr_falcons rpc;
51 u32 flags = PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
52 int status = 0;
53
54 if (falconidmask == 0)
55 return -EINVAL;
56
57 if (falconidmask & ~((1 << LSF_FALCON_ID_FECS) |
58 (1 << LSF_FALCON_ID_GPCCS)))
59 return -EINVAL;
60
61 g->pmu_lsf_loaded_falcon_id = 0;
62 /* check whether pmu is ready to bootstrap lsf if not wait for it */
63 if (!g->pmu_lsf_pmu_wpr_init_done) {
64 pmu_wait_message_cond(&g->pmu,
65 gk20a_get_gr_idle_timeout(g),
66 &g->pmu_lsf_pmu_wpr_init_done, 1);
67 /* check again if it still not ready indicate an error */
68 if (!g->pmu_lsf_pmu_wpr_init_done) {
69 nvgpu_err(g, "PMU not ready to load LSF");
70 status = -ETIMEDOUT;
71 goto exit;
72 }
73 }
74
75 memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_acr_bootstrap_gr_falcons));
76 rpc.falcon_id_mask = falconidmask;
77 rpc.flags = flags;
78 rpc.falcon_va_mask = 0;
79 rpc.wpr_base_virtual.lo = 0;
80 rpc.wpr_base_virtual.hi = 0;
81 PMU_RPC_EXECUTE(status, pmu, ACR, BOOTSTRAP_GR_FALCONS, &rpc, 0);
82 if (status) {
83 nvgpu_err(g, "Failed to execute RPC, status=0x%x", status);
84 goto exit;
85 }
86
87 pmu_wait_message_cond(&g->pmu, gk20a_get_gr_idle_timeout(g),
88 &g->pmu_lsf_loaded_falcon_id, 1);
89
90 if (g->pmu_lsf_loaded_falcon_id != 1)
91 status = -ETIMEDOUT;
92
93exit:
94 return status;
95}