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
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Seema Khowala
2019-02-28 11:15:24 -08:00
committed by mobile promotions
parent 7172d96bcd
commit c905858565
24 changed files with 997 additions and 385 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"),
@@ -34,8 +34,7 @@
#include <nvgpu/unit.h>
#include <nvgpu/gk20a.h>
#include <nvgpu/debugger.h>
#include "gk20a/gr_gk20a.h"
#include <nvgpu/power_features/power_features.h>
/*
* API to get first channel from the list of all channels
@@ -208,60 +207,29 @@ int nvgpu_dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powerg
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 != NULL) {
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 != NULL) {
g->ops.clock_gating.slcg_perf_load_gating_prod(g,
false);
}
if (g->ops.clock_gating.slcg_ltc_load_gating_prod != NULL) {
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);
}
nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn, "module idle");
if (g->slcg_enabled) {
if (g->ops.clock_gating.slcg_ltc_load_gating_prod != NULL) {
g->ops.clock_gating.slcg_ltc_load_gating_prod(g,
g->slcg_enabled);
}
if (g->ops.clock_gating.slcg_perf_load_gating_prod != NULL) {
g->ops.clock_gating.slcg_perf_load_gating_prod(g,
g->slcg_enabled);
}
if (g->ops.clock_gating.slcg_gr_load_gating_prod != NULL) {
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");
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",