gpu: nvgpu: gm20b: dynamically detect priv security for secure boot of falcon

based on the config setting and fuse secure no non secure boot is done

Change-Id: I5937ba945c5a3a86f72e0f2a9078fcde01977137
Signed-off-by: Vijayakumar <vsubbu@nvidia.com>
Reviewed-on: http://git-master/r/487684
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Vijayakumar
2014-08-22 17:22:57 +05:30
committed by Dan Willemsen
parent 08983f727f
commit a52a50d407
6 changed files with 57 additions and 17 deletions

View File

@@ -297,6 +297,7 @@ struct gpu_ops {
int (*init_clk_support)(struct gk20a *g);
int (*suspend_clk_support)(struct gk20a *g);
} clk;
bool privsecurity;
};
struct gk20a {

View File

@@ -26,7 +26,9 @@ int gpu_init_hal(struct gk20a *g)
gk20a_init_hal(&g->ops);
break;
case GK20A_GPUID_GM20B:
gm20b_init_hal(&g->ops);
gk20a_dbg_info("gm20b detected");
if (gm20b_init_hal(&g->ops))
return -ENODEV;
break;
default:
gk20a_err(&g->dev->dev, "no support for %x", ver);

View File

@@ -44,6 +44,7 @@ struct gpu_ops gk20a_ops = {
int gk20a_init_hal(struct gpu_ops *gops)
{
*gops = gk20a_ops;
gops->privsecurity = 0;
gk20a_init_ltc(gops);
gk20a_init_gr_ops(gops);
gk20a_init_fb(gops);

View File

@@ -31,12 +31,11 @@ static void gr_gm20b_init_gpc_mmu(struct gk20a *g)
gk20a_dbg_info("initialize gpc mmu");
#ifndef CONFIG_TEGRA_ACR
/* Bypass MMU check for non-secure boot. For
* secure-boot,this register write has no-effect */
gk20a_writel(g, fb_priv_mmu_phy_secure_r(), 0xffffffff);
#endif
if (!g->ops.privsecurity) {
/* Bypass MMU check for non-secure boot. For
* secure-boot,this register write has no-effect */
gk20a_writel(g, fb_priv_mmu_phy_secure_r(), 0xffffffff);
}
temp = gk20a_readl(g, fb_mmu_ctrl_r());
temp &= gr_gpcs_pri_mmu_ctrl_vm_pg_size_m() |
gr_gpcs_pri_mmu_ctrl_use_pdb_big_page_size_m() |
@@ -722,6 +721,13 @@ static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
return 0;
}
#else
static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
{
return -EPERM;
}
#endif
void gm20b_init_gr(struct gpu_ops *gops)
@@ -745,11 +751,10 @@ void gm20b_init_gr(struct gpu_ops *gops)
gops->gr.init_fs_state = gr_gm20b_ctx_state_floorsweep;
gops->gr.set_hww_esr_report_mask = gr_gm20b_set_hww_esr_report_mask;
gops->gr.falcon_load_ucode = gr_gm20b_load_ctxsw_ucode_segments;
#ifdef CONFIG_TEGRA_ACR
gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode;
#else
gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode;
#endif
if (gops->privsecurity)
gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode;
else
gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode;
gops->gr.get_gpc_tpc_mask = gr_gm20b_get_gpc_tpc_mask;
gops->gr.free_channel_ctx = gk20a_free_channel_ctx;
gops->gr.alloc_obj_ctx = gk20a_alloc_obj_ctx;

View File

@@ -27,6 +27,10 @@
#include "mm_gm20b.h"
#include "pmu_gm20b.h"
#include "clk_gm20b.h"
#include <linux/tegra-fuse.h>
#define FUSE_OPT_PRIV_SEC_DIS_0 0x264
#define PRIV_SECURITY_DISABLE 0x01
struct gpu_ops gm20b_ops = {
.clock_gating = {
@@ -46,6 +50,34 @@ struct gpu_ops gm20b_ops = {
int gm20b_init_hal(struct gpu_ops *gops)
{
*gops = gm20b_ops;
#ifdef CONFIG_TEGRA_ACR
if (tegra_platform_is_linsim()) {
gops->privsecurity = 1;
} else {
if (tegra_fuse_readl(FUSE_OPT_PRIV_SEC_DIS_0) &
PRIV_SECURITY_DISABLE) {
gk20a_dbg_info("priv security is disabled in HW");
gops->privsecurity = 0;
} else {
gops->privsecurity = 1;
}
}
#else
if (tegra_platform_is_linsim()) {
gk20a_dbg_info("running ASIM with PRIV security disabled");
gops->privsecurity = 0;
} else {
if (tegra_fuse_readl(FUSE_OPT_PRIV_SEC_DIS_0) &
PRIV_SECURITY_DISABLE) {
gops->privsecurity = 0;
} else {
gk20a_dbg_info("priv security is not supported but enabled");
gops->privsecurity = 1;
return -EPERM;
}
}
#endif
gm20b_init_ltc(gops);
gm20b_init_gr(gops);
gm20b_init_ltc(gops);

View File

@@ -150,10 +150,9 @@ int gm20b_pmu_setup_elpg(struct gk20a *g)
void gm20b_init_pmu_ops(struct gpu_ops *gops)
{
#ifdef CONFIG_TEGRA_ACR
gm20b_init_secure_pmu(gops);
#else
gk20a_init_pmu_ops(gops);
#endif
if (gops->privsecurity)
gm20b_init_secure_pmu(gops);
else
gk20a_init_pmu_ops(gops);
gops->pmu.pmu_setup_elpg = gm20b_pmu_setup_elpg;
}