summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/gr_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c96
1 files changed, 35 insertions, 61 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index e1204dad..6c7831d5 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -688,29 +688,9 @@ static void gr_gm20b_load_gpccs_with_bootloader(struct gk20a *g)
688 gr_fecs_falcon_hwcfg_r()); 688 gr_fecs_falcon_hwcfg_r());
689} 689}
690 690
691static int gr_gm20b_ctx_wait_lsf_ready(struct gk20a *g, u32 timeout, u32 val)
692{
693 unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
694 unsigned long delay = GR_FECS_POLL_INTERVAL;
695 u32 reg;
696
697 gk20a_dbg_fn("");
698 reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0));
699 do {
700 reg = gk20a_readl(g, gr_fecs_ctxsw_mailbox_r(0));
701 if (reg == val)
702 return 0;
703 udelay(delay);
704 } while (time_before(jiffies, end_jiffies) ||
705 !tegra_platform_is_silicon());
706
707 return -ETIMEDOUT;
708}
709
710static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) 691static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
711{ 692{
712 u32 err; 693 u32 err, flags;
713 unsigned long timeout = gk20a_get_gr_idle_timeout(g);
714 u32 reg_offset = gr_gpcs_gpccs_falcon_hwcfg_r() - 694 u32 reg_offset = gr_gpcs_gpccs_falcon_hwcfg_r() -
715 gr_fecs_falcon_hwcfg_r(); 695 gr_fecs_falcon_hwcfg_r();
716 696
@@ -723,63 +703,57 @@ static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
723 gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); 703 gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777));
724 } 704 }
725 705
706 flags = PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
707 g->ops.pmu.lsfloadedfalconid = 0;
726 if (g->ops.pmu.fecsbootstrapdone) { 708 if (g->ops.pmu.fecsbootstrapdone) {
727 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); 709 /* this must be recovery so bootstrap fecs and gpccs */
728 gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS); 710 if (!g->ops.securegpccs) {
729 err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, 0x55AA55AA); 711 gr_gm20b_load_gpccs_with_bootloader(g);
712 err = g->ops.pmu.load_lsfalcon_ucode(g,
713 (1 << LSF_FALCON_ID_FECS));
714 } else {
715 /* bind WPR VA inst block */
716 gr_gk20a_load_falcon_bind_instblk(g);
717 err = g->ops.pmu.load_lsfalcon_ucode(g,
718 (1 << LSF_FALCON_ID_FECS) |
719 (1 << LSF_FALCON_ID_GPCCS));
720 }
730 if (err) { 721 if (err) {
731 gk20a_err(dev_from_gk20a(g), "Unable to recover FECS"); 722 gk20a_err(dev_from_gk20a(g),
723 "Unable to recover GR falcon");
732 return err; 724 return err;
733 } else {
734 if (!g->ops.securegpccs) {
735 gr_gm20b_load_gpccs_with_bootloader(g);
736 gk20a_writel(g, gr_gpccs_dmactl_r(),
737 gr_gpccs_dmactl_require_ctx_f(0));
738 gk20a_writel(g, gr_gpccs_cpuctl_r(),
739 gr_gpccs_cpuctl_startcpu_f(1));
740 } else {
741 gk20a_writel(g,
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 }
750 } 725 }
726
751 } else { 727 } else {
728 /* cold boot or rg exit */
752 g->ops.pmu.fecsbootstrapdone = true; 729 g->ops.pmu.fecsbootstrapdone = true;
753 if (!g->ops.securegpccs) { 730 if (!g->ops.securegpccs) {
754 gr_gm20b_load_gpccs_with_bootloader(g); 731 gr_gm20b_load_gpccs_with_bootloader(g);
755 gk20a_writel(g, gr_gpccs_dmactl_r(),
756 gr_gpccs_dmactl_require_ctx_f(0));
757 gk20a_writel(g, gr_gpccs_cpuctl_r(),
758 gr_gpccs_cpuctl_startcpu_f(1));
759 } else { 732 } else {
760 pmu_wait_message_cond(&g->pmu, 733 /* bind WPR VA inst block */
761 gk20a_get_gr_idle_timeout(g), 734 gr_gk20a_load_falcon_bind_instblk(g);
762 &g->ops.pmu.lspmuwprinitdone, 1); 735 err = g->ops.pmu.load_lsfalcon_ucode(g,
763 if (!g->ops.pmu.lspmuwprinitdone) { 736 (1 << LSF_FALCON_ID_GPCCS));
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) { 737 if (err) {
773 gk20a_err(dev_from_gk20a(g), 738 gk20a_err(dev_from_gk20a(g),
774 "Unable to boot GPCCS\n"); 739 "Unable to boot GPCCS\n");
775 return err; 740 return err;
776 } 741 }
777 gk20a_writel(g, reg_offset +
778 gr_fecs_cpuctl_alias_r(),
779 gr_gpccs_cpuctl_startcpu_f(1));
780 } 742 }
781 } 743 }
782 744
745 /*start gpccs */
746 if (g->ops.securegpccs) {
747 gk20a_writel(g, reg_offset +
748 gr_fecs_cpuctl_alias_r(),
749 gr_gpccs_cpuctl_startcpu_f(1));
750 } else {
751 gk20a_writel(g, gr_gpccs_dmactl_r(),
752 gr_gpccs_dmactl_require_ctx_f(0));
753 gk20a_writel(g, gr_gpccs_cpuctl_r(),
754 gr_gpccs_cpuctl_startcpu_f(1));
755 }
756 /* start fecs */
783 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); 757 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
784 gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); 758 gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1);
785 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); 759 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff);