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);