summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
diff options
context:
space:
mode:
authorVijayakumar <vsubbu@nvidia.com>2015-06-24 03:26:50 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-06-26 16:14:53 -0400
commit30d399de307befc4edc2b8ca66c36ad2440d34f1 (patch)
tree6e94200cc3f0c8d320de3c413ec471939990355c /drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
parent25b540e5c9b4febaa0aedc8cfe3b3fcf6cfd56b8 (diff)
gpu: nvgpu: load secure gpccs using dma
bug 200080684 use new cmd defined in ucode for loading GR falcons. flip PRIV load flag in lsb header to indicate using dma. use pmu msg as cmd completion for new cmd instead of polling fecs mailbox. also move check for using dma in non secure boot path to hal. Change-Id: I22582a705bd1ae0603f858e1fe200d72e6794a81 Signed-off-by: Vijayakumar <vsubbu@nvidia.com> Reviewed-on: http://git-master/r/761625 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-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.c63
1 files changed, 57 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
index 28b40b1c..ac19e99c 100644
--- a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
@@ -18,6 +18,7 @@
18#include "gk20a/pmu_gk20a.h" 18#include "gk20a/pmu_gk20a.h"
19#include "acr_gm20b.h" 19#include "acr_gm20b.h"
20#include "pmu_gm20b.h" 20#include "pmu_gm20b.h"
21#include "hw_gr_gm20b.h"
21 22
22/*! 23/*!
23 * Structure/object which single register write need to be done during PG init 24 * Structure/object which single register write need to be done during PG init
@@ -190,21 +191,40 @@ int gm20b_pmu_init_acr(struct gk20a *g)
190 return 0; 191 return 0;
191} 192}
192 193
193static void pmu_handle_fecs_boot_acr_msg(struct gk20a *g, struct pmu_msg *msg, 194void pmu_handle_fecs_boot_acr_msg(struct gk20a *g, struct pmu_msg *msg,
194 void *param, u32 handle, u32 status) 195 void *param, u32 handle, u32 status)
195{ 196{
196 197
197 gk20a_dbg_fn(""); 198 gk20a_dbg_fn("");
198 199
199 200
200 if (msg->msg.acr.acrmsg.falconid == LSF_FALCON_ID_FECS) 201 gm20b_dbg_pmu("reply PMU_ACR_CMD_ID_BOOTSTRAP_FALCON");
201 gm20b_dbg_pmu("reply PMU_ACR_CMD_ID_BOOTSTRAP_FALCON");
202 202
203 gm20b_dbg_pmu("response code = %x\n", msg->msg.acr.acrmsg.falconid); 203 gm20b_dbg_pmu("response code = %x\n", msg->msg.acr.acrmsg.falconid);
204 g->ops.pmu.lsfloadedfalconid = msg->msg.acr.acrmsg.falconid;
204 gk20a_dbg_fn("done"); 205 gk20a_dbg_fn("done");
205} 206}
206 207
207void gm20b_pmu_load_lsf(struct gk20a *g, u8 falcon_id) 208static int pmu_gm20b_ctx_wait_lsf_ready(struct gk20a *g, u32 timeout, u32 val)
209{
210 unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
211 unsigned long delay = GR_FECS_POLL_INTERVAL;
212 u32 reg;
213
214 gk20a_dbg_fn("");
215 reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0));
216 do {
217 reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0));
218 if (reg == val)
219 return 0;
220 udelay(delay);
221 } while (time_before(jiffies, end_jiffies) ||
222 !tegra_platform_is_silicon());
223
224 return -ETIMEDOUT;
225}
226
227void gm20b_pmu_load_lsf(struct gk20a *g, u32 falcon_id, u32 flags)
208{ 228{
209 struct pmu_gk20a *pmu = &g->pmu; 229 struct pmu_gk20a *pmu = &g->pmu;
210 struct pmu_cmd cmd; 230 struct pmu_cmd cmd;
@@ -221,8 +241,7 @@ void gm20b_pmu_load_lsf(struct gk20a *g, u8 falcon_id)
221 sizeof(struct pmu_acr_cmd_bootstrap_falcon); 241 sizeof(struct pmu_acr_cmd_bootstrap_falcon);
222 cmd.cmd.acr.bootstrap_falcon.cmd_type = 242 cmd.cmd.acr.bootstrap_falcon.cmd_type =
223 PMU_ACR_CMD_ID_BOOTSTRAP_FALCON; 243 PMU_ACR_CMD_ID_BOOTSTRAP_FALCON;
224 cmd.cmd.acr.bootstrap_falcon.flags = 244 cmd.cmd.acr.bootstrap_falcon.flags = flags;
225 PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
226 cmd.cmd.acr.bootstrap_falcon.falconid = falcon_id; 245 cmd.cmd.acr.bootstrap_falcon.falconid = falcon_id;
227 gm20b_dbg_pmu("cmd post PMU_ACR_CMD_ID_BOOTSTRAP_FALCON: %x\n", 246 gm20b_dbg_pmu("cmd post PMU_ACR_CMD_ID_BOOTSTRAP_FALCON: %x\n",
228 falcon_id); 247 falcon_id);
@@ -234,13 +253,45 @@ void gm20b_pmu_load_lsf(struct gk20a *g, u8 falcon_id)
234 return; 253 return;
235} 254}
236 255
256int gm20b_load_falcon_ucode(struct gk20a *g, u32 falconidmask)
257{
258 u32 err = 0;
259 u32 flags = PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
260 unsigned long timeout = gk20a_get_gr_idle_timeout(g);
261
262 /* GM20B PMU supports loading FECS only */
263 if (!(falconidmask == (1 << LSF_FALCON_ID_FECS)))
264 return -EINVAL;
265 /* check whether pmu is ready to bootstrap lsf if not wait for it */
266 if (!g->ops.pmu.lspmuwprinitdone) {
267 pmu_wait_message_cond(&g->pmu,
268 gk20a_get_gr_idle_timeout(g),
269 &g->ops.pmu.lspmuwprinitdone, 1);
270 /* check again if it still not ready indicate an error */
271 if (!g->ops.pmu.lspmuwprinitdone) {
272 gk20a_err(dev_from_gk20a(g),
273 "PMU not ready to load LSF");
274 return -ETIMEDOUT;
275 }
276 }
277 /* load FECS */
278 gk20a_writel(g,
279 gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
280 gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS, flags);
281 err = pmu_gm20b_ctx_wait_lsf_ready(g, timeout,
282 0x55AA55AA);
283 return err;
284}
285
237void gm20b_init_pmu_ops(struct gpu_ops *gops) 286void gm20b_init_pmu_ops(struct gpu_ops *gops)
238{ 287{
239 if (gops->privsecurity) { 288 if (gops->privsecurity) {
240 gm20b_init_secure_pmu(gops); 289 gm20b_init_secure_pmu(gops);
241 gops->pmu.init_wpr_region = gm20b_pmu_init_acr; 290 gops->pmu.init_wpr_region = gm20b_pmu_init_acr;
291 gops->pmu.load_lsfalcon_ucode = gm20b_load_falcon_ucode;
242 } else { 292 } else {
243 gk20a_init_pmu_ops(gops); 293 gk20a_init_pmu_ops(gops);
294 gops->pmu.load_lsfalcon_ucode = NULL;
244 gops->pmu.init_wpr_region = NULL; 295 gops->pmu.init_wpr_region = NULL;
245 } 296 }
246 gops->pmu.pmu_setup_elpg = gm20b_pmu_setup_elpg; 297 gops->pmu.pmu_setup_elpg = gm20b_pmu_setup_elpg;