summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2014-10-14 04:48:40 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:49 -0400
commit3f3844a11ccac7957fdb7139a1c9c2a767d315a5 (patch)
tree728a145ec168983d833dcb1de04d5dab84bb43e7 /drivers/gpu/nvgpu/gm20b/gr_gm20b.c
parenta870ff1d294126a3b46db4e0fdc14276035a2840 (diff)
gpu: nvgpu: select ucode boot init by signature
Compute a signature checksum for ctxsw ucode boot section and determine the format of boot initialization data by it. This unifies gk20a and gk20b ucode segment loading a lot by separating the bootloader loading logic to separate functions. Note: Whenever the boot segment binary changes, its updated signature must be added here. Management of different bootloaders must be supported for repo-crossing staging issues. Bug 1519397 Change-Id: I96f9b905d3631dfdebf71ea3a652a0968615fd0a Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/556679 GVS: Gerrit_Virtual_Submit 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.c70
1 files changed, 3 insertions, 67 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index 1256d4a6..660ffa88 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -595,76 +595,12 @@ static int gr_gm20b_ctx_state_floorsweep(struct gk20a *g)
595static int gr_gm20b_load_ctxsw_ucode_segments(struct gk20a *g, u64 addr_base, 595static int gr_gm20b_load_ctxsw_ucode_segments(struct gk20a *g, u64 addr_base,
596 struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset) 596 struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset)
597{ 597{
598 u32 addr_code32;
599 u32 addr_data32;
600 u32 addr_load32;
601 u32 dst = 0;
602 u32 blocks;
603 u32 b;
604
605 addr_code32 = u64_lo32((addr_base + segments->code.offset) >> 8);
606 addr_data32 = u64_lo32((addr_base + segments->data.offset) >> 8);
607 addr_load32 = u64_lo32((addr_base + segments->boot.offset) >> 8);
608
609 gk20a_writel(g, reg_offset + gr_fecs_dmactl_r(), 598 gk20a_writel(g, reg_offset + gr_fecs_dmactl_r(),
610 gr_fecs_dmactl_require_ctx_f(0)); 599 gr_fecs_dmactl_require_ctx_f(0));
611 600
612 /* 601 /* Copy falcon bootloader into dmem */
613 * Copy falcon bootloader header into dmem at offset 0. 602 gr_gk20a_load_ctxsw_ucode_header(g, addr_base, segments, reg_offset);
614 * Configure dmem port 0 for auto-incrementing writes starting at dmem 603 gr_gk20a_load_ctxsw_ucode_boot(g, addr_base, segments, reg_offset);
615 * offset 0.
616 */
617 gk20a_writel(g, reg_offset + gr_fecs_dmemc_r(0),
618 gr_fecs_dmemc_offs_f(0) |
619 gr_fecs_dmemc_blk_f(0) |
620 gr_fecs_dmemc_aincw_f(1));
621
622 /* Write out the actual data */
623 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
624 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
625 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
626 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
627 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 4);
628 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), addr_code32);
629 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
630 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), segments->code.size);
631 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
632 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
633 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
634 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), addr_data32);
635 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), segments->data.size);
636
637 blocks = ((segments->boot.size + 0xFF) & ~0xFF) >> 8;
638
639 /*
640 * Set the base FB address for the DMA transfer. Subtract off the 256
641 * byte IMEM block offset such that the relative FB and IMEM offsets
642 * match, allowing the IMEM tags to be properly created.
643 */
644
645 dst = segments->boot_imem_offset;
646 gk20a_writel(g, reg_offset + gr_fecs_dmatrfbase_r(),
647 (addr_load32 - (dst >> 8)));
648
649 for (b = 0; b < blocks; b++) {
650 /* Setup destination IMEM offset */
651 gk20a_writel(g, reg_offset + gr_fecs_dmatrfmoffs_r(),
652 dst + (b << 8));
653
654 /* Setup source offset (relative to BASE) */
655 gk20a_writel(g, reg_offset + gr_fecs_dmatrffboffs_r(),
656 dst + (b << 8));
657
658 gk20a_writel(g, reg_offset + gr_fecs_dmatrfcmd_r(),
659 gr_fecs_dmatrfcmd_imem_f(0x01) |
660 gr_fecs_dmatrfcmd_write_f(0x00) |
661 gr_fecs_dmatrfcmd_size_f(0x06) |
662 gr_fecs_dmatrfcmd_ctxdma_f(0));
663 }
664
665 /* Specify the falcon boot vector */
666 gk20a_writel(g, reg_offset + gr_fecs_bootvec_r(),
667 gr_fecs_bootvec_vec_f(segments->boot_entry));
668 604
669 /* start the falcon immediately if PRIV security is disabled*/ 605 /* start the falcon immediately if PRIV security is disabled*/
670 if (!g->ops.privsecurity) { 606 if (!g->ops.privsecurity) {