diff --git a/arch/nvgpu-common.yaml b/arch/nvgpu-common.yaml index 3a9543c92..0db83af2a 100644 --- a/arch/nvgpu-common.yaml +++ b/arch/nvgpu-common.yaml @@ -1102,6 +1102,8 @@ cic: include/nvgpu/gops/cic_mon.h, include/nvgpu/cic_mon.h, common/cic/rm/rm_intr.c, + common/cic/rm/rm_init.c, + common/cic/rm/cic_rm_priv.h, include/nvgpu/cic_rm.h ] ## diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index f9d88be26..69400cede 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -324,6 +324,7 @@ nvgpu-y += \ common/cic/mon/mon_pri.o \ common/cic/mon/mon_pmu.o \ common/cic/mon/mon_mmu.o \ + common/cic/rm/rm_init.o \ common/cic/rm/rm_intr.o \ hal/bus/bus_gk20a.o \ hal/class/class_gm20b.o \ diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index a456c6ec5..8e9034c7d 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -167,6 +167,7 @@ srcs += common/device.c \ common/cic/mon/mon_pri.c \ common/cic/mon/mon_pmu.c \ common/cic/mon/mon_mmu.c \ + common/cic/rm/rm_init.c \ common/cic/rm/rm_intr.c \ hal/init/hal_gv11b.c \ hal/init/hal_gv11b_litter.c \ diff --git a/drivers/gpu/nvgpu/common/cic/mon/mon_intr.c b/drivers/gpu/nvgpu/common/cic/mon/mon_intr.c index fe294e4ca..f0ded89ec 100644 --- a/drivers/gpu/nvgpu/common/cic/mon/mon_intr.c +++ b/drivers/gpu/nvgpu/common/cic/mon/mon_intr.c @@ -128,14 +128,13 @@ u32 nvgpu_cic_mon_intr_nonstall_isr(struct gk20a *g) return NVGPU_CIC_INTR_QUIESCE_PENDING; } - nvgpu_atomic_set(&g->mc.sw_irq_nonstall_pending, 1); + nvgpu_cic_rm_set_irq_nonstall(g, 1); return NVGPU_CIC_INTR_HANDLE; } void nvgpu_cic_mon_intr_nonstall_handle(struct gk20a *g) { - int err; u32 nonstall_ops = 0; nonstall_ops = g->ops.mc.isr_nonstall(g); @@ -144,14 +143,11 @@ void nvgpu_cic_mon_intr_nonstall_handle(struct gk20a *g) } /* sync handled irq counter before re-enabling interrupts */ - nvgpu_atomic_set(&g->mc.sw_irq_nonstall_pending, 0); + nvgpu_cic_rm_set_irq_nonstall(g, 0); nvgpu_cic_mon_intr_nonstall_resume(g); - err = nvgpu_cond_broadcast(&g->mc.sw_irq_nonstall_last_handled_cond); - if (err != 0) { - nvgpu_err(g, "nvgpu_cond_broadcast failed err=%d", err); - } + (void)nvgpu_cic_rm_broadcast_last_irq_nonstall(g); } u32 nvgpu_cic_mon_intr_stall_isr(struct gk20a *g) @@ -176,7 +172,7 @@ u32 nvgpu_cic_mon_intr_stall_isr(struct gk20a *g) return NVGPU_CIC_INTR_QUIESCE_PENDING; } - nvgpu_atomic_set(&g->mc.sw_irq_stall_pending, 1); + nvgpu_cic_rm_set_irq_stall(g, 1); nvgpu_trace_intr_stall_done(g); @@ -185,8 +181,6 @@ u32 nvgpu_cic_mon_intr_stall_isr(struct gk20a *g) void nvgpu_cic_mon_intr_stall_handle(struct gk20a *g) { - int err; - nvgpu_trace_intr_thread_stall_start(g); g->ops.mc.isr_stall(g); @@ -194,14 +188,11 @@ void nvgpu_cic_mon_intr_stall_handle(struct gk20a *g) nvgpu_trace_intr_thread_stall_done(g); /* sync handled irq counter before re-enabling interrupts */ - nvgpu_atomic_set(&g->mc.sw_irq_stall_pending, 0); + nvgpu_cic_rm_set_irq_stall(g, 0); nvgpu_cic_mon_intr_stall_resume(g); - err = nvgpu_cond_broadcast(&g->mc.sw_irq_stall_last_handled_cond); - if (err != 0) { - nvgpu_err(g, "nvgpu_cond_broadcast failed err=%d", err); - } + (void)nvgpu_cic_rm_broadcast_last_irq_stall(g); } #ifdef CONFIG_NVGPU_NON_FUSA diff --git a/drivers/gpu/nvgpu/common/cic/rm/cic_rm_priv.h b/drivers/gpu/nvgpu/common/cic/rm/cic_rm_priv.h new file mode 100644 index 000000000..98067d4ac --- /dev/null +++ b/drivers/gpu/nvgpu/common/cic/rm/cic_rm_priv.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef CIC_RM_PRIV_H +#define CIC_RM_PRIV_H + +#include +#include +#include + +struct nvgpu_cic_rm { + /** + * One of the condition variables needed to keep track of deferred + * interrupts. + * The condition variable that is signalled upon handling of the + * stalling interrupt. Function #nvgpu_cic_wait_for_stall_interrupts + * waits on this condition variable. + */ + struct nvgpu_cond sw_irq_stall_last_handled_cond; + + /** + * One of the counters needed to keep track of deferred interrupts. + * Stalling interrupt status counter - Set to 1 on entering stalling + * interrupt handler and reset to 0 on exit. + */ + nvgpu_atomic_t sw_irq_stall_pending; + + /** + * One of the condition variables needed to keep track of deferred + * interrupts. + * The condition variable that is signalled upon handling of the + * non-stalling interrupt. Function #nvgpu_cic_wait_for_nonstall_interrupts + * waits on this condition variable. + */ + struct nvgpu_cond sw_irq_nonstall_last_handled_cond; + + /** + * One of the counters needed to keep track of deferred interrupts. + * Non-stalling interrupt status counter - Set to 1 on entering + * non-stalling interrupt handler and reset to 0 on exit. + */ + nvgpu_atomic_t sw_irq_nonstall_pending; +}; + +#endif /* CIC_RM_PRIV_H */ diff --git a/drivers/gpu/nvgpu/common/cic/rm/rm_init.c b/drivers/gpu/nvgpu/common/cic/rm/rm_init.c new file mode 100644 index 000000000..74bf1b104 --- /dev/null +++ b/drivers/gpu/nvgpu/common/cic/rm/rm_init.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "cic_rm_priv.h" + +int nvgpu_cic_rm_setup(struct gk20a *g) +{ + struct nvgpu_cic_rm *cic_rm; + int err = 0; + + if (g->cic_rm != NULL) { + cic_dbg(g, "CIC_RM already initialized"); + return 0; + } + + cic_rm = nvgpu_kzalloc(g, sizeof(*cic_rm)); + if (cic_rm == NULL) { + nvgpu_err(g, "Failed to allocate memory " + "for struct nvgpu_cic_rm"); + return -ENOMEM; + } + + g->cic_rm = cic_rm; + cic_dbg(g, "CIC_RM unit initialization done."); + return err; +} + +int nvgpu_cic_rm_init_vars(struct gk20a *g) +{ + struct nvgpu_cic_rm *cic_rm; + int err = 0; + + cic_rm = g->cic_rm; + if (cic_rm == NULL) { + nvgpu_err(g, "CIC_RM setup pending"); + return -EINVAL; + } + + err = nvgpu_cond_init(&cic_rm->sw_irq_stall_last_handled_cond); + if (err != 0) { + nvgpu_err(g, "sw irq stall cond init failed\n"); + goto cleanup; + } + + err = nvgpu_cond_init(&cic_rm->sw_irq_nonstall_last_handled_cond); + if (err != 0) { + nvgpu_err(g, "sw irq nonstall cond init failed\n"); + goto cleanup_cond; + } + + return 0; + +cleanup_cond: + nvgpu_cond_destroy(&cic_rm->sw_irq_stall_last_handled_cond); +cleanup: + return err; +} + +int nvgpu_cic_rm_deinit_vars(struct gk20a *g) +{ + struct nvgpu_cic_rm *cic_rm; + + cic_rm = g->cic_rm; + + if (cic_rm == NULL) { + cic_dbg(g, "CIC_RM already removed"); + return 0; + } + + nvgpu_cond_destroy(&cic_rm->sw_irq_stall_last_handled_cond); + nvgpu_cond_destroy(&cic_rm->sw_irq_nonstall_last_handled_cond); + + return 0; +} + +int nvgpu_cic_rm_remove(struct gk20a *g) +{ + struct nvgpu_cic_rm *cic_rm; + + cic_rm = g->cic_rm; + + if (cic_rm == NULL) { + cic_dbg(g, "CIC_RM already removed"); + return 0; + } + + nvgpu_kfree(g, cic_rm); + g->cic_rm = NULL; + + return 0; +} diff --git a/drivers/gpu/nvgpu/common/cic/rm/rm_intr.c b/drivers/gpu/nvgpu/common/cic/rm/rm_intr.c index 91f9caf7e..85136e8df 100644 --- a/drivers/gpu/nvgpu/common/cic/rm/rm_intr.c +++ b/drivers/gpu/nvgpu/common/cic/rm/rm_intr.c @@ -22,21 +22,62 @@ #include #include -#include + +#include "cic_rm_priv.h" + +void nvgpu_cic_rm_set_irq_stall(struct gk20a *g, u32 value) +{ + nvgpu_atomic_set(&g->cic_rm->sw_irq_stall_pending, value); +} + +void nvgpu_cic_rm_set_irq_nonstall(struct gk20a *g, u32 value) +{ + nvgpu_atomic_set(&g->cic_rm->sw_irq_nonstall_pending, value); +} + +int nvgpu_cic_rm_broadcast_last_irq_stall(struct gk20a *g) +{ + int err = 0; + + err = nvgpu_cond_broadcast( + &g->cic_rm->sw_irq_stall_last_handled_cond); + if (err != 0) { + nvgpu_err(g, + "Last IRQ stall cond_broadcast failed err=%d", + err); + } + + return err; +} + +int nvgpu_cic_rm_broadcast_last_irq_nonstall(struct gk20a *g) +{ + int err = 0; + + err = nvgpu_cond_broadcast( + &g->cic_rm->sw_irq_nonstall_last_handled_cond); + if (err != 0) { + nvgpu_err(g, + "Last IRQ nonstall cond_broadcast failed err=%d", + err); + } + + return err; +} int nvgpu_cic_rm_wait_for_stall_interrupts(struct gk20a *g, u32 timeout) { /* wait until all stalling irqs are handled */ - return NVGPU_COND_WAIT(&g->mc.sw_irq_stall_last_handled_cond, - nvgpu_atomic_read(&g->mc.sw_irq_stall_pending) == 0, + return NVGPU_COND_WAIT(&g->cic_rm->sw_irq_stall_last_handled_cond, + nvgpu_atomic_read(&g->cic_rm->sw_irq_stall_pending) == 0, timeout); } int nvgpu_cic_rm_wait_for_nonstall_interrupts(struct gk20a *g, u32 timeout) { /* wait until all non-stalling irqs are handled */ - return NVGPU_COND_WAIT(&g->mc.sw_irq_nonstall_last_handled_cond, - nvgpu_atomic_read(&g->mc.sw_irq_nonstall_pending) == 0, + return NVGPU_COND_WAIT(&g->cic_rm->sw_irq_nonstall_last_handled_cond, + nvgpu_atomic_read(&g->cic_rm->sw_irq_nonstall_pending) == 0, timeout); } diff --git a/drivers/gpu/nvgpu/common/init/nvgpu_init.c b/drivers/gpu/nvgpu/common/init/nvgpu_init.c index e2a5f7d98..daba0a4b8 100644 --- a/drivers/gpu/nvgpu/common/init/nvgpu_init.c +++ b/drivers/gpu/nvgpu/common/init/nvgpu_init.c @@ -369,11 +369,6 @@ int nvgpu_prepare_poweroff(struct gk20a *g) nvgpu_err(g, "Failed to deinit CIC-mon."); } - ret = nvgpu_cic_mon_remove(g); - if (ret != 0) { - nvgpu_err(g, "Failed to remove CIC-mon."); - } - return ret; } @@ -783,12 +778,6 @@ int nvgpu_early_poweron(struct gk20a *g) /* Initialize CIC early on before the interrupts are * enabled. */ - err = nvgpu_cic_mon_setup(g); - if (err != 0) { - nvgpu_err(g, "CIC-mon setup failed[%d]", err); - goto done; - } - err = nvgpu_cic_mon_init_lut(g); if (err != 0) { nvgpu_err(g, "CIC LUT Initialization failed[%d]", err); diff --git a/drivers/gpu/nvgpu/include/nvgpu/cic_rm.h b/drivers/gpu/nvgpu/include/nvgpu/cic_rm.h index 5f184720e..18596ad1a 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/cic_rm.h +++ b/drivers/gpu/nvgpu/include/nvgpu/cic_rm.h @@ -25,6 +25,137 @@ #include +/** + * @brief Setup the CIC-RM subunit's data structures + * + * @param g [in] - The GPU driver struct. + * + * - Check if CIC-RM subunit is already initialized by checking its + * reference in struct gk20a. + * - If not initialized, allocate memory for CIC-RM's private data + * structure. + * - Store a reference pointer to the CIC struct in struct gk20a. + * - This API should to be called before any of the CIC-RM + * functionality is requested. + * + * @return 0 if Initialization had already happened or was + * successful in this call. + * < 0 if any steps in initialization fail. + * + * @retval -ENOMEM if sufficient memory is not available for CIC-RM + * struct. + * + */ +int nvgpu_cic_rm_setup(struct gk20a *g); + +/** + * @brief Remove the CIC-RM subunit's data structures + * + * @param g [in] - The GPU driver struct. + * + * - Check if CIC-RM subunit is already removed by checking its + * reference in struct gk20a. + * - If not removed already, free the memory allocated for CIC-RM's + * private data structure. + * - Invalidate reference pointer to the CIC-RM struct in struct gk20a. + * - No CIC-RM functionality will be available after this API is + * called. + * + * @return 0 if Deinitialization had already happened or was + * successful in this call. + * + * @retval None. + */ +int nvgpu_cic_rm_remove(struct gk20a *g); + +/** + * @brief Initialize the CIC-RM subunit's data structures + * + * @param g [in] - The GPU driver struct. + * + * - Check if CIC-RM subunit's setup is pending. + * - Initialize the condition variables used to keep track of + * deferred interrupts. + * + * @return 0 if Initialization is successful. + * < 0 if any steps in initialization fail. + * + * @retval -EINVAL if CIC-RM setup is pending. + * + */ +int nvgpu_cic_rm_init_vars(struct gk20a *g); + +/** + * @brief De-initialize the CIC-RM subunit's data structures + * + * @param g [in] - The GPU driver struct. + * + * - Check if CIC-RM subunit is already removed by checking its + * reference in struct gk20a. + * - Destroy the condition variables used to keep track of + * deferred interrupts. + * + * @return 0 if Deinitialization had already happened or was + * successful in this call. + * + * @retval None. + */ +int nvgpu_cic_rm_deinit_vars(struct gk20a *g); + +/** + * @brief Set the stalling interrupt status counter. + * + * @param g [in] - The GPU driver struct. + * @param value[in] - Counter value to be set. + * + * - Sets the stalling interrupt status counter atomically + * to \a value. + * - This API is called to set the counter to 1 on entering the + * stalling interrupt handler and reset to 0 on exit. + */ +void nvgpu_cic_rm_set_irq_stall(struct gk20a *g, u32 value); + +/** + * @brief Set the non-stalling interrupt status counter. + * + * @param g [in] - The GPU driver struct. + * @param value[in] - Counter value to be set. + * + * - Sets the non-stalling interrupt status counter atomically + * to \a value. + * - This API is called to set the counter to 1 on entering the + * non-stalling interrupt handler and reset to 0 on exit. + */ +void nvgpu_cic_rm_set_irq_nonstall(struct gk20a *g, u32 value); + +/** + * @brief Signal the completion of stall interrupt handling. + * + * @param g [in] - The GPU driver struct. + * + * - Signal the waitqueues waiting on condition variable that keeps + * track of deferred stalling interrupts. + * - This API is called on completion of stall interrupt handling. + * + * @return 0 if waitqueue broadcast call is successful. + * < 0 if broadcast call fails + */ +int nvgpu_cic_rm_broadcast_last_irq_stall(struct gk20a *g); + +/** + * @brief Signal the completion of non-stall interrupt handling. + * + * @param g [in] - The GPU driver struct. + * + * - Signal the waitqueues waiting on condition variable that keeps + * track of deferred non-stalling interrupts. + * - This API is called on completion of non-stall interrupt handling. + * + * @return 0 if waitqueue broadcast call is successful. + * < 0 if broadcast call fails + */ +int nvgpu_cic_rm_broadcast_last_irq_nonstall(struct gk20a *g); + /** * @brief Wait for the stalling interrupts to complete. * diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index b91a99e04..3ecbe82de 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -108,6 +108,7 @@ struct vm_gk20a_mapping_batch; struct pmu_pg_stats_data; struct clk_domains_mon_status_params; struct nvgpu_cic_mon; +struct nvgpu_cic_rm; #ifdef CONFIG_NVGPU_GSP_SCHEDULER struct nvgpu_gsp; #endif @@ -826,6 +827,9 @@ struct gk20a { /** Pointer to struct storing CIC-MON's data */ struct nvgpu_cic_mon *cic_mon; + + /** Pointer to struct storing CIC-RM's data */ + struct nvgpu_cic_rm *cic_rm; }; /** diff --git a/drivers/gpu/nvgpu/include/nvgpu/mc.h b/drivers/gpu/nvgpu/include/nvgpu/mc.h index 5fcaaf4b8..5bde51341 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/mc.h +++ b/drivers/gpu/nvgpu/include/nvgpu/mc.h @@ -106,9 +106,6 @@ * Some of the dynamic interfaces are HAL functions. They are documented * here. * + include/nvgpu/gops/mc.h - * - * Following interface is common function. - * + nvgpu_cic_rm_wait_for_deferred_interrupts() */ @@ -205,38 +202,6 @@ struct nvgpu_mc { */ u32 intr_mask_restore[4]; - /** - * One of the condition variables needed to keep track of deferred - * interrupts. - * The condition variable that is signalled upon handling of the - * stalling interrupt. Function #nvgpu_cic_wait_for_stall_interrupts - * waits on this condition variable. - */ - struct nvgpu_cond sw_irq_stall_last_handled_cond; - - /** - * One of the counters needed to keep track of deferred interrupts. - * Stalling interrupt status counter - Set to 1 on entering stalling - * interrupt handler and reset to 0 on exit. - */ - nvgpu_atomic_t sw_irq_stall_pending; - - /** - * One of the condition variables needed to keep track of deferred - * interrupts. - * The condition variable that is signalled upon handling of the - * non-stalling interrupt. Function #nvgpu_cic_wait_for_nonstall_interrupts - * waits on this condition variable. - */ - struct nvgpu_cond sw_irq_nonstall_last_handled_cond; - - /** - * One of the counters needed to keep track of deferred interrupts. - * Non-stalling interrupt status counter - Set to 1 on entering - * non-stalling interrupt handler and reset to 0 on exit. - */ - nvgpu_atomic_t sw_irq_nonstall_pending; - /** @cond DOXYGEN_SHOULD_SKIP_THIS */ #if defined(CONFIG_NVGPU_NON_FUSA) diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index 0317a27cf..60d9efc21 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "platform_gk20a.h" #include "module.h" @@ -57,9 +58,6 @@ static void nvgpu_init_vars(struct gk20a *g) struct device *dev = dev_from_gk20a(g); struct gk20a_platform *platform = dev_get_drvdata(dev); - nvgpu_cond_init(&g->mc.sw_irq_stall_last_handled_cond); - nvgpu_cond_init(&g->mc.sw_irq_nonstall_last_handled_cond); - init_rwsem(&l->busy_lock); nvgpu_rwsem_init(&g->deterministic_busy); @@ -278,6 +276,19 @@ int nvgpu_probe(struct gk20a *g, struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); int err = 0; + err = nvgpu_cic_rm_setup(g); + if (err != 0) { + nvgpu_err(g, "CIC-RM setup failed"); + return err; + } + + err = nvgpu_cic_rm_init_vars(g); + if (err != 0) { + nvgpu_err(g, "CIC-RM init vars failed"); + (void) nvgpu_cic_rm_remove(g); + return err; + } + nvgpu_init_vars(g); nvgpu_init_max_comptag(g); nvgpu_init_timeout(g); diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index ad05e062b..ea0a06e17 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -1598,6 +1598,12 @@ static int gk20a_probe(struct platform_device *dev) if (nvgpu_platform_is_simulation(gk20a)) nvgpu_set_enabled(gk20a, NVGPU_IS_FMODEL, true); + err = nvgpu_cic_mon_setup(gk20a); + if (err != 0) { + nvgpu_err(gk20a, "CIC-MON setup failed"); + goto return_err_cic_mon; + } + intr_size = platform_irq_count(dev); if (intr_size > 0U && intr_size <= NVGPU_MAX_INTERRUPTS) { irq_idx = 0U; @@ -1698,6 +1704,8 @@ static int gk20a_probe(struct platform_device *dev) return 0; return_err: + nvgpu_cic_mon_remove(gk20a); +return_err_cic_mon: nvgpu_free_enabled_flags(gk20a); return_err_errata: nvgpu_free_errata_flags(gk20a); @@ -1762,6 +1770,12 @@ int nvgpu_remove(struct device *dev) nvgpu_mutex_destroy(&g->clk_arb_enable_lock); + err = nvgpu_cic_rm_deinit_vars(g); + if (err != 0) { + nvgpu_err(g, "CIC-RM deinit vars failed."); + return err; + } + nvgpu_log_fn(g, "removed"); return err; @@ -1779,6 +1793,18 @@ static int __exit gk20a_remove(struct platform_device *pdev) err = nvgpu_remove(dev); + err = nvgpu_cic_mon_remove(g); + if (err != 0) { + nvgpu_err(g, "CIC-MON remove failed"); + return err; + } + + err = nvgpu_cic_rm_remove(g); + if (err != 0) { + nvgpu_err(g, "CIC-RM remove failed."); + return err; + } + gk20a_dma_buf_priv_list_clear(l); nvgpu_mutex_destroy(&l->dmabuf_priv_list_lock); diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index 5bd6954c3..813f1d5c6 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c @@ -601,6 +601,12 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, g->msi_enabled = true; #endif + err = nvgpu_cic_mon_setup(g); + if (err != 0) { + nvgpu_err(g, "CIC-MON setup failed"); + goto err_disable_msi; + } + /* Number of stall interrupt line = 1 (for dgpu <= tu10x) */ l->interrupts.stall_size = 1U; l->interrupts.nonstall_size = 0U; @@ -610,7 +616,7 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, if ((int)l->interrupts.stall_lines[0] < 0) { err = -ENXIO; - goto err_disable_msi; + goto err_deinit_cic_mon; } err = devm_request_threaded_irq(&pdev->dev, @@ -624,7 +630,7 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, if (err) { nvgpu_err(g, "failed to request irq @ %d", l->interrupts.stall_lines[0]); - goto err_disable_msi; + goto err_deinit_cic_mon; } nvgpu_disable_irqs(g); @@ -694,6 +700,8 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, err_free_irq: nvgpu_free_irq(g); +err_deinit_cic_mon: + nvgpu_cic_mon_remove(g); err_disable_msi: #if defined(CONFIG_PCI_MSI) if (g->msi_enabled) @@ -770,6 +778,9 @@ static void nvgpu_pci_remove(struct pci_dev *pdev) nvgpu_enable_irqs(g); } #endif + (void)nvgpu_cic_mon_remove(g); + (void)nvgpu_cic_rm_remove(g); + nvgpu_pci_pm_deinit(&pdev->dev); /* free allocated platform data space */ diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c index c301e931d..a0ba14165 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -387,6 +388,19 @@ int vgpu_probe(struct platform_device *pdev) return -ENOMEM; } + err = nvgpu_cic_rm_setup(gk20a); + if (err != 0) { + nvgpu_err(gk20a, "CIC-RM setup failed"); + return err; + } + + err = nvgpu_cic_rm_init_vars(gk20a); + if (err != 0) { + nvgpu_err(gk20a, "CIC-RM init vars failed"); + (void) nvgpu_cic_rm_remove(gk20a); + return err; + } + vgpu_init_vars(gk20a, platform); init_rwsem(&l->busy_lock); diff --git a/libs/dgpu/libnvgpu-drv-dgpu_safe.export b/libs/dgpu/libnvgpu-drv-dgpu_safe.export index f520b2771..5ace22e07 100644 --- a/libs/dgpu/libnvgpu-drv-dgpu_safe.export +++ b/libs/dgpu/libnvgpu-drv-dgpu_safe.export @@ -802,3 +802,7 @@ nvgpu_cic_mon_get_err_desc nvgpu_cic_mon_report_err_safety_services nvgpu_cic_mon_get_num_hw_modules nvgpu_cic_mon_remove +nvgpu_cic_rm_setup +nvgpu_cic_rm_init_vars +nvgpu_cic_rm_deinit_vars +nvgpu_cic_rm_remove diff --git a/libs/igpu/libnvgpu-drv-igpu_safe.export b/libs/igpu/libnvgpu-drv-igpu_safe.export index 34a260b6a..0feb422f9 100644 --- a/libs/igpu/libnvgpu-drv-igpu_safe.export +++ b/libs/igpu/libnvgpu-drv-igpu_safe.export @@ -817,3 +817,7 @@ nvgpu_cic_mon_get_err_desc nvgpu_cic_mon_report_err_safety_services nvgpu_cic_mon_get_num_hw_modules nvgpu_cic_mon_remove +nvgpu_cic_rm_setup +nvgpu_cic_rm_init_vars +nvgpu_cic_rm_deinit_vars +nvgpu_cic_rm_remove diff --git a/userspace/required_tests.ini b/userspace/required_tests.ini index 63865ae7e..f0834b677 100644 --- a/userspace/required_tests.ini +++ b/userspace/required_tests.ini @@ -331,7 +331,6 @@ test_mc_free_env.mc_free_env=0 test_mc_setup_env.mc_setup_env=0 test_pause_resume_mask.pause_resume_mask=0 test_unit_config.unit_config=2 -test_wait_for_deferred_interrupts.wait_for_deferred_interrupts=0 [mm.as] test_as_alloc_share.as_alloc_share_0k_um=0 diff --git a/userspace/units/fifo/nvgpu-fifo-common.c b/userspace/units/fifo/nvgpu-fifo-common.c index 1a6a434ae..306e6b973 100644 --- a/userspace/units/fifo/nvgpu-fifo-common.c +++ b/userspace/units/fifo/nvgpu-fifo-common.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -199,6 +200,16 @@ int test_fifo_init_support(struct unit_module *m, struct gk20a *g, void *args) unit_return_fail(m, "CIC LUT init failed\n"); } + err = nvgpu_cic_rm_setup(g); + if (err != 0) { + unit_return_fail(m, "CIC-rm init failed\n"); + } + + err = nvgpu_cic_rm_init_vars(g); + if (err != 0) { + unit_return_fail(m, "CIC-rm vars init failed\n"); + } + return UNIT_SUCCESS; fail: diff --git a/userspace/units/gr/nvgpu-gr.c b/userspace/units/gr/nvgpu-gr.c index 2bf0099b7..7a0606dba 100644 --- a/userspace/units/gr/nvgpu-gr.c +++ b/userspace/units/gr/nvgpu-gr.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "common/gr/gr_falcon_priv.h" @@ -180,6 +181,15 @@ int test_gr_init_setup_ready(struct unit_module *m, unit_return_fail(m, "CIC LUT init failed\n"); } + err = nvgpu_cic_rm_setup(g); + if (err != 0) { + unit_return_fail(m, "CIC-rm init failed\n"); + } + + err = nvgpu_cic_rm_init_vars(g); + if (err != 0) { + unit_return_fail(m, "CIC-rm vars init failed\n"); + } /* Allocate and Initialize GR */ err = test_gr_init_setup(m, g, args); if (err != 0) { diff --git a/userspace/units/mc/nvgpu-mc.c b/userspace/units/mc/nvgpu-mc.c index 131d2f622..8194d92b9 100644 --- a/userspace/units/mc/nvgpu-mc.c +++ b/userspace/units/mc/nvgpu-mc.c @@ -653,37 +653,6 @@ int test_enable_disable_reset(struct unit_module *m, struct gk20a *g, void *args return UNIT_SUCCESS; } -int test_wait_for_deferred_interrupts(struct unit_module *m, struct gk20a *g, - void *args) -{ - struct nvgpu_posix_fault_inj *cond_fi = - nvgpu_cond_get_fault_injection(); - - nvgpu_cond_init(&g->mc.sw_irq_stall_last_handled_cond); - nvgpu_cond_init(&g->mc.sw_irq_nonstall_last_handled_cond); - - /* immediate completion */ - nvgpu_atomic_set(&g->mc.sw_irq_stall_pending, 0); - nvgpu_atomic_set(&g->mc.sw_irq_nonstall_pending, 0); - nvgpu_cic_rm_wait_for_deferred_interrupts(g); - - /* cause timeout */ - nvgpu_posix_enable_fault_injection(cond_fi, true, 0); - - /* wait on stall until timeout for branch coverage */ - nvgpu_atomic_set(&g->mc.sw_irq_stall_pending, 1); - nvgpu_cic_rm_wait_for_deferred_interrupts(g); - - /* wait on nonstall until timeout for branch coverage */ - nvgpu_atomic_set(&g->mc.sw_irq_nonstall_pending, 1); - nvgpu_cic_rm_wait_for_deferred_interrupts(g); - - /* disable the fault injection */ - nvgpu_posix_enable_fault_injection(cond_fi, false, 0); - - return UNIT_SUCCESS; -} - struct unit_module_test mc_tests[] = { UNIT_TEST(mc_setup_env, test_mc_setup_env, NULL, 0), UNIT_TEST(unit_config, test_unit_config, NULL, 2), @@ -695,7 +664,6 @@ struct unit_module_test mc_tests[] = { UNIT_TEST(isr_nonstall, test_isr_nonstall, NULL, 2), UNIT_TEST(is_intr1_pending, test_is_intr1_pending, NULL, 0), UNIT_TEST(enable_disable_reset, test_enable_disable_reset, NULL, 0), - UNIT_TEST(wait_for_deferred_interrupts, test_wait_for_deferred_interrupts, NULL, 0), UNIT_TEST(mc_free_env, test_mc_free_env, NULL, 0), }; diff --git a/userspace/units/mc/nvgpu-mc.h b/userspace/units/mc/nvgpu-mc.h index c0ced4f9b..9b282fefa 100644 --- a/userspace/units/mc/nvgpu-mc.h +++ b/userspace/units/mc/nvgpu-mc.h @@ -329,35 +329,6 @@ int test_enable_disable_reset(struct unit_module *m, struct gk20a *g, void *args */ int test_reset_mask(struct unit_module *m, struct gk20a *g, void *args); -/** - * Test specification for: test_wait_for_deferred_interrupts - * - * Description: Validate functionality of waiting for deferred interrupts. - * - * Test Type: Feature - * - * Targets: nvgpu_cic_wait_for_deferred_interrupts - * - * Input: test_mc_setup_env must have been run. - * - * Steps: - * - Initialize cond structures required by the API. - * - Set the irq count states in the gk20a struct to 0 to cause immediate - * completion. - * - Call the API. - * - Enable cond fault injection to simulate a timeouts. - * - Set the irq count states in the gk20a struct to simulate pending stall - * interrupts. - * - Call the API. - * - Set the irq count states in the gk20a struct to simulate pending non-stall - * interrupts. - * - Disable cond fault injection. - * - * Output: Returns PASS if expected result is met, FAIL otherwise. - */ -int test_wait_for_deferred_interrupts(struct unit_module *m, struct gk20a *g, - void *args); - /** * @} */ diff --git a/userspace/units/rc/nvgpu-rc.c b/userspace/units/rc/nvgpu-rc.c index dac8a72f5..ca45ce507 100644 --- a/userspace/units/rc/nvgpu-rc.c +++ b/userspace/units/rc/nvgpu-rc.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "../fifo/nvgpu-fifo-common.h" #include "../fifo/nvgpu-fifo-gv11b.h" @@ -96,6 +97,16 @@ int test_rc_init(struct unit_module *m, struct gk20a *g, void *args) nvgpu_device_init(g); + ret = nvgpu_cic_rm_setup(g); + if (ret != 0) { + unit_return_fail(m, "CIC-rm init failed\n"); + } + + ret = nvgpu_cic_rm_init_vars(g); + if (ret != 0) { + unit_return_fail(m, "CIC-rm vars init failed\n"); + } + g->ops.gr.init.get_no_of_sm = stub_gv11b_gr_init_get_no_of_sm; g->ops.ecc.ecc_init_support(g);