gpu: nvgpu: wait for engines to go idle before suspend

Wait for pbdma and engine to go idle so that the tasks get completed before
suspending.

Updated the logic in gk20a_wait_engine_idle to consider the ctxsw status.
And updated PBDMA idle logic to check the pbdma status and the pb/gp
get/put pointers.

Bug 3789519
Bug 3832838

Change-Id: Ifd105bbb305eaf358423281b192f67d782d773a4
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2870162
Reviewed-by: Martin Radev <mradev@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Sagar Kamble
2023-03-13 14:06:57 +05:30
committed by mobile promotions
parent 5a2ed4df76
commit 3b414dbf07
3 changed files with 159 additions and 20 deletions

View File

@@ -400,6 +400,40 @@ static int gk20a_lockout_registers(struct gk20a *g)
return 0;
}
static int gk20a_fifo_wait_engines_idle(struct gk20a *g)
{
u32 engine_id_idx;
u32 active_engine_id = 0;
int ret;
nvgpu_log_fn(g, " ");
for (engine_id_idx = 0; engine_id_idx < g->fifo.num_engines; engine_id_idx++) {
active_engine_id = g->fifo.active_engines_list[engine_id_idx];
ret = gk20a_fifo_wait_pbdma_idle(g,
g->fifo.engine_info[active_engine_id].pbdma_id);
if (ret != 0) {
nvgpu_log_info(g, "failed to idle the pbdma");
ret = -EAGAIN;
goto done;
}
ret = gk20a_fifo_wait_engine_id_idle(g,
g->fifo.engine_info[active_engine_id].engine_id);
if (ret != 0) {
nvgpu_log_info(g, "failed to idle the engine");
ret = -EAGAIN;
goto done;
}
}
done:
nvgpu_log_fn(g, "done");
return ret;
}
static int gk20a_pm_prepare_poweroff(struct device *dev)
{
struct gk20a *g = get_gk20a(dev);
@@ -419,6 +453,13 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
nvgpu_hide_usermode_for_poweroff(g);
ret = gk20a_fifo_wait_engines_idle(g);
if (ret) {
nvgpu_err(g, "failed to idle engines");
nvgpu_restore_usermode_for_poweron(g);
goto done;
}
gk20a_scale_suspend(dev);
#ifdef CONFIG_NVGPU_SUPPORT_CDE