summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gr_gk20a.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/gk20a/gr_gk20a.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/gk20a/gr_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c105
1 files changed, 86 insertions, 19 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 84b79b42..30ea49a7 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -1776,9 +1776,17 @@ static int gr_gk20a_copy_ctxsw_ucode_segments(
1776 u32 *bootimage, 1776 u32 *bootimage,
1777 u32 *code, u32 *data) 1777 u32 *code, u32 *data)
1778{ 1778{
1779 int i;
1780
1779 memcpy(buf + segments->boot.offset, bootimage, segments->boot.size); 1781 memcpy(buf + segments->boot.offset, bootimage, segments->boot.size);
1780 memcpy(buf + segments->code.offset, code, segments->code.size); 1782 memcpy(buf + segments->code.offset, code, segments->code.size);
1781 memcpy(buf + segments->data.offset, data, segments->data.size); 1783 memcpy(buf + segments->data.offset, data, segments->data.size);
1784
1785 /* compute a "checksum" for the boot binary to detect its version */
1786 segments->boot_signature = 0;
1787 for (i = 0; i < segments->boot.size / sizeof(u32); i++)
1788 segments->boot_signature += bootimage[i];
1789
1782 return 0; 1790 return 0;
1783} 1791}
1784 1792
@@ -1968,22 +1976,14 @@ void gr_gk20a_load_falcon_bind_instblk(struct gk20a *g)
1968 gk20a_err(dev_from_gk20a(g), "arbiter complete timeout"); 1976 gk20a_err(dev_from_gk20a(g), "arbiter complete timeout");
1969} 1977}
1970 1978
1971static int gr_gk20a_load_ctxsw_ucode_segments(struct gk20a *g, u64 addr_base, 1979void gr_gk20a_load_ctxsw_ucode_header(struct gk20a *g, u64 addr_base,
1972 struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset) 1980 struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset)
1973{ 1981{
1974 u32 addr_code32; 1982 u32 addr_code32;
1975 u32 addr_data32; 1983 u32 addr_data32;
1976 u32 addr_load32;
1977 u32 dst = 0;
1978 u32 blocks;
1979 u32 b;
1980 1984
1981 addr_code32 = u64_lo32((addr_base + segments->code.offset) >> 8); 1985 addr_code32 = u64_lo32((addr_base + segments->code.offset) >> 8);
1982 addr_data32 = u64_lo32((addr_base + segments->data.offset) >> 8); 1986 addr_data32 = u64_lo32((addr_base + segments->data.offset) >> 8);
1983 addr_load32 = u64_lo32((addr_base + segments->boot.offset) >> 8);
1984
1985 gk20a_writel(g, reg_offset + gr_fecs_dmactl_r(),
1986 gr_fecs_dmactl_require_ctx_f(0));
1987 1987
1988 /* 1988 /*
1989 * Copy falcon bootloader header into dmem at offset 0. 1989 * Copy falcon bootloader header into dmem at offset 0.
@@ -1996,17 +1996,73 @@ static int gr_gk20a_load_ctxsw_ucode_segments(struct gk20a *g, u64 addr_base,
1996 gr_fecs_dmemc_aincw_f(1)); 1996 gr_fecs_dmemc_aincw_f(1));
1997 1997
1998 /* Write out the actual data */ 1998 /* Write out the actual data */
1999 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); 1999 switch (segments->boot_signature) {
2000 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), addr_code32); 2000 case FALCON_UCODE_SIG_T12X_FECS_WITH_RESERVED:
2001 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); 2001 case FALCON_UCODE_SIG_T12X_GPCCS_WITH_RESERVED:
2002 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), segments->code.size); 2002 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2003 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); 2003 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2004 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), addr_data32); 2004 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2005 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), segments->data.size); 2005 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2006 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), addr_code32); 2006 /* fallthrough */
2007 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); 2007 case FALCON_UCODE_SIG_T12X_FECS_WITHOUT_RESERVED:
2008 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0); 2008 case FALCON_UCODE_SIG_T12X_GPCCS_WITHOUT_RESERVED:
2009 case FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED:
2010 case FALCON_UCODE_SIG_T21X_FECS_WITHOUT_RESERVED2:
2011 case FALCON_UCODE_SIG_T21X_GPCCS_WITHOUT_RESERVED:
2012 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2013 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2014 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2015 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2016 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 4);
2017 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2018 addr_code32);
2019 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2020 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2021 segments->code.size);
2022 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2023 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2024 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2025 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2026 addr_data32);
2027 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2028 segments->data.size);
2029 break;
2030 case FALCON_UCODE_SIG_T12X_FECS_OLDER:
2031 case FALCON_UCODE_SIG_T12X_GPCCS_OLDER:
2032 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2033 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2034 addr_code32);
2035 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2036 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2037 segments->code.size);
2038 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2039 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2040 addr_data32);
2041 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2042 segments->data.size);
2043 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0),
2044 addr_code32);
2045 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2046 gk20a_writel(g, reg_offset + gr_fecs_dmemd_r(0), 0);
2047 break;
2048 default:
2049 gk20a_err(dev_from_gk20a(g),
2050 "unknown falcon ucode boot signature 0x%08x"
2051 " with reg_offset 0x%08x",
2052 segments->boot_signature, reg_offset);
2053 BUG();
2054 }
2055}
2056
2057void gr_gk20a_load_ctxsw_ucode_boot(struct gk20a *g, u64 addr_base,
2058 struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset)
2059{
2060 u32 addr_load32;
2061 u32 blocks;
2062 u32 b;
2063 u32 dst;
2009 2064
2065 addr_load32 = u64_lo32((addr_base + segments->boot.offset) >> 8);
2010 blocks = ((segments->boot.size + 0xFF) & ~0xFF) >> 8; 2066 blocks = ((segments->boot.size + 0xFF) & ~0xFF) >> 8;
2011 2067
2012 /* 2068 /*
@@ -2038,6 +2094,17 @@ static int gr_gk20a_load_ctxsw_ucode_segments(struct gk20a *g, u64 addr_base,
2038 /* Specify the falcon boot vector */ 2094 /* Specify the falcon boot vector */
2039 gk20a_writel(g, reg_offset + gr_fecs_bootvec_r(), 2095 gk20a_writel(g, reg_offset + gr_fecs_bootvec_r(),
2040 gr_fecs_bootvec_vec_f(segments->boot_entry)); 2096 gr_fecs_bootvec_vec_f(segments->boot_entry));
2097}
2098
2099int gr_gk20a_load_ctxsw_ucode_segments(struct gk20a *g, u64 addr_base,
2100 struct gk20a_ctxsw_ucode_segments *segments, u32 reg_offset)
2101{
2102 gk20a_writel(g, reg_offset + gr_fecs_dmactl_r(),
2103 gr_fecs_dmactl_require_ctx_f(0));
2104
2105 /* Copy falcon bootloader into dmem */
2106 gr_gk20a_load_ctxsw_ucode_header(g, addr_base, segments, reg_offset);
2107 gr_gk20a_load_ctxsw_ucode_boot(g, addr_base, segments, reg_offset);
2041 2108
2042 /* Write to CPUCTL to start the falcon */ 2109 /* Write to CPUCTL to start the falcon */
2043 gk20a_writel(g, reg_offset + gr_fecs_cpuctl_r(), 2110 gk20a_writel(g, reg_offset + gr_fecs_cpuctl_r(),