summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/gr_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/gr_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/gr_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index 660ffa88..8a3de4e8 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/delay.h> /* for mdelay */
17 18
18#include "gk20a/gk20a.h" 19#include "gk20a/gk20a.h"
19#include "gk20a/gr_gk20a.h" 20#include "gk20a/gr_gk20a.h"
@@ -24,6 +25,8 @@
24#include "hw_proj_gm20b.h" 25#include "hw_proj_gm20b.h"
25#include "hw_ctxsw_prog_gm20b.h" 26#include "hw_ctxsw_prog_gm20b.h"
26#include "hw_fuse_gm20b.h" 27#include "hw_fuse_gm20b.h"
28#include "pmu_gm20b.h"
29#include "acr_gm20b.h"
27 30
28static void gr_gm20b_init_gpc_mmu(struct gk20a *g) 31static void gr_gm20b_init_gpc_mmu(struct gk20a *g)
29{ 32{
@@ -625,8 +628,29 @@ static void gr_gm20b_load_gpccs_with_bootloader(struct gk20a *g)
625 gr_fecs_falcon_hwcfg_r()); 628 gr_fecs_falcon_hwcfg_r());
626} 629}
627 630
631static int gr_gm20b_ctx_wait_lsf_ready(struct gk20a *g, u32 timeout, u32 val)
632{
633 unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
634 unsigned long delay = GR_IDLE_CHECK_DEFAULT;
635 u32 reg;
636
637 gk20a_dbg_fn("");
638 reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0));
639 do {
640 reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0));
641 if (reg == val)
642 return 0;
643 usleep_range(delay, delay * 2);
644 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
645 } while (time_before(jiffies, end_jiffies) ||
646 !tegra_platform_is_silicon());
647
648 return -ETIMEDOUT;
649}
650
628static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) 651static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
629{ 652{
653 u32 err;
630 gk20a_dbg_fn(""); 654 gk20a_dbg_fn("");
631 655
632 if (tegra_platform_is_linsim()) { 656 if (tegra_platform_is_linsim()) {
@@ -636,16 +660,49 @@ static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
636 gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); 660 gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777));
637 } 661 }
638 662
663 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
664 gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS);
665
639 gr_gm20b_load_gpccs_with_bootloader(g); 666 gr_gm20b_load_gpccs_with_bootloader(g);
640 667
641 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), 0x0); 668 if (g->ops.pmu.fecsrecoveryinprogress) {
642 gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); 669 unsigned long timeout = gk20a_get_gr_idle_timeout(g);
643 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); 670 err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, 0x55AA55AA);
671 if (err) {
672 gk20a_err(dev_from_gk20a(g), "Unable to recover FECS");
673 return err;
674 } else {
675 g->ops.pmu.fecsrecoveryinprogress = 0;
676 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
677 gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1);
678 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6),
679 0xffffffff);
680
681 gk20a_writel(g, gr_gpccs_dmactl_r(),
682 gr_gpccs_dmactl_require_ctx_f(0));
683 gk20a_writel(g, gr_gpccs_cpuctl_r(),
684 gr_gpccs_cpuctl_startcpu_f(1));
685
686 gk20a_writel(g, gr_fecs_cpuctl_alias_r(),
687 gr_fecs_cpuctl_startcpu_f(1));
688 }
689 }
644 690
645 gk20a_writel(g, gr_gpccs_dmactl_r(), gr_gpccs_dmactl_require_ctx_f(0));
646 691
647 gk20a_writel(g, gr_gpccs_cpuctl_r(), gr_gpccs_cpuctl_startcpu_f(1)); 692 if (!g->ops.pmu.fecsbootstrapdone) {
648 gk20a_writel(g, gr_fecs_cpuctl_alias_r(), gr_fecs_cpuctl_startcpu_f(1)); 693 g->ops.pmu.fecsbootstrapdone = true;
694 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
695 gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1);
696 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff);
697
698 gk20a_writel(g, gr_gpccs_dmactl_r(),
699 gr_gpccs_dmactl_require_ctx_f(0));
700 gk20a_writel(g, gr_gpccs_cpuctl_r(),
701 gr_gpccs_cpuctl_startcpu_f(1));
702
703 gk20a_writel(g, gr_fecs_cpuctl_alias_r(),
704 gr_fecs_cpuctl_startcpu_f(1));
705 }
649 706
650 gk20a_dbg_fn("done"); 707 gk20a_dbg_fn("done");
651 708