summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
diff options
context:
space:
mode:
authorVijayakumar <vsubbu@nvidia.com>2014-09-30 10:49:44 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:52 -0400
commit748475df20bbe6843bdf4fbc02384dc5aa28866e (patch)
tree700012cf758d6731017b8b23153abae4311bf065 /drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
parent4739499f07b29282ee1031d08adaa76c238da2a6 (diff)
gpu: nvgpu: gm20b: Support secure FECS recovery
When falcons are secured use PMU commands to reload FECS firmware. Bug 200042729 Change-Id: I09f2472b16dac6a510dba067bce3950075973d5f Signed-off-by: Vijayakumar <vsubbu@nvidia.com> Reviewed-on: http://git-master/r/552544 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/pmu_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/pmu_gm20b.c96
1 files changed, 94 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
index 98dc6845..91927950 100644
--- a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
@@ -13,7 +13,9 @@
13 * more details. 13 * more details.
14 */ 14 */
15 15
16#include <linux/delay.h> /* for udelay */
16#include "gk20a/gk20a.h" 17#include "gk20a/gk20a.h"
18#include "gk20a/pmu_gk20a.h"
17#include "acr_gm20b.h" 19#include "acr_gm20b.h"
18#include "pmu_gm20b.h" 20#include "pmu_gm20b.h"
19 21
@@ -26,6 +28,9 @@ struct pg_init_sequence_list {
26 u32 writeval; 28 u32 writeval;
27}; 29};
28 30
31#define gm20b_dbg_pmu(fmt, arg...) \
32 gk20a_dbg(gpu_dbg_pmu, fmt, ##arg)
33
29 34
30/* PROD settings for ELPG sequencing registers*/ 35/* PROD settings for ELPG sequencing registers*/
31static struct pg_init_sequence_list _pginitseq_gm20b[] = { 36static struct pg_init_sequence_list _pginitseq_gm20b[] = {
@@ -148,11 +153,98 @@ int gm20b_pmu_setup_elpg(struct gk20a *g)
148 return ret; 153 return ret;
149} 154}
150 155
156void pmu_handle_acr_init_wpr_msg(struct gk20a *g, struct pmu_msg *msg,
157 void *param, u32 handle, u32 status)
158{
159 gk20a_dbg_fn("");
160
161 gm20b_dbg_pmu("reply PMU_ACR_CMD_ID_INIT_WPR_REGION");
162
163 if (msg->msg.acr.acrmsg.errorcode == PMU_ACR_SUCCESS)
164 g->ops.pmu.lspmuwprinitdone = true;
165 gk20a_dbg_fn("done");
166}
167
168
169int gm20b_pmu_init_acr(struct gk20a *g)
170{
171 struct pmu_gk20a *pmu = &g->pmu;
172 struct pmu_cmd cmd;
173 u32 seq;
174
175 gk20a_dbg_fn("");
176
177 /* init ACR */
178 memset(&cmd, 0, sizeof(struct pmu_cmd));
179 cmd.hdr.unit_id = PMU_UNIT_ACR;
180 cmd.hdr.size = PMU_CMD_HDR_SIZE +
181 sizeof(struct pmu_acr_cmd_init_wpr_details);
182 cmd.cmd.acr.init_wpr.cmd_type = PMU_ACR_CMD_ID_INIT_WPR_REGION;
183 cmd.cmd.acr.init_wpr.regionid = 0x01;
184 cmd.cmd.acr.init_wpr.wproffset = 0x00;
185 gm20b_dbg_pmu("cmd post PMU_ACR_CMD_ID_INIT_WPR_REGION");
186 gk20a_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ,
187 pmu_handle_acr_init_wpr_msg, pmu, &seq, ~0);
188
189 gk20a_dbg_fn("done");
190 return 0;
191}
192
193void pmu_handle_fecs_boot_acr_msg(struct gk20a *g, struct pmu_msg *msg,
194 void *param, u32 handle, u32 status)
195{
196
197 gk20a_dbg_fn("");
198
199
200 if (msg->msg.acr.acrmsg.falconid == LSF_FALCON_ID_FECS)
201 gm20b_dbg_pmu("reply PMU_ACR_CMD_ID_BOOTSTRAP_FALCON");
202
203 gm20b_dbg_pmu("response code = %x\n", msg->msg.acr.acrmsg.falconid);
204 gk20a_dbg_fn("done");
205}
206
207void gm20b_pmu_load_lsf(struct gk20a *g, u8 falcon_id)
208{
209 struct pmu_gk20a *pmu = &g->pmu;
210 struct pmu_cmd cmd;
211 u32 seq;
212
213 gk20a_dbg_fn("");
214
215 gm20b_dbg_pmu("wprinit status = %x\n", g->ops.pmu.lspmuwprinitdone);
216 if (g->ops.pmu.lspmuwprinitdone && g->ops.pmu.fecsbootstrapdone) {
217 /* send message to load FECS falcon */
218 memset(&cmd, 0, sizeof(struct pmu_cmd));
219 cmd.hdr.unit_id = PMU_UNIT_ACR;
220 cmd.hdr.size = PMU_CMD_HDR_SIZE +
221 sizeof(struct pmu_acr_cmd_bootstrap_falcon);
222 cmd.cmd.acr.bootstrap_falcon.cmd_type =
223 PMU_ACR_CMD_ID_BOOTSTRAP_FALCON;
224 cmd.cmd.acr.bootstrap_falcon.flags =
225 PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
226 cmd.cmd.acr.bootstrap_falcon.falconid = falcon_id;
227 gm20b_dbg_pmu("cmd post PMU_ACR_CMD_ID_BOOTSTRAP_FALCON");
228 g->ops.pmu.fecsrecoveryinprogress = 1;
229 gk20a_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ,
230 pmu_handle_fecs_boot_acr_msg, pmu, &seq, ~0);
231 }
232
233 gk20a_dbg_fn("done");
234 return;
235}
236
151void gm20b_init_pmu_ops(struct gpu_ops *gops) 237void gm20b_init_pmu_ops(struct gpu_ops *gops)
152{ 238{
153 if (gops->privsecurity) 239 if (gops->privsecurity) {
154 gm20b_init_secure_pmu(gops); 240 gm20b_init_secure_pmu(gops);
155 else 241 gops->pmu.init_wpr_region = gm20b_pmu_init_acr;
242 } else {
156 gk20a_init_pmu_ops(gops); 243 gk20a_init_pmu_ops(gops);
244 gops->pmu.init_wpr_region = NULL;
245 }
157 gops->pmu.pmu_setup_elpg = gm20b_pmu_setup_elpg; 246 gops->pmu.pmu_setup_elpg = gm20b_pmu_setup_elpg;
247 gops->pmu.lspmuwprinitdone = false;
248 gops->pmu.fecsbootstrapdone = false;
249 gops->pmu.fecsrecoveryinprogress = 0;
158} 250}