int (*init_clk_support)(struct gk20a *g);
int (*suspend_clk_support)(struct gk20a *g);
} clk;
+ bool privsecurity;
};
struct gk20a {
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);
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);
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() |
return 0;
}
+#else
+
+static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
+{
+ return -EPERM;
+}
+
#endif
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;
}
#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 = {
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);
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;
}