diff options
author | Vijayakumar <vsubbu@nvidia.com> | 2015-04-09 07:17:13 -0400 |
---|---|---|
committer | Ishan Mittal <imittal@nvidia.com> | 2015-05-18 02:03:44 -0400 |
commit | d65a93b80c60bb677fbc13b7180e0f31b7f97f84 (patch) | |
tree | da92083e7565c8d82f4f8bd7d06dab20b4f61e1a /drivers/gpu/nvgpu/gm20b/gr_gm20b.c | |
parent | 6a5cc111713cec1d0e1edf9b8a1e64eb17105d9c (diff) |
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 <vsubbu@nvidia.com>
Reviewed-on: http://git-master/r/729622
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.c | 86 |
1 files changed, 54 insertions, 32 deletions
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) | |||
710 | static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) | 710 | static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) |
711 | { | 711 | { |
712 | u32 err; | 712 | u32 err; |
713 | unsigned long timeout = gk20a_get_gr_idle_timeout(g); | ||
714 | u32 reg_offset = gr_gpcs_gpccs_falcon_hwcfg_r() - | ||
715 | gr_fecs_falcon_hwcfg_r(); | ||
716 | |||
713 | gk20a_dbg_fn(""); | 717 | gk20a_dbg_fn(""); |
714 | 718 | ||
715 | if (tegra_platform_is_linsim()) { | 719 | if (tegra_platform_is_linsim()) { |
@@ -719,50 +723,68 @@ static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) | |||
719 | gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); | 723 | gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); |
720 | } | 724 | } |
721 | 725 | ||
722 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); | 726 | if (g->ops.pmu.fecsbootstrapdone) { |
723 | gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS); | 727 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); |
724 | 728 | gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS); | |
725 | gr_gm20b_load_gpccs_with_bootloader(g); | ||
726 | |||
727 | if (g->ops.pmu.fecsrecoveryinprogress) { | ||
728 | unsigned long timeout = gk20a_get_gr_idle_timeout(g); | ||
729 | err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, 0x55AA55AA); | 729 | err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, 0x55AA55AA); |
730 | if (err) { | 730 | if (err) { |
731 | gk20a_err(dev_from_gk20a(g), "Unable to recover FECS"); | 731 | gk20a_err(dev_from_gk20a(g), "Unable to recover FECS"); |
732 | return err; | 732 | return err; |
733 | } else { | 733 | } else { |
734 | g->ops.pmu.fecsrecoveryinprogress = 0; | 734 | if (!g->ops.securegpccs) { |
735 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); | 735 | gr_gm20b_load_gpccs_with_bootloader(g); |
736 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); | 736 | gk20a_writel(g, gr_gpccs_dmactl_r(), |
737 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), | ||
738 | 0xffffffff); | ||
739 | |||
740 | gk20a_writel(g, gr_gpccs_dmactl_r(), | ||
741 | gr_gpccs_dmactl_require_ctx_f(0)); | 737 | gr_gpccs_dmactl_require_ctx_f(0)); |
742 | gk20a_writel(g, gr_gpccs_cpuctl_r(), | 738 | gk20a_writel(g, gr_gpccs_cpuctl_r(), |
743 | gr_gpccs_cpuctl_startcpu_f(1)); | 739 | gr_gpccs_cpuctl_startcpu_f(1)); |
744 | 740 | } else { | |
745 | gk20a_writel(g, gr_fecs_cpuctl_alias_r(), | 741 | gk20a_writel(g, |
746 | gr_fecs_cpuctl_startcpu_f(1)); | 742 | gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); |
743 | gm20b_pmu_load_lsf(g, LSF_FALCON_ID_GPCCS); | ||
744 | err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, | ||
745 | 0x55AA55AA); | ||
746 | gk20a_writel(g, reg_offset + | ||
747 | gr_fecs_cpuctl_alias_r(), | ||
748 | gr_gpccs_cpuctl_startcpu_f(1)); | ||
749 | } | ||
747 | } | 750 | } |
748 | } | 751 | } else { |
749 | |||
750 | |||
751 | if (!g->ops.pmu.fecsbootstrapdone) { | ||
752 | g->ops.pmu.fecsbootstrapdone = true; | 752 | g->ops.pmu.fecsbootstrapdone = true; |
753 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); | 753 | if (!g->ops.securegpccs) { |
754 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); | 754 | gr_gm20b_load_gpccs_with_bootloader(g); |
755 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); | 755 | gk20a_writel(g, gr_gpccs_dmactl_r(), |
756 | 756 | gr_gpccs_dmactl_require_ctx_f(0)); | |
757 | gk20a_writel(g, gr_gpccs_dmactl_r(), | 757 | gk20a_writel(g, gr_gpccs_cpuctl_r(), |
758 | gr_gpccs_dmactl_require_ctx_f(0)); | 758 | gr_gpccs_cpuctl_startcpu_f(1)); |
759 | gk20a_writel(g, gr_gpccs_cpuctl_r(), | 759 | } else { |
760 | pmu_wait_message_cond(&g->pmu, | ||
761 | gk20a_get_gr_idle_timeout(g), | ||
762 | &g->ops.pmu.lspmuwprinitdone, 1); | ||
763 | if (!g->ops.pmu.lspmuwprinitdone) { | ||
764 | gk20a_err(dev_from_gk20a(g), | ||
765 | "PMU WPR needed but not ready yet"); | ||
766 | return -ETIMEDOUT; | ||
767 | } | ||
768 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); | ||
769 | gm20b_pmu_load_lsf(g, LSF_FALCON_ID_GPCCS); | ||
770 | err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, | ||
771 | 0x55AA55AA); | ||
772 | if (err) { | ||
773 | gk20a_err(dev_from_gk20a(g), | ||
774 | "Unable to boot GPCCS\n"); | ||
775 | return err; | ||
776 | } | ||
777 | gk20a_writel(g, reg_offset + | ||
778 | gr_fecs_cpuctl_alias_r(), | ||
760 | gr_gpccs_cpuctl_startcpu_f(1)); | 779 | gr_gpccs_cpuctl_startcpu_f(1)); |
761 | 780 | } | |
762 | gk20a_writel(g, gr_fecs_cpuctl_alias_r(), | ||
763 | gr_fecs_cpuctl_startcpu_f(1)); | ||
764 | } | 781 | } |
765 | 782 | ||
783 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); | ||
784 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); | ||
785 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); | ||
786 | gk20a_writel(g, gr_fecs_cpuctl_alias_r(), | ||
787 | gr_fecs_cpuctl_startcpu_f(1)); | ||
766 | gk20a_dbg_fn("done"); | 788 | gk20a_dbg_fn("done"); |
767 | 789 | ||
768 | return 0; | 790 | return 0; |