diff --git a/drivers/gpu/nvgpu/common/power_features/cg/cg.c b/drivers/gpu/nvgpu/common/power_features/cg/cg.c index 0c598a104..0de5c8a9f 100644 --- a/drivers/gpu/nvgpu/common/power_features/cg/cg.c +++ b/drivers/gpu/nvgpu/common/power_features/cg/cg.c @@ -262,6 +262,24 @@ done: nvgpu_mutex_release(&g->cg_pg_lock); } +#ifdef CONFIG_NVGPU_PROFILER +void nvgpu_cg_slcg_perf_load_enable(struct gk20a *g, bool enable) +{ + nvgpu_log_fn(g, " "); + + nvgpu_mutex_acquire(&g->cg_pg_lock); + if (!g->slcg_enabled) { + goto done; + } + + if (g->ops.cg.slcg_perf_load_gating_prod != NULL) { + g->ops.cg.slcg_perf_load_gating_prod(g, enable); + } +done: + nvgpu_mutex_release(&g->cg_pg_lock); +} +#endif + static void cg_init_gr_slcg_load_gating_prod(struct gk20a *g) { if (g->ops.cg.slcg_bus_load_gating_prod != NULL) { diff --git a/drivers/gpu/nvgpu/common/profiler/pm_reservation.c b/drivers/gpu/nvgpu/common/profiler/pm_reservation.c index dc1591ba5..74b79c277 100644 --- a/drivers/gpu/nvgpu/common/profiler/pm_reservation.c +++ b/drivers/gpu/nvgpu/common/profiler/pm_reservation.c @@ -23,9 +23,46 @@ #include #include #include +#include +#include #include #include +static void prepare_resource_reservation(struct gk20a *g, + enum nvgpu_profiler_pm_resource_type pm_resource, bool acquire) +{ + if ((pm_resource != NVGPU_PROFILER_PM_RESOURCE_TYPE_HWPM_LEGACY) && + (pm_resource != NVGPU_PROFILER_PM_RESOURCE_TYPE_PMA_STREAM)) { + return; + } + + if (acquire) { + nvgpu_atomic_inc(&g->hwpm_refcount); + nvgpu_log(g, gpu_dbg_prof, "HWPM refcount acquired %u, resource %u", + nvgpu_atomic_read(&g->hwpm_refcount), pm_resource); + + if (nvgpu_atomic_read(&g->hwpm_refcount) == 1) { + nvgpu_log(g, gpu_dbg_prof, + "Trigger HWPM system reset, disable perf SLCG"); + g->ops.mc.reset(g, g->ops.mc.reset_mask(g, + NVGPU_UNIT_PERFMON)); + nvgpu_cg_slcg_perf_load_enable(g, false); + } + } else { + nvgpu_atomic_dec(&g->hwpm_refcount); + nvgpu_log(g, gpu_dbg_prof, "HWPM refcount released %u, resource %u", + nvgpu_atomic_read(&g->hwpm_refcount), pm_resource); + + if (nvgpu_atomic_read(&g->hwpm_refcount) == 0) { + nvgpu_log(g, gpu_dbg_prof, + "Trigger HWPM system reset, re-enable perf SLCG"); + g->ops.mc.reset(g, g->ops.mc.reset_mask(g, + NVGPU_UNIT_PERFMON)); + nvgpu_cg_slcg_perf_load_enable(g, true); + } + } +} + static bool check_pm_resource_existing_reservation_locked( struct nvgpu_pm_resource_reservations *reservations, u32 reservation_id, u32 vmid) @@ -130,6 +167,8 @@ int nvgpu_pm_reservation_acquire(struct gk20a *g, u32 reservation_id, nvgpu_list_add(&reservation_entry->entry, &reservations->head); reservations->count++; + prepare_resource_reservation(g, pm_resource, true); + done: nvgpu_mutex_release(&reservations->lock); @@ -162,7 +201,9 @@ int nvgpu_pm_reservation_release(struct gk20a *g, u32 reservation_id, } } - if (!was_reserved) { + if (was_reserved) { + prepare_resource_reservation(g, pm_resource, false); + } else { err = -EINVAL; } @@ -189,6 +230,7 @@ void nvgpu_pm_reservation_release_all_per_vmid(struct gk20a *g, u32 vmid) nvgpu_list_del(&reservation_entry->entry); reservations->count--; nvgpu_kfree(g, reservation_entry); + prepare_resource_reservation(g, i, false); } } nvgpu_mutex_release(&reservations->lock); @@ -219,6 +261,8 @@ int nvgpu_pm_reservation_init(struct gk20a *g) g->pm_reservations = reservations; + nvgpu_atomic_set(&g->hwpm_refcount, 0); + nvgpu_log(g, gpu_dbg_prof, "initialized"); return 0; diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 2a40d929b..03a486488 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -858,6 +858,7 @@ struct gk20a { #ifdef CONFIG_NVGPU_PROFILER struct nvgpu_list_node profiler_objects; struct nvgpu_pm_resource_reservations *pm_reservations; + nvgpu_atomic_t hwpm_refcount; #endif #ifdef CONFIG_NVGPU_FECS_TRACE diff --git a/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h b/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h index b7e27cd4a..5ac462be3 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/power_features/cg.h @@ -436,5 +436,9 @@ void nvgpu_cg_slcg_gr_perf_ltc_load_enable(struct gk20a *g); void nvgpu_cg_slcg_gr_perf_ltc_load_disable(struct gk20a *g); void nvgpu_cg_slcg_set_slcg_enabled(struct gk20a *g, bool enable); +#endif + +#ifdef CONFIG_NVGPU_PROFILER +void nvgpu_cg_slcg_perf_load_enable(struct gk20a *g, bool enable); #endif #endif /*NVGPU_POWER_FEATURES_CG_H*/