From 087d4d3df45faed0f08f1b9d309b33a663f1e17c Mon Sep 17 00:00:00 2001 From: vinodg Date: Tue, 20 Aug 2019 23:58:23 -0700 Subject: [PATCH] gpu: nvgpu: rmmod support in dgpu simulation Changes added to support "rmmod nvgpu" in dgpu simulation after gpu poweron. nvgpu_engine-wait_for_idle got stuck in busy mode for nvdec and nvec engines in simulation as simulation doesnt support timeout. These engines are not valid engines in nvgpu engine list. Add nvgpu_engine_check_valid_id before checking engine status. Simulation crash on accessing 0xb81604 top interrupt register. Add func_priv_cpu_intr_top__size_1_v() function to get the supported size than using default MAX_INTR_TOP_REGS. nvlink is not supprted in dgpu simulation. Avoid warning for -ENODEV return. Avoid register read following gpu power off completion. Bug 2498574 Change-Id: I9f9f1cf1ac4620242bda1d2cc0f29f51f81a6711 Signed-off-by: vinodg Reviewed-on: https://git-master.nvidia.com/r/2179930 Reviewed-by: Seshendra Gadagottu GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/engines.c | 4 ++++ drivers/gpu/nvgpu/hal/mc/mc_tu104.c | 5 +++-- drivers/gpu/nvgpu/hal/mc/mc_tu104.h | 2 -- .../gpu/nvgpu/include/nvgpu/hw/tu104/hw_func_tu104.h | 1 + drivers/gpu/nvgpu/os/linux/pci.c | 10 ++++++++-- drivers/gpu/nvgpu/os/linux/sim_pci.c | 5 +---- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/nvgpu/common/fifo/engines.c b/drivers/gpu/nvgpu/common/fifo/engines.c index 8f72af80e..3f4cf2f82 100644 --- a/drivers/gpu/nvgpu/common/fifo/engines.c +++ b/drivers/gpu/nvgpu/common/fifo/engines.c @@ -438,6 +438,10 @@ int nvgpu_engine_wait_for_idle(struct gk20a *g) } for (i = 0; i < host_num_engines; i++) { + if (!nvgpu_engine_check_valid_id(g, i)) { + continue; + } + ret = -ETIMEDOUT; do { g->ops.engine_status.read_engine_status_info(g, i, diff --git a/drivers/gpu/nvgpu/hal/mc/mc_tu104.c b/drivers/gpu/nvgpu/hal/mc/mc_tu104.c index 25cbf64dd..21e4c8c64 100644 --- a/drivers/gpu/nvgpu/hal/mc/mc_tu104.c +++ b/drivers/gpu/nvgpu/hal/mc/mc_tu104.c @@ -367,7 +367,7 @@ void intr_tu104_stall_resume(struct gk20a *g) void intr_tu104_log_pending_intrs(struct gk20a *g) { bool pending; - u32 intr, i; + u32 intr, i, size; intr = intr_tu104_nonstall(g); if (intr != 0U) { @@ -386,7 +386,8 @@ void intr_tu104_log_pending_intrs(struct gk20a *g) } } - for (i = 0U; i < MAX_INTR_TOP_REGS; i++) { + size = func_priv_cpu_intr_top__size_1_v(); + for (i = 0U; i < size; i++) { intr = nvgpu_func_readl(g, func_priv_cpu_intr_top_r(i)); if (intr == 0U) { diff --git a/drivers/gpu/nvgpu/hal/mc/mc_tu104.h b/drivers/gpu/nvgpu/hal/mc/mc_tu104.h index f49d207dc..fc039575c 100644 --- a/drivers/gpu/nvgpu/hal/mc/mc_tu104.h +++ b/drivers/gpu/nvgpu/hal/mc/mc_tu104.h @@ -25,8 +25,6 @@ #include -#define MAX_INTR_TOP_REGS (2U) - #define NV_CPU_INTR_SUBTREE_TO_TOP_IDX(i) ((i) / 32U) #define NV_CPU_INTR_SUBTREE_TO_TOP_BIT(i) ((i) % 32U) #define NV_CPU_INTR_SUBTREE_TO_LEAF_REG0(i) ((i)*2U) diff --git a/drivers/gpu/nvgpu/include/nvgpu/hw/tu104/hw_func_tu104.h b/drivers/gpu/nvgpu/include/nvgpu/hw/tu104/hw_func_tu104.h index 7355d20c4..69cd25718 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/hw/tu104/hw_func_tu104.h +++ b/drivers/gpu/nvgpu/include/nvgpu/hw/tu104/hw_func_tu104.h @@ -74,6 +74,7 @@ #define func_priv_cpu_intr_leaf_en_clear__size_1_v() (0x00000008U) #define func_priv_cpu_intr_top_r(i)\ (nvgpu_safe_add_u32(0x00001600U, nvgpu_safe_mult_u32((i), 4U))) +#define func_priv_cpu_intr_top__size_1_v() (0x00000001U) #define func_priv_cpu_intr_leaf_r(i)\ (nvgpu_safe_add_u32(0x00001000U, nvgpu_safe_mult_u32((i), 4U))) #define func_priv_mmu_fault_buffer_lo_r(i)\ diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index c2b686cee..68e5c0e27 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c @@ -605,7 +605,10 @@ static void nvgpu_pci_remove(struct pci_dev *pdev) WARN(err, "gpu failed to clear pci power"); err = nvgpu_nvlink_deinit(g); - WARN(err, "gpu failed to remove nvlink"); + /* ENODEV is a legal error if there is no NVLINK */ + if (err != -ENODEV) { + WARN(err, "gpu failed to remove nvlink"); + } gk20a_driver_start_unload(g); @@ -655,7 +658,10 @@ void nvgpu_pci_shutdown(struct pci_dev *pdev) if (is_nvgpu_gpu_state_valid(g)) { err = nvgpu_nvlink_deinit(g); - WARN(err, "gpu failed to remove nvlink"); + /* ENODEV is a legal error if there is no NVLINK */ + if (err != -ENODEV) { + WARN(err, "gpu failed to remove nvlink"); + } } else nvgpu_err(g, "skipped nvlink deinit"); diff --git a/drivers/gpu/nvgpu/os/linux/sim_pci.c b/drivers/gpu/nvgpu/os/linux/sim_pci.c index 55d722e85..9ff72f935 100644 --- a/drivers/gpu/nvgpu/os/linux/sim_pci.c +++ b/drivers/gpu/nvgpu/os/linux/sim_pci.c @@ -54,11 +54,8 @@ static bool _nvgpu_pci_is_simulation(struct gk20a *g, u32 sim_base) void nvgpu_remove_sim_support_linux_pci(struct gk20a *g) { struct sim_nvgpu_linux *sim_linux; - bool is_simulation; - is_simulation = _nvgpu_pci_is_simulation(g, sim_r()); - - if (!is_simulation) { + if (!nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) { return; }