diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu
index e21a94267..e7ea3c5df 100644
--- a/drivers/gpu/nvgpu/Makefile.nvgpu
+++ b/drivers/gpu/nvgpu/Makefile.nvgpu
@@ -51,6 +51,7 @@ nvgpu-y := \
common/mm/gmmu.o \
common/mm/vm.o \
common/mm/vm_area.o \
+ common/enabled.o \
common/pramin.o \
common/semaphore.o \
common/as.o \
diff --git a/drivers/gpu/nvgpu/common/enabled.c b/drivers/gpu/nvgpu/common/enabled.c
new file mode 100644
index 000000000..d56f0551d
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/enabled.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, 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,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#include "gk20a/gk20a.h"
+
+int nvgpu_init_enabled_flags(struct gk20a *g)
+{
+ /*
+ * Zero all flags initially. Flags that should be set to non-zero states
+ * can be done so during driver init.
+ */
+ g->enabled_flags = nvgpu_kzalloc(g,
+ BITS_TO_LONGS(NVGPU_MAX_ENABLED_BITS) *
+ sizeof(unsigned long));
+ if (!g->enabled_flags)
+ return -ENOMEM;
+
+ return 0;
+}
+
+bool nvgpu_is_enabled(struct gk20a *g, int flag)
+{
+ return test_bit(flag, g->enabled_flags);
+}
+
+bool __nvgpu_set_enabled(struct gk20a *g, int flag, bool state)
+{
+ if (state)
+ return test_and_set_bit(flag, g->enabled_flags);
+ else
+ return test_and_clear_bit(flag, g->enabled_flags);
+}
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c
index adf9ff372..d5fc40de4 100644
--- a/drivers/gpu/nvgpu/common/linux/module.c
+++ b/drivers/gpu/nvgpu/common/linux/module.c
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include "gk20a/gk20a.h"
#include "gk20a/platform_gk20a.h"
@@ -873,11 +874,15 @@ static int gk20a_probe(struct platform_device *dev)
set_gk20a(dev, gk20a);
gk20a->dev = &dev->dev;
- if (nvgpu_platform_is_simulation(gk20a))
- gk20a->is_fmodel = true;
-
nvgpu_kmem_init(gk20a);
+ err = nvgpu_init_enabled_flags(gk20a);
+ if (err)
+ return err;
+
+ if (nvgpu_platform_is_simulation(gk20a))
+ __nvgpu_set_enabled(gk20a, NVGPU_IS_FMODEL, true);
+
gk20a->irq_stall = platform_get_irq(dev, 0);
gk20a->irq_nonstall = platform_get_irq(dev, 1);
if (gk20a->irq_stall < 0 || gk20a->irq_nonstall < 0)
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c
index 767e9d473..0a5095fe7 100644
--- a/drivers/gpu/nvgpu/common/linux/pci.c
+++ b/drivers/gpu/nvgpu/common/linux/pci.c
@@ -20,6 +20,7 @@
#include
#include
+#include
#include "gk20a/gk20a.h"
#include "gk20a/platform_gk20a.h"
@@ -358,11 +359,17 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
return -ENOMEM;
}
+ nvgpu_kmem_init(g);
+
+ err = nvgpu_init_enabled_flags(g);
+ if (err) {
+ kfree(g);
+ return err;
+ }
+
platform->g = g;
g->dev = &pdev->dev;
- nvgpu_kmem_init(g);
-
err = pci_enable_device(pdev);
if (err)
return err;
diff --git a/drivers/gpu/nvgpu/common/mm/gmmu.c b/drivers/gpu/nvgpu/common/mm/gmmu.c
index 695347bc2..dc91cc2f1 100644
--- a/drivers/gpu/nvgpu/common/mm/gmmu.c
+++ b/drivers/gpu/nvgpu/common/mm/gmmu.c
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include "gk20a/gk20a.h"
#include "gk20a/mm_gk20a.h"
@@ -74,7 +75,7 @@ static int nvgpu_alloc_gmmu_pages(struct vm_gk20a *vm, u32 order,
u32 len = num_pages * PAGE_SIZE;
int err;
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return alloc_gmmu_phys_pages(vm, order, entry);
/*
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 936e4d04f..571570d8d 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include "gk20a.h"
#include "debug_gk20a.h"
@@ -126,7 +127,7 @@ static void free_channel(struct fifo_gk20a *f,
* On teardown it is not possible to dereference platform, but ignoring
* this is fine then because no new channels would be created.
*/
- if (!g->driver_is_dying) {
+ if (!nvgpu_is_enabled(g, NVGPU_DRIVER_IS_DYING)) {
if (g->aggressive_sync_destroy_thresh &&
(f->used_channels <
g->aggressive_sync_destroy_thresh))
@@ -2418,7 +2419,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
struct nvgpu_gpfifo __user *user_gpfifo = args ?
(struct nvgpu_gpfifo __user *)(uintptr_t)args->gpfifo : NULL;
- if (g->driver_is_dying)
+ if (nvgpu_is_enabled(g, NVGPU_DRIVER_IS_DYING))
return -ENODEV;
if (c->has_timedout)
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index f4e7fe457..31b0a771b 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
@@ -364,20 +365,20 @@ done:
*/
int gk20a_can_busy(struct gk20a *g)
{
- if (g->driver_is_dying)
+ if (nvgpu_is_enabled(g, NVGPU_DRIVER_IS_DYING))
return 0;
return 1;
}
/*
- * Start the process for unloading the driver. Set g->driver_is_dying.
+ * Start the process for unloading the driver. Set NVGPU_DRIVER_IS_DYING.
*/
void gk20a_driver_start_unload(struct gk20a *g)
{
gk20a_dbg(gpu_dbg_shutdown, "Driver is now going down!\n");
down_write(&g->busy_lock);
- g->driver_is_dying = 1;
+ __nvgpu_set_enabled(g, NVGPU_DRIVER_IS_DYING, true);
up_write(&g->busy_lock);
if (g->is_virtual)
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 104170843..689fafb11 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -1,8 +1,8 @@
/*
- * GK20A Graphics
- *
* Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
+ * GK20A Graphics
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
@@ -971,15 +971,17 @@ struct gk20a {
struct device *dev;
struct platform_device *host1x_dev;
+ /*
+ * Used by . Do not access directly!
+ */
+ unsigned long *enabled_flags;
+
atomic_t usage_count;
- int driver_is_dying;
atomic_t nonstall_ops;
struct work_struct nonstall_fn_work;
struct workqueue_struct *nonstall_work_queue;
- bool is_fmodel;
-
struct kref refcount;
struct resource *reg_mem;
diff --git a/drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c
index 32c95e2fc..b0a90fc81 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_ctx_gk20a.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include "gk20a.h"
#include "gr_ctx_gk20a.h"
@@ -442,7 +443,7 @@ done:
int gr_gk20a_init_ctx_vars(struct gk20a *g, struct gr_gk20a *gr)
{
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return gr_gk20a_init_ctx_vars_sim(g, gr);
else
return gr_gk20a_init_ctx_vars_fw(g, gr);
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 2b5d809fb..c12f49ac1 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include "gk20a.h"
#include "kind_gk20a.h"
@@ -386,7 +387,7 @@ int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long duration_ms,
u32 delay = expect_delay;
struct nvgpu_timeout timeout;
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return 0;
gk20a_dbg_fn("");
@@ -1597,7 +1598,7 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g,
if (gr->ctx_vars.golden_image_initialized) {
goto clean_up;
}
- if (!g->is_fmodel) {
+ if (!nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
struct nvgpu_timeout timeout;
nvgpu_timeout_init(g, &timeout,
@@ -1642,7 +1643,7 @@ static int gr_gk20a_init_golden_ctx_image(struct gk20a *g,
gk20a_readl(g, gr_fecs_ctxsw_reset_ctl_r());
nvgpu_udelay(10);
- if (!g->is_fmodel) {
+ if (!nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
struct nvgpu_timeout timeout;
nvgpu_timeout_init(g, &timeout,
@@ -2582,7 +2583,7 @@ int gr_gk20a_load_ctxsw_ucode(struct gk20a *g)
gk20a_dbg_fn("");
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(7),
gr_fecs_ctxsw_mailbox_value_f(0xc0de7777));
gk20a_writel(g, gr_gpccs_ctxsw_mailbox_r(7),
diff --git a/drivers/gpu/nvgpu/gk20a/ltc_common.c b/drivers/gpu/nvgpu/gk20a/ltc_common.c
index 1958c11c8..2b015fa0b 100644
--- a/drivers/gpu/nvgpu/gk20a/ltc_common.c
+++ b/drivers/gpu/nvgpu/gk20a/ltc_common.c
@@ -19,6 +19,7 @@
*/
#include
+#include
#include "gk20a.h"
#include "gr_gk20a.h"
@@ -92,7 +93,7 @@ static void gk20a_ltc_init_cbc(struct gk20a *g, struct gr_gk20a *gr)
u64 compbit_store_iova;
u64 compbit_base_post_divide64;
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
compbit_store_iova = gk20a_mem_phys(&gr->compbit_store.mem);
else
compbit_store_iova = g->ops.mm.get_iova_addr(g,
diff --git a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c
index 23576ce0c..8867202f8 100644
--- a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include "gk20a.h"
#include "ltc_gk20a.h"
@@ -83,7 +84,7 @@ static int gk20a_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr)
gk20a_dbg_info("max comptag lines : %d",
max_comptag_lines);
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
err = gk20a_ltc_alloc_phys_cbc(g, compbit_backing_size);
else
err = gk20a_ltc_alloc_virt_cbc(g, compbit_backing_size);
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 17fa0c175..786a66930 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
@@ -824,7 +825,7 @@ void free_gmmu_pages(struct vm_gk20a *vm,
if (entry->woffset) /* fake shadow mem */
return;
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
free_gmmu_phys_pages(vm, entry);
return;
}
@@ -836,7 +837,7 @@ int map_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry)
{
gk20a_dbg_fn("");
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return map_gmmu_phys_pages(entry);
if (IS_ENABLED(CONFIG_ARM64)) {
@@ -860,7 +861,7 @@ void unmap_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry)
{
gk20a_dbg_fn("");
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
unmap_gmmu_phys_pages(entry);
return;
}
diff --git a/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c b/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c
index 2f837bfc7..dbab6b4ba 100644
--- a/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/priv_ring_gk20a.c
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
#include
@@ -28,7 +29,7 @@
void gk20a_enable_priv_ring(struct gk20a *g)
{
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return;
if (g->ops.clock_gating.slcg_priring_load_gating_prod)
@@ -53,7 +54,7 @@ void gk20a_priv_ring_isr(struct gk20a *g)
u32 gpc;
u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return;
status0 = gk20a_readl(g, pri_ringmaster_intr_status0_r());
diff --git a/drivers/gpu/nvgpu/gk20a/therm_gk20a.c b/drivers/gpu/nvgpu/gk20a/therm_gk20a.c
index b700c7357..00159fae5 100644
--- a/drivers/gpu/nvgpu/gk20a/therm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/therm_gk20a.c
@@ -16,6 +16,8 @@
* along with this program. If not, see .
*/
+#include
+
#include "gk20a.h"
#include
@@ -123,7 +125,7 @@ int gk20a_elcg_init_idle_filters(struct gk20a *g)
active_engine_id = f->active_engines_list[engine_id];
gate_ctrl = gk20a_readl(g, therm_gate_ctrl_r(active_engine_id));
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
gate_ctrl = set_field(gate_ctrl,
therm_gate_ctrl_eng_delay_after_m(),
therm_gate_ctrl_eng_delay_after_f(4));
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index e7b6fa857..82c587f95 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -19,6 +19,7 @@
#include
#include
+#include
#include "gk20a/gk20a.h"
#include "gk20a/gr_gk20a.h"
@@ -745,7 +746,7 @@ static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
gk20a_dbg_fn("");
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(7),
gr_fecs_ctxsw_mailbox_value_f(0xc0de7777));
gk20a_writel(g, gr_gpccs_ctxsw_mailbox_r(7),
diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
index 33198c23f..f5328f035 100644
--- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
@@ -39,6 +39,7 @@
#include "hal_gm20b.h"
#include
+#include
#include
#include
@@ -192,7 +193,7 @@ int gm20b_init_hal(struct gk20a *g)
gops->securegpccs = false;
gops->pmupstate = false;
#ifdef CONFIG_TEGRA_ACR
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
gops->privsecurity = 1;
} else {
val = gk20a_readl(g, fuse_opt_priv_sec_en_r());
@@ -204,7 +205,7 @@ int gm20b_init_hal(struct gk20a *g)
}
}
#else
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
gk20a_dbg_info("running ASIM with PRIV security disabled");
gops->privsecurity = 0;
} else {
diff --git a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c
index 84c3dfcd7..791cc45b4 100644
--- a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c
@@ -18,6 +18,7 @@
#include "gk20a/gk20a.h"
#include
+#include
#include
#include
@@ -82,7 +83,7 @@ static int gm20b_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr)
gk20a_dbg_info("max comptag lines : %d",
max_comptag_lines);
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
err = gk20a_ltc_alloc_phys_cbc(g, compbit_backing_size);
else
err = gk20a_ltc_alloc_virt_cbc(g, compbit_backing_size);
diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
index 133582cd7..e2a931bed 100644
--- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
@@ -45,6 +45,7 @@
#include "hal_gp10b.h"
#include
+#include
#include
#include
@@ -197,7 +198,7 @@ int gp10b_init_hal(struct gk20a *g)
gops->clock_gating = gp10b_ops.clock_gating;
gops->pmupstate = false;
#ifdef CONFIG_TEGRA_ACR
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
gops->privsecurity = 0;
gops->securegpccs = 0;
} else if (g->is_virtual) {
@@ -215,7 +216,7 @@ int gp10b_init_hal(struct gk20a *g)
}
}
#else
- if (g->is_fmodel) {
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
gk20a_dbg_info("running simulator with PRIV security disabled");
gops->privsecurity = 0;
gops->securegpccs = 0;
diff --git a/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c
index 165e93fe8..5cf5a6447 100644
--- a/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c
@@ -19,6 +19,7 @@
#include "gm20b/ltc_gm20b.h"
#include
+#include
#include
#include
@@ -102,7 +103,7 @@ static int gp10b_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr)
gk20a_dbg_info("gobs_per_comptagline_per_slice: %d",
gobs_per_comptagline_per_slice);
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
err = gk20a_ltc_alloc_phys_cbc(g, compbit_backing_size);
else
err = gk20a_ltc_alloc_virt_cbc(g, compbit_backing_size);
diff --git a/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c b/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c
index 7cdbec5e4..8aaa7bff7 100644
--- a/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
#include
@@ -34,7 +35,7 @@ static void gp10b_priv_ring_isr(struct gk20a *g)
u32 gpc;
u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return;
status0 = gk20a_readl(g, pri_ringmaster_intr_status0_r());
diff --git a/drivers/gpu/nvgpu/include/nvgpu/enabled.h b/drivers/gpu/nvgpu/include/nvgpu/enabled.h
new file mode 100644
index 000000000..5d30ba12c
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/enabled.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, 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,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __NVGPU_ENABLED_H__
+#define __NVGPU_ENABLED_H__
+
+struct gk20a;
+
+#include
+
+/*
+ * Available flags that describe what's enabled and what's not in the GPU. Each
+ * flag here is defined by it's offset in a bitmap.
+ */
+#define NVGPU_IS_FMODEL 1
+#define NVGPU_DRIVER_IS_DYING 2
+
+/*
+ * Must be greater than the largest bit offset in the above list.
+ */
+#define NVGPU_MAX_ENABLED_BITS 64
+
+/**
+ * nvgpu_is_enabled - Check if the passed flag is enabled.
+ *
+ * @g - The GPU.
+ * @flag - Which flag to check.
+ *
+ * Returns true if the passed @flag is true; false otherwise.
+ */
+bool nvgpu_is_enabled(struct gk20a *g, int flag);
+
+/**
+ * __nvgpu_set_enabled - Set the state of a flag.
+ *
+ * @g - The GPU.
+ * @flag - Which flag to modify.
+ * @state - The state to set the flag to.
+ *
+ * Set the state of the passed @flag to @state. This will return the previous
+ * state of the passed @flag.
+ */
+bool __nvgpu_set_enabled(struct gk20a *g, int flag, bool state);
+
+int nvgpu_init_enabled_flags(struct gk20a *g);
+
+#endif
diff --git a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c
index a3b73cdf8..96312a009 100644
--- a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c
+++ b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c
@@ -47,6 +47,7 @@
#include
#include
+#include
#include
@@ -120,7 +121,7 @@ int gk20a_tegra_secure_page_alloc(struct device *dev)
dma_addr_t iova;
size_t size = PAGE_SIZE;
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return -EINVAL;
dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs));
@@ -401,7 +402,7 @@ static bool gk20a_tegra_is_railgated(struct device *dev)
struct gk20a_platform *platform = dev_get_drvdata(dev);
bool ret = false;
- if (!g->is_fmodel)
+ if (!nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
ret = !tegra_dvfs_is_rail_up(platform->gpu_rail);
return ret;
@@ -419,7 +420,7 @@ static int gm20b_tegra_railgate(struct device *dev)
struct gk20a_platform *platform = dev_get_drvdata(dev);
int ret = 0;
- if (g->is_fmodel ||
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL) ||
!tegra_dvfs_is_rail_up(platform->gpu_rail))
return 0;
@@ -483,7 +484,7 @@ static int gm20b_tegra_unrailgate(struct device *dev)
int ret = 0;
bool first = false;
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return 0;
ret = tegra_dvfs_rail_power_up(platform->gpu_rail);
diff --git a/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c
index 84175e98d..971ef66a1 100644
--- a/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c
@@ -28,6 +28,7 @@
#include
#include
+#include
#include
#include "clk.h"
@@ -78,7 +79,7 @@ int gp10b_tegra_get_clocks(struct device *dev)
struct gk20a_platform *platform = dev_get_drvdata(dev);
unsigned int i;
- if (g->is_fmodel)
+ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
return 0;
platform->num_clks = 0;
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c
index 248d2a1b8..a88d9e090 100644
--- a/drivers/gpu/nvgpu/vgpu/vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/vgpu.c
@@ -21,6 +21,7 @@
#include
#include
+#include
#include "vgpu/vgpu.h"
#include "vgpu/fecs_trace_vgpu.h"
@@ -581,14 +582,20 @@ int vgpu_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ nvgpu_kmem_init(gk20a);
+
+ err = nvgpu_init_enabled_flags(gk20a);
+ if (err) {
+ kfree(gk20a);
+ return err;
+ }
+
gk20a->dev = dev;
if (tegra_platform_is_linsim() || tegra_platform_is_vdk())
- gk20a->is_fmodel = true;
+ __nvgpu_set_enabled(gk20a, NVGPU_IS_FMODEL, true);
gk20a->is_virtual = true;
- nvgpu_kmem_init(gk20a);
-
priv = nvgpu_kzalloc(gk20a, sizeof(*priv));
if (!priv) {
kfree(gk20a);