mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: Use old ctxsw boot method on gm20b
Boot FECS/GPCCS with old method on gm20b. We don't yet have bootloader for it. Change-Id: I09046960cd86b0402d3ea2cd8e4c92597766fa10 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/412604 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Arto Merilainen <amerilainen@nvidia.com> Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Tested-by: Seshendra Gadagottu <sgadagottu@nvidia.com>
This commit is contained in:
committed by
Dan Willemsen
parent
e6b3d1e87f
commit
af8c1dc3a8
@@ -162,6 +162,123 @@ void gk20a_fecs_dump_falcon_stats(struct gk20a *g)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gr_gk20a_load_falcon_dmem(struct gk20a *g)
|
||||||
|
{
|
||||||
|
u32 i, ucode_u32_size;
|
||||||
|
const u32 *ucode_u32_data;
|
||||||
|
u32 checksum;
|
||||||
|
|
||||||
|
gk20a_dbg_fn("");
|
||||||
|
|
||||||
|
gk20a_writel(g, gr_gpccs_dmemc_r(0), (gr_gpccs_dmemc_offs_f(0) |
|
||||||
|
gr_gpccs_dmemc_blk_f(0) |
|
||||||
|
gr_gpccs_dmemc_aincw_f(1)));
|
||||||
|
|
||||||
|
ucode_u32_size = g->gr.ctx_vars.ucode.gpccs.data.count;
|
||||||
|
ucode_u32_data = (const u32 *)g->gr.ctx_vars.ucode.gpccs.data.l;
|
||||||
|
|
||||||
|
for (i = 0, checksum = 0; i < ucode_u32_size; i++) {
|
||||||
|
gk20a_writel(g, gr_gpccs_dmemd_r(0), ucode_u32_data[i]);
|
||||||
|
checksum += ucode_u32_data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
gk20a_writel(g, gr_fecs_dmemc_r(0), (gr_fecs_dmemc_offs_f(0) |
|
||||||
|
gr_fecs_dmemc_blk_f(0) |
|
||||||
|
gr_fecs_dmemc_aincw_f(1)));
|
||||||
|
|
||||||
|
ucode_u32_size = g->gr.ctx_vars.ucode.fecs.data.count;
|
||||||
|
ucode_u32_data = (const u32 *)g->gr.ctx_vars.ucode.fecs.data.l;
|
||||||
|
|
||||||
|
for (i = 0, checksum = 0; i < ucode_u32_size; i++) {
|
||||||
|
gk20a_writel(g, gr_fecs_dmemd_r(0), ucode_u32_data[i]);
|
||||||
|
checksum += ucode_u32_data[i];
|
||||||
|
}
|
||||||
|
gk20a_dbg_fn("done");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gr_gk20a_load_falcon_imem(struct gk20a *g)
|
||||||
|
{
|
||||||
|
u32 cfg, fecs_imem_size, gpccs_imem_size, ucode_u32_size;
|
||||||
|
const u32 *ucode_u32_data;
|
||||||
|
u32 tag, i, pad_start, pad_end;
|
||||||
|
u32 checksum;
|
||||||
|
|
||||||
|
gk20a_dbg_fn("");
|
||||||
|
|
||||||
|
cfg = gk20a_readl(g, gr_fecs_cfg_r());
|
||||||
|
fecs_imem_size = gr_fecs_cfg_imem_sz_v(cfg);
|
||||||
|
|
||||||
|
cfg = gk20a_readl(g, gr_gpc0_cfg_r());
|
||||||
|
gpccs_imem_size = gr_gpc0_cfg_imem_sz_v(cfg);
|
||||||
|
|
||||||
|
/* Use the broadcast address to access all of the GPCCS units. */
|
||||||
|
gk20a_writel(g, gr_gpccs_imemc_r(0), (gr_gpccs_imemc_offs_f(0) |
|
||||||
|
gr_gpccs_imemc_blk_f(0) |
|
||||||
|
gr_gpccs_imemc_aincw_f(1)));
|
||||||
|
|
||||||
|
/* Setup the tags for the instruction memory. */
|
||||||
|
tag = 0;
|
||||||
|
gk20a_writel(g, gr_gpccs_imemt_r(0), gr_gpccs_imemt_tag_f(tag));
|
||||||
|
|
||||||
|
ucode_u32_size = g->gr.ctx_vars.ucode.gpccs.inst.count;
|
||||||
|
ucode_u32_data = (const u32 *)g->gr.ctx_vars.ucode.gpccs.inst.l;
|
||||||
|
|
||||||
|
for (i = 0, checksum = 0; i < ucode_u32_size; i++) {
|
||||||
|
if (i && ((i % (256/sizeof(u32))) == 0)) {
|
||||||
|
tag++;
|
||||||
|
gk20a_writel(g, gr_gpccs_imemt_r(0),
|
||||||
|
gr_gpccs_imemt_tag_f(tag));
|
||||||
|
}
|
||||||
|
gk20a_writel(g, gr_gpccs_imemd_r(0), ucode_u32_data[i]);
|
||||||
|
checksum += ucode_u32_data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
pad_start = i*4;
|
||||||
|
pad_end = pad_start+(256-pad_start%256)+256;
|
||||||
|
for (i = pad_start;
|
||||||
|
(i < gpccs_imem_size * 256) && (i < pad_end);
|
||||||
|
i += 4) {
|
||||||
|
if (i && ((i % 256) == 0)) {
|
||||||
|
tag++;
|
||||||
|
gk20a_writel(g, gr_gpccs_imemt_r(0),
|
||||||
|
gr_gpccs_imemt_tag_f(tag));
|
||||||
|
}
|
||||||
|
gk20a_writel(g, gr_gpccs_imemd_r(0), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
gk20a_writel(g, gr_fecs_imemc_r(0), (gr_fecs_imemc_offs_f(0) |
|
||||||
|
gr_fecs_imemc_blk_f(0) |
|
||||||
|
gr_fecs_imemc_aincw_f(1)));
|
||||||
|
|
||||||
|
/* Setup the tags for the instruction memory. */
|
||||||
|
tag = 0;
|
||||||
|
gk20a_writel(g, gr_fecs_imemt_r(0), gr_fecs_imemt_tag_f(tag));
|
||||||
|
|
||||||
|
ucode_u32_size = g->gr.ctx_vars.ucode.fecs.inst.count;
|
||||||
|
ucode_u32_data = (const u32 *)g->gr.ctx_vars.ucode.fecs.inst.l;
|
||||||
|
|
||||||
|
for (i = 0, checksum = 0; i < ucode_u32_size; i++) {
|
||||||
|
if (i && ((i % (256/sizeof(u32))) == 0)) {
|
||||||
|
tag++;
|
||||||
|
gk20a_writel(g, gr_fecs_imemt_r(0),
|
||||||
|
gr_fecs_imemt_tag_f(tag));
|
||||||
|
}
|
||||||
|
gk20a_writel(g, gr_fecs_imemd_r(0), ucode_u32_data[i]);
|
||||||
|
checksum += ucode_u32_data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
pad_start = i*4;
|
||||||
|
pad_end = pad_start+(256-pad_start%256)+256;
|
||||||
|
for (i = pad_start; (i < fecs_imem_size * 256) && i < pad_end; i += 4) {
|
||||||
|
if (i && ((i % 256) == 0)) {
|
||||||
|
tag++;
|
||||||
|
gk20a_writel(g, gr_fecs_imemt_r(0),
|
||||||
|
gr_fecs_imemt_tag_f(tag));
|
||||||
|
}
|
||||||
|
gk20a_writel(g, gr_fecs_imemd_r(0), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies,
|
static int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies,
|
||||||
u32 expect_delay)
|
u32 expect_delay)
|
||||||
{
|
{
|
||||||
@@ -1646,6 +1763,22 @@ static int gr_gk20a_load_golden_ctx_image(struct gk20a *g,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gr_gk20a_start_falcon_ucode(struct gk20a *g)
|
||||||
|
{
|
||||||
|
gk20a_dbg_fn("");
|
||||||
|
|
||||||
|
gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0),
|
||||||
|
gr_fecs_ctxsw_mailbox_clear_value_f(~0));
|
||||||
|
|
||||||
|
gk20a_writel(g, gr_gpccs_dmactl_r(), gr_gpccs_dmactl_require_ctx_f(0));
|
||||||
|
gk20a_writel(g, gr_fecs_dmactl_r(), gr_fecs_dmactl_require_ctx_f(0));
|
||||||
|
|
||||||
|
gk20a_writel(g, gr_gpccs_cpuctl_r(), gr_gpccs_cpuctl_startcpu_f(1));
|
||||||
|
gk20a_writel(g, gr_fecs_cpuctl_r(), gr_fecs_cpuctl_startcpu_f(1));
|
||||||
|
|
||||||
|
gk20a_dbg_fn("done");
|
||||||
|
}
|
||||||
|
|
||||||
static int gr_gk20a_init_ctxsw_ucode_vaspace(struct gk20a *g)
|
static int gr_gk20a_init_ctxsw_ucode_vaspace(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct mm_gk20a *mm = &g->mm;
|
struct mm_gk20a *mm = &g->mm;
|
||||||
@@ -2030,10 +2163,20 @@ static int gr_gk20a_load_ctxsw_ucode(struct gk20a *g, struct gr_gk20a *gr)
|
|||||||
gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777));
|
gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gr->skip_ucode_init)
|
/*
|
||||||
gr_gk20a_init_ctxsw_ucode(g);
|
* In case bootloader is not supported, revert to the old way of
|
||||||
gr_gk20a_load_falcon_with_bootloader(g);
|
* loading gr ucode, without the faster bootstrap routine.
|
||||||
gr->skip_ucode_init = true;
|
*/
|
||||||
|
if (g->gpu_characteristics.arch == NVHOST_GPU_ARCH_GM200) {
|
||||||
|
gr_gk20a_load_falcon_dmem(g);
|
||||||
|
gr_gk20a_load_falcon_imem(g);
|
||||||
|
gr_gk20a_start_falcon_ucode(g);
|
||||||
|
} else {
|
||||||
|
if (!gr->skip_ucode_init)
|
||||||
|
gr_gk20a_init_ctxsw_ucode(g);
|
||||||
|
gr_gk20a_load_falcon_with_bootloader(g);
|
||||||
|
gr->skip_ucode_init = true;
|
||||||
|
}
|
||||||
|
|
||||||
ret = gr_gk20a_ctx_wait_ucode(g, 0, 0,
|
ret = gr_gk20a_ctx_wait_ucode(g, 0, 0,
|
||||||
GR_IS_UCODE_OP_EQUAL,
|
GR_IS_UCODE_OP_EQUAL,
|
||||||
|
|||||||
Reference in New Issue
Block a user