]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu: nvgpu: gm20b: dynamically detect priv security for secure boot of falcon
authorVijayakumar <vsubbu@nvidia.com>
Fri, 22 Aug 2014 11:52:57 +0000 (17:22 +0530)
committerTom Cherry <tcherry@nvidia.com>
Wed, 27 Aug 2014 19:08:18 +0000 (12:08 -0700)
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>
drivers/gpu/nvgpu/gk20a/gk20a.h
drivers/gpu/nvgpu/gk20a/hal.c
drivers/gpu/nvgpu/gk20a/hal_gk20a.c
drivers/gpu/nvgpu/gm20b/gr_gm20b.c
drivers/gpu/nvgpu/gm20b/hal_gm20b.c
drivers/gpu/nvgpu/gm20b/pmu_gm20b.c

index a1080f0b8975ef6bfe7c760389119f7245ef1acc..14c7e7fc10dc4972da9b818339fd524c1d41aa3c 100644 (file)
@@ -251,6 +251,7 @@ struct gpu_ops {
                int (*init_clk_support)(struct gk20a *g);
                int (*suspend_clk_support)(struct gk20a *g);
        } clk;
+       bool privsecurity;
 };
 
 struct gk20a {
index 1aae030495c8a5cdd56fd7f7b7a33528d2969c49..8d1a29ddef9d51abe16ca6785e55f7d8a00c18d2 100644 (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);
index 3dae9450c53898ebea499ce281ee5ff1dc2b1a2c..1b8157f1eb5f5e87926a8ff9288a686a1a2297b8 100644 (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);
index 72500b0eb99274a6c689ced565c79e4f24b0cc0e..702247d1bb8964a6fb9d5f2635d9fbea74320958 100644 (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,10 +751,9 @@ 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;
 }
index 5e8fc0aeb2751afa79028f6659e99dc2726f7641..1dafc13d20acd7d28279d4b90d0107e03920d610 100644 (file)
 #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);
index 04f9e02a6449f701c7a7a0c439ea3d9d3ea3d2c8..98dc6845299895da32861e138814aaab7a98b568 100644 (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;
 }