gpu: nvgpu: gp10b: dma support for secure gpccs

bug 200080684

Change-Id: I013a0ca7762f6cca0498bd282303597bf683cb7d
Signed-off-by: Vijayakumar <vsubbu@nvidia.com>
Reviewed-on: http://git-master/r/746737
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Vijayakumar
2015-05-25 15:01:04 +05:30
committed by Deepak Nibade
parent 8d354418ec
commit 4c074ba302
2 changed files with 76 additions and 1 deletions

View File

@@ -3,7 +3,7 @@
*
* GM20B Graphics Context
*
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -69,4 +69,5 @@ static bool gr_gp10b_is_firmware_defined(void)
void gp10b_init_gr_ctx(struct gpu_ops *gops) {
gops->gr_ctx.get_netlist_name = gr_gp10b_get_netlist_name;
gops->gr_ctx.is_fw_defined = gr_gp10b_is_firmware_defined;
gops->gr_ctx.use_dma_for_fw_bootstrap = false;
}

View File

@@ -21,6 +21,8 @@
#include "pmu_gp10b.h"
#define gp10b_dbg_pmu(fmt, arg...) \
gk20a_dbg(gpu_dbg_pmu, fmt, ##arg)
/*!
* Structure/object which single register write need to be done during PG init
* sequence to set PROD values.
@@ -130,6 +132,76 @@ static struct pg_init_sequence_list _pginitseq_gp10b[] = {
{0x0010e004, 0x0000008E},
};
void gp10b_pmu_load_multiple_falcons(struct gk20a *g, u32 falconidmask,
u32 flags)
{
struct pmu_gk20a *pmu = &g->pmu;
struct pmu_cmd cmd;
u32 seq;
gk20a_dbg_fn("");
gp10b_dbg_pmu("wprinit status = %x\n", g->ops.pmu.lspmuwprinitdone);
if (g->ops.pmu.lspmuwprinitdone) {
/* send message to load FECS falcon */
memset(&cmd, 0, sizeof(struct pmu_cmd));
cmd.hdr.unit_id = PMU_UNIT_ACR;
cmd.hdr.size = PMU_CMD_HDR_SIZE +
sizeof(struct pmu_acr_cmd_bootstrap_multiple_falcons);
cmd.cmd.acr.boot_falcons.cmd_type =
PMU_ACR_CMD_ID_BOOTSTRAP_MULTIPLE_FALCONS;
cmd.cmd.acr.boot_falcons.flags = flags;
cmd.cmd.acr.boot_falcons.falconidmask =
falconidmask;
cmd.cmd.acr.boot_falcons.usevamask =
1 << LSF_FALCON_ID_GPCCS;
cmd.cmd.acr.boot_falcons.wprvirtualbase.lo =
u64_lo32(g->pmu.wpr_buf.gpu_va);
cmd.cmd.acr.boot_falcons.wprvirtualbase.hi =
u64_hi32(g->pmu.wpr_buf.gpu_va);
gp10b_dbg_pmu("PMU_ACR_CMD_ID_BOOTSTRAP_MULTIPLE_FALCONS:%x\n",
falconidmask);
gk20a_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ,
pmu_handle_fecs_boot_acr_msg, pmu, &seq, ~0);
}
gk20a_dbg_fn("done");
return;
}
int gp10b_load_falcon_ucode(struct gk20a *g, u32 falconidmask)
{
u32 flags = PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
/* GM20B PMU supports loading FECS and GPCCS only */
if (falconidmask == 0)
return -EINVAL;
if (falconidmask & ~((1 << LSF_FALCON_ID_FECS) |
(1 << LSF_FALCON_ID_GPCCS)))
return -EINVAL;
g->ops.pmu.lsfloadedfalconid = 0;
/* check whether pmu is ready to bootstrap lsf if not wait for it */
if (!g->ops.pmu.lspmuwprinitdone) {
pmu_wait_message_cond(&g->pmu,
gk20a_get_gr_idle_timeout(g),
&g->ops.pmu.lspmuwprinitdone, 1);
/* check again if it still not ready indicate an error */
if (!g->ops.pmu.lspmuwprinitdone) {
gk20a_err(dev_from_gk20a(g),
"PMU not ready to load LSF");
return -ETIMEDOUT;
}
}
/* load falcon(s) */
gp10b_pmu_load_multiple_falcons(g, falconidmask, flags);
pmu_wait_message_cond(&g->pmu,
gk20a_get_gr_idle_timeout(g),
&g->ops.pmu.lsfloadedfalconid, falconidmask);
if (g->ops.pmu.lsfloadedfalconid != falconidmask)
return -ETIMEDOUT;
return 0;
}
static int gp10b_pmu_setup_elpg(struct gk20a *g)
{
int ret = 0;
@@ -157,8 +229,10 @@ void gp10b_init_pmu_ops(struct gpu_ops *gops)
if (gops->privsecurity) {
gm20b_init_secure_pmu(gops);
gops->pmu.init_wpr_region = gm20b_pmu_init_acr;
gops->pmu.load_lsfalcon_ucode = gp10b_load_falcon_ucode;
} else {
gk20a_init_pmu_ops(gops);
gops->pmu.load_lsfalcon_ucode = NULL;
gops->pmu.init_wpr_region = NULL;
}
gops->pmu.pmu_setup_elpg = gp10b_pmu_setup_elpg;