From d65a93b80c60bb677fbc13b7180e0f31b7f97f84 Mon Sep 17 00:00:00 2001 From: Vijayakumar Date: Thu, 9 Apr 2015 16:47:13 +0530 Subject: gpu: nvgpu: add secure gpccs boot support bug 200080684 keeping it disabled by default also trimming the code by removing redundant variable to check recovery. pmu quick wait now checks only for irqs which are serviced by kernel. requests pmu to bit bang gpccs ucode. Change-Id: I12ef23d6d59b507e86a129b69eab65b21d0438c6 Signed-off-by: Vijayakumar Reviewed-on: http://git-master/r/729622 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gm20b/gr_gm20b.c | 86 ++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 32 deletions(-) (limited to 'drivers/gpu/nvgpu/gm20b/gr_gm20b.c') diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index 55a21c98..1fa1eb24 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c @@ -710,6 +710,10 @@ static int gr_gm20b_ctx_wait_lsf_ready(struct gk20a *g, u32 timeout, u32 val) static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) { u32 err; + unsigned long timeout = gk20a_get_gr_idle_timeout(g); + u32 reg_offset = gr_gpcs_gpccs_falcon_hwcfg_r() - + gr_fecs_falcon_hwcfg_r(); + gk20a_dbg_fn(""); if (tegra_platform_is_linsim()) { @@ -719,50 +723,68 @@ static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); } - gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); - gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS); - - gr_gm20b_load_gpccs_with_bootloader(g); - - if (g->ops.pmu.fecsrecoveryinprogress) { - unsigned long timeout = gk20a_get_gr_idle_timeout(g); + if (g->ops.pmu.fecsbootstrapdone) { + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); + gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS); err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, 0x55AA55AA); if (err) { gk20a_err(dev_from_gk20a(g), "Unable to recover FECS"); return err; } else { - g->ops.pmu.fecsrecoveryinprogress = 0; - gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); - gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); - gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), - 0xffffffff); - - gk20a_writel(g, gr_gpccs_dmactl_r(), + if (!g->ops.securegpccs) { + gr_gm20b_load_gpccs_with_bootloader(g); + gk20a_writel(g, gr_gpccs_dmactl_r(), gr_gpccs_dmactl_require_ctx_f(0)); - gk20a_writel(g, gr_gpccs_cpuctl_r(), + gk20a_writel(g, gr_gpccs_cpuctl_r(), gr_gpccs_cpuctl_startcpu_f(1)); - - gk20a_writel(g, gr_fecs_cpuctl_alias_r(), - gr_fecs_cpuctl_startcpu_f(1)); + } else { + gk20a_writel(g, + gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); + gm20b_pmu_load_lsf(g, LSF_FALCON_ID_GPCCS); + err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, + 0x55AA55AA); + gk20a_writel(g, reg_offset + + gr_fecs_cpuctl_alias_r(), + gr_gpccs_cpuctl_startcpu_f(1)); + } } - } - - - if (!g->ops.pmu.fecsbootstrapdone) { + } else { g->ops.pmu.fecsbootstrapdone = true; - gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); - gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); - gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); - - gk20a_writel(g, gr_gpccs_dmactl_r(), - gr_gpccs_dmactl_require_ctx_f(0)); - gk20a_writel(g, gr_gpccs_cpuctl_r(), + if (!g->ops.securegpccs) { + gr_gm20b_load_gpccs_with_bootloader(g); + gk20a_writel(g, gr_gpccs_dmactl_r(), + gr_gpccs_dmactl_require_ctx_f(0)); + gk20a_writel(g, gr_gpccs_cpuctl_r(), + gr_gpccs_cpuctl_startcpu_f(1)); + } else { + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &g->ops.pmu.lspmuwprinitdone, 1); + if (!g->ops.pmu.lspmuwprinitdone) { + gk20a_err(dev_from_gk20a(g), + "PMU WPR needed but not ready yet"); + return -ETIMEDOUT; + } + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); + gm20b_pmu_load_lsf(g, LSF_FALCON_ID_GPCCS); + err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, + 0x55AA55AA); + if (err) { + gk20a_err(dev_from_gk20a(g), + "Unable to boot GPCCS\n"); + return err; + } + gk20a_writel(g, reg_offset + + gr_fecs_cpuctl_alias_r(), gr_gpccs_cpuctl_startcpu_f(1)); - - gk20a_writel(g, gr_fecs_cpuctl_alias_r(), - gr_fecs_cpuctl_startcpu_f(1)); + } } + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); + gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); + gk20a_writel(g, gr_fecs_cpuctl_alias_r(), + gr_fecs_cpuctl_startcpu_f(1)); gk20a_dbg_fn("done"); return 0; -- cgit v1.2.2