gpu: nvgpu: add cg and pg function

Add new power/clock gating functions that can be called by
other units.

New clock_gating functions will reside in cg.c under
common/power_features/cg unit.

New power gating functions will reside in pg.c under
common/power_features/pg unit.

Use nvgpu_pg_elpg_disable and nvgpu_pg_elpg_enable to disable/enable
elpg and also in gr_gk20a_elpg_protected macro to access gr registers.

Add cg_pg_lock to make elpg_enabled, elcg_enabled, blcg_enabled
and slcg_enabled thread safe.

JIRA NVGPU-2014

Change-Id: I00d124c2ee16242c9a3ef82e7620fbb7f1297aff
Signed-off-by: Seema Khowala <seemaj@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2025493
Signed-off-by: Debarshi Dutta <ddutta@nvidia.com>
(cherry-picked from c905858565 in
dev-kernel)
Reviewed-on: https://git-master.nvidia.com/r/2108406
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Debarshi Dutta
2019-04-30 13:54:08 +05:30
committed by mobile promotions
parent f495f52c70
commit c81cc032c4
24 changed files with 984 additions and 354 deletions

View File

@@ -1,7 +1,7 @@
/*
* Tegra GK20A GPU Debugger/Profiler Driver
*
* Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2013-2019, 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"),
@@ -32,6 +32,7 @@
#include <nvgpu/utils.h>
#include <nvgpu/channel.h>
#include <nvgpu/unit.h>
#include <nvgpu/power_features/power_features.h>
#include "gk20a.h"
#include "gr_gk20a.h"
@@ -234,60 +235,28 @@ int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate)
return err;
}
/*do elpg disable before clock gating */
nvgpu_pmu_pg_global_enable(g, false);
err = nvgpu_cg_pg_disable(g);
if (g->ops.clock_gating.slcg_gr_load_gating_prod) {
g->ops.clock_gating.slcg_gr_load_gating_prod(g,
false);
if (err == 0) {
dbg_s->is_pg_disabled = true;
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
"pg disabled");
}
if (g->ops.clock_gating.slcg_perf_load_gating_prod) {
g->ops.clock_gating.slcg_perf_load_gating_prod(g,
false);
}
if (g->ops.clock_gating.slcg_ltc_load_gating_prod) {
g->ops.clock_gating.slcg_ltc_load_gating_prod(g,
false);
}
gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_RUN);
gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN);
dbg_s->is_pg_disabled = true;
} else {
/* restore (can) powergate, clk state */
/* release pending exceptions to fault/be handled as usual */
/*TBD: ordering of these? */
if (g->elcg_enabled) {
gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO);
}
err = nvgpu_cg_pg_enable(g);
if (g->blcg_enabled) {
gr_gk20a_init_cg_mode(g, BLCG_MODE, BLCG_AUTO);
}
if (g->slcg_enabled) {
if (g->ops.clock_gating.slcg_ltc_load_gating_prod) {
g->ops.clock_gating.slcg_ltc_load_gating_prod(g,
g->slcg_enabled);
}
if (g->ops.clock_gating.slcg_perf_load_gating_prod) {
g->ops.clock_gating.slcg_perf_load_gating_prod(g,
g->slcg_enabled);
}
if (g->ops.clock_gating.slcg_gr_load_gating_prod) {
g->ops.clock_gating.slcg_gr_load_gating_prod(g,
g->slcg_enabled);
}
}
nvgpu_pmu_pg_global_enable(g, true);
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
"module idle");
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, "module idle");
gk20a_idle(g);
dbg_s->is_pg_disabled = false;
if (err == 0) {
dbg_s->is_pg_disabled = false;
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn,
"pg enabled");
}
}
nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %s done",