mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
gpu: nvgpu: pg stat read update
- Added struct pmu_pg_stats_data to extract data from multiple version of pmu pg statistics - Added pmu_pg_stats_v2 interface to fetch PG statistics data from PMU - Added MSCG debugfs node to read mscg statistics from PMU. - Added pmu_elpg_statistics HAL support for gp106 PG statistics read. - Made changes to gp104/gp106 pmu_elpg_statistics HAL to support for struct pmu_pg_stats_data JIRA DNVGPU-165 Change-Id: I2b9e89c0fae90deb45006c4478170b9a97b56603 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/1252798 (cherry picked from commit 3c073b15fd991db8d65b3171b02c161294be40cd) Reviewed-on: http://git-master/r/1271615 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
e239ce69b3
commit
f3e0dba8bf
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* GK20A Graphics
|
* GK20A Graphics
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -605,8 +605,7 @@ struct gpu_ops {
|
|||||||
int (*load_lsfalcon_ucode)(struct gk20a *g, u32 falconidmask);
|
int (*load_lsfalcon_ucode)(struct gk20a *g, u32 falconidmask);
|
||||||
void (*write_dmatrfbase)(struct gk20a *g, u32 addr);
|
void (*write_dmatrfbase)(struct gk20a *g, u32 addr);
|
||||||
void (*pmu_elpg_statistics)(struct gk20a *g, u32 pg_engine_id,
|
void (*pmu_elpg_statistics)(struct gk20a *g, u32 pg_engine_id,
|
||||||
u32 *ingating_time, u32 *ungating_time,
|
struct pmu_pg_stats_data *pg_stat_data);
|
||||||
u32 *gating_cnt);
|
|
||||||
int (*pmu_pg_init_param)(struct gk20a *g, u32 pg_engine_id);
|
int (*pmu_pg_init_param)(struct gk20a *g, u32 pg_engine_id);
|
||||||
u32 (*pmu_pg_supported_engines_list)(struct gk20a *g);
|
u32 (*pmu_pg_supported_engines_list)(struct gk20a *g);
|
||||||
u32 (*pmu_pg_engines_feature_list)(struct gk20a *g,
|
u32 (*pmu_pg_engines_feature_list)(struct gk20a *g,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* GK20A PMU (aka. gPMU outside gk20a context)
|
* GK20A PMU (aka. gPMU outside gk20a context)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -46,9 +46,9 @@
|
|||||||
#define gk20a_dbg_pmu(fmt, arg...) \
|
#define gk20a_dbg_pmu(fmt, arg...) \
|
||||||
gk20a_dbg(gpu_dbg_pmu, fmt, ##arg)
|
gk20a_dbg(gpu_dbg_pmu, fmt, ##arg)
|
||||||
|
|
||||||
static int gk20a_pmu_get_elpg_residency_gating(struct gk20a *g,
|
static int gk20a_pmu_get_pg_stats(struct gk20a *g,
|
||||||
u32 pg_engine_id, u32 *ingating_time,
|
u32 pg_engine_id,
|
||||||
u32 *ungating_time, u32 *gating_cnt);
|
struct pmu_pg_stats_data *pg_stat_data);
|
||||||
static void ap_callback_init_and_enable_ctrl(
|
static void ap_callback_init_and_enable_ctrl(
|
||||||
struct gk20a *g, struct pmu_msg *msg,
|
struct gk20a *g, struct pmu_msg *msg,
|
||||||
void *param, u32 seq_desc, u32 status);
|
void *param, u32 seq_desc, u32 status);
|
||||||
@@ -4979,7 +4979,7 @@ int gk20a_pmu_perfmon_enable(struct gk20a *g, bool enable)
|
|||||||
int gk20a_pmu_destroy(struct gk20a *g)
|
int gk20a_pmu_destroy(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct pmu_gk20a *pmu = &g->pmu;
|
struct pmu_gk20a *pmu = &g->pmu;
|
||||||
u32 elpg_ingating_time, elpg_ungating_time, gating_cnt;
|
struct pmu_pg_stats_data pg_stat_data = { 0 };
|
||||||
|
|
||||||
gk20a_dbg_fn("");
|
gk20a_dbg_fn("");
|
||||||
|
|
||||||
@@ -4989,17 +4989,16 @@ int gk20a_pmu_destroy(struct gk20a *g)
|
|||||||
/* make sure the pending operations are finished before we continue */
|
/* make sure the pending operations are finished before we continue */
|
||||||
cancel_work_sync(&pmu->pg_init);
|
cancel_work_sync(&pmu->pg_init);
|
||||||
|
|
||||||
gk20a_pmu_get_elpg_residency_gating(g,
|
gk20a_pmu_get_pg_stats(g,
|
||||||
PMU_PG_ELPG_ENGINE_ID_GRAPHICS, &elpg_ingating_time,
|
PMU_PG_ELPG_ENGINE_ID_GRAPHICS, &pg_stat_data);
|
||||||
&elpg_ungating_time, &gating_cnt);
|
|
||||||
|
|
||||||
gk20a_pmu_disable_elpg(g);
|
gk20a_pmu_disable_elpg(g);
|
||||||
pmu->initialized = false;
|
pmu->initialized = false;
|
||||||
|
|
||||||
/* update the s/w ELPG residency counters */
|
/* update the s/w ELPG residency counters */
|
||||||
g->pg_ingating_time_us += (u64)elpg_ingating_time;
|
g->pg_ingating_time_us += (u64)pg_stat_data.ingating_time;
|
||||||
g->pg_ungating_time_us += (u64)elpg_ungating_time;
|
g->pg_ungating_time_us += (u64)pg_stat_data.ungating_time;
|
||||||
g->pg_gating_cnt += gating_cnt;
|
g->pg_gating_cnt += pg_stat_data.gating_cnt;
|
||||||
|
|
||||||
mutex_lock(&pmu->isr_mutex);
|
mutex_lock(&pmu->isr_mutex);
|
||||||
pmu->isr_enabled = false;
|
pmu->isr_enabled = false;
|
||||||
@@ -5070,7 +5069,7 @@ void gk20a_pmu_reset_load_counters(struct gk20a *g)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void gk20a_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
void gk20a_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
||||||
u32 *ingating_time, u32 *ungating_time, u32 *gating_cnt)
|
struct pmu_pg_stats_data *pg_stat_data)
|
||||||
{
|
{
|
||||||
struct pmu_gk20a *pmu = &g->pmu;
|
struct pmu_gk20a *pmu = &g->pmu;
|
||||||
struct pmu_pg_stats stats;
|
struct pmu_pg_stats stats;
|
||||||
@@ -5079,22 +5078,24 @@ void gk20a_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
|||||||
pmu->stat_dmem_offset[pg_engine_id],
|
pmu->stat_dmem_offset[pg_engine_id],
|
||||||
(u8 *)&stats, sizeof(struct pmu_pg_stats), 0);
|
(u8 *)&stats, sizeof(struct pmu_pg_stats), 0);
|
||||||
|
|
||||||
*ingating_time = stats.pg_ingating_time_us;
|
pg_stat_data->ingating_time = stats.pg_ingating_time_us;
|
||||||
*ungating_time = stats.pg_ungating_time_us;
|
pg_stat_data->ungating_time = stats.pg_ungating_time_us;
|
||||||
*gating_cnt = stats.pg_gating_cnt;
|
pg_stat_data->gating_cnt = stats.pg_gating_cnt;
|
||||||
|
pg_stat_data->avg_entry_latency_us = stats.pg_avg_entry_time_us;
|
||||||
|
pg_stat_data->avg_exit_latency_us = stats.pg_avg_exit_time_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gk20a_pmu_get_elpg_residency_gating(struct gk20a *g,
|
static int gk20a_pmu_get_pg_stats(struct gk20a *g,
|
||||||
u32 pg_engine_id, u32 *ingating_time,
|
u32 pg_engine_id,
|
||||||
u32 *ungating_time, u32 *gating_cnt)
|
struct pmu_pg_stats_data *pg_stat_data)
|
||||||
{
|
{
|
||||||
struct pmu_gk20a *pmu = &g->pmu;
|
struct pmu_gk20a *pmu = &g->pmu;
|
||||||
u32 pg_engine_id_list = 0;
|
u32 pg_engine_id_list = 0;
|
||||||
|
|
||||||
if (!pmu->initialized) {
|
if (!pmu->initialized) {
|
||||||
*ingating_time = 0;
|
pg_stat_data->ingating_time = 0;
|
||||||
*ungating_time = 0;
|
pg_stat_data->ungating_time = 0;
|
||||||
*gating_cnt = 0;
|
pg_stat_data->gating_cnt = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5103,8 +5104,7 @@ static int gk20a_pmu_get_elpg_residency_gating(struct gk20a *g,
|
|||||||
|
|
||||||
if (BIT(pg_engine_id) & pg_engine_id_list)
|
if (BIT(pg_engine_id) & pg_engine_id_list)
|
||||||
g->ops.pmu.pmu_elpg_statistics(g, pg_engine_id,
|
g->ops.pmu.pmu_elpg_statistics(g, pg_engine_id,
|
||||||
ingating_time,
|
pg_stat_data);
|
||||||
ungating_time, gating_cnt);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -5257,13 +5257,11 @@ int gk20a_aelpg_init_and_enable(struct gk20a *g, u8 ctrl_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
static int mscg_residency_show(struct seq_file *s, void *data)
|
static int mscg_stat_show(struct seq_file *s, void *data)
|
||||||
{
|
{
|
||||||
struct gk20a *g = s->private;
|
struct gk20a *g = s->private;
|
||||||
u32 ingating_time = 0;
|
|
||||||
u32 ungating_time = 0;
|
|
||||||
u32 gating_cnt;
|
|
||||||
u64 total_ingating, total_ungating, residency, divisor, dividend;
|
u64 total_ingating, total_ungating, residency, divisor, dividend;
|
||||||
|
struct pmu_pg_stats_data pg_stat_data = { 0 };
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Don't unnecessarily power on the device */
|
/* Don't unnecessarily power on the device */
|
||||||
@@ -5272,13 +5270,15 @@ static int mscg_residency_show(struct seq_file *s, void *data)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
gk20a_pmu_get_elpg_residency_gating(g,
|
gk20a_pmu_get_pg_stats(g,
|
||||||
PMU_PG_ELPG_ENGINE_ID_MS, &ingating_time,
|
PMU_PG_ELPG_ENGINE_ID_MS, &pg_stat_data);
|
||||||
&ungating_time, &gating_cnt);
|
|
||||||
gk20a_idle(g->dev);
|
gk20a_idle(g->dev);
|
||||||
}
|
}
|
||||||
total_ingating = g->pg_ingating_time_us + (u64)ingating_time;
|
total_ingating = g->pg_ingating_time_us +
|
||||||
total_ungating = g->pg_ungating_time_us + (u64)ungating_time;
|
(u64)pg_stat_data.ingating_time;
|
||||||
|
total_ungating = g->pg_ungating_time_us +
|
||||||
|
(u64)pg_stat_data.ungating_time;
|
||||||
|
|
||||||
divisor = total_ingating + total_ungating;
|
divisor = total_ingating + total_ungating;
|
||||||
|
|
||||||
/* We compute the residency on a scale of 1000 */
|
/* We compute the residency on a scale of 1000 */
|
||||||
@@ -5289,21 +5289,28 @@ static int mscg_residency_show(struct seq_file *s, void *data)
|
|||||||
else
|
else
|
||||||
residency = 0;
|
residency = 0;
|
||||||
|
|
||||||
seq_printf(s, "Time in MSCG: %llu us\n"
|
seq_printf(s,
|
||||||
|
"Time in MSCG: %llu us\n"
|
||||||
"Time out of MSCG: %llu us\n"
|
"Time out of MSCG: %llu us\n"
|
||||||
"MSCG residency ratio: %llu\n",
|
"MSCG residency ratio: %llu\n"
|
||||||
total_ingating, total_ungating, residency);
|
"MSCG Entry Count: %u\n"
|
||||||
|
"MSCG Avg Entry latency %u\n"
|
||||||
|
"MSCG Avg Exit latency %u\n",
|
||||||
|
total_ingating, total_ungating,
|
||||||
|
residency, pg_stat_data.gating_cnt,
|
||||||
|
pg_stat_data.avg_entry_latency_us,
|
||||||
|
pg_stat_data.avg_exit_latency_us);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mscg_residency_open(struct inode *inode, struct file *file)
|
static int mscg_stat_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
return single_open(file, mscg_residency_show, inode->i_private);
|
return single_open(file, mscg_stat_show, inode->i_private);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations mscg_residency_fops = {
|
static const struct file_operations mscg_stat_fops = {
|
||||||
.open = mscg_residency_open,
|
.open = mscg_stat_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
.release = single_release,
|
.release = single_release,
|
||||||
@@ -5312,8 +5319,8 @@ static const struct file_operations mscg_residency_fops = {
|
|||||||
static int mscg_transitions_show(struct seq_file *s, void *data)
|
static int mscg_transitions_show(struct seq_file *s, void *data)
|
||||||
{
|
{
|
||||||
struct gk20a *g = s->private;
|
struct gk20a *g = s->private;
|
||||||
u32 ingating_time, ungating_time, total_gating_cnt;
|
struct pmu_pg_stats_data pg_stat_data = { 0 };
|
||||||
u32 gating_cnt = 0;
|
u32 total_gating_cnt;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (g->power_on) {
|
if (g->power_on) {
|
||||||
@@ -5321,12 +5328,11 @@ static int mscg_transitions_show(struct seq_file *s, void *data)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
gk20a_pmu_get_elpg_residency_gating(g,
|
gk20a_pmu_get_pg_stats(g,
|
||||||
PMU_PG_ELPG_ENGINE_ID_MS, &ingating_time,
|
PMU_PG_ELPG_ENGINE_ID_MS, &pg_stat_data);
|
||||||
&ungating_time, &gating_cnt);
|
|
||||||
gk20a_idle(g->dev);
|
gk20a_idle(g->dev);
|
||||||
}
|
}
|
||||||
total_gating_cnt = g->pg_gating_cnt + gating_cnt;
|
total_gating_cnt = g->pg_gating_cnt + pg_stat_data.gating_cnt;
|
||||||
|
|
||||||
seq_printf(s, "%u\n", total_gating_cnt);
|
seq_printf(s, "%u\n", total_gating_cnt);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -5345,12 +5351,10 @@ static const struct file_operations mscg_transitions_fops = {
|
|||||||
.release = single_release,
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int elpg_residency_show(struct seq_file *s, void *data)
|
static int elpg_stat_show(struct seq_file *s, void *data)
|
||||||
{
|
{
|
||||||
struct gk20a *g = s->private;
|
struct gk20a *g = s->private;
|
||||||
u32 ingating_time = 0;
|
struct pmu_pg_stats_data pg_stat_data = { 0 };
|
||||||
u32 ungating_time = 0;
|
|
||||||
u32 gating_cnt;
|
|
||||||
u64 total_ingating, total_ungating, residency, divisor, dividend;
|
u64 total_ingating, total_ungating, residency, divisor, dividend;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -5360,13 +5364,14 @@ static int elpg_residency_show(struct seq_file *s, void *data)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
gk20a_pmu_get_elpg_residency_gating(g,
|
gk20a_pmu_get_pg_stats(g,
|
||||||
PMU_PG_ELPG_ENGINE_ID_GRAPHICS, &ingating_time,
|
PMU_PG_ELPG_ENGINE_ID_GRAPHICS, &pg_stat_data);
|
||||||
&ungating_time, &gating_cnt);
|
|
||||||
gk20a_idle(g->dev);
|
gk20a_idle(g->dev);
|
||||||
}
|
}
|
||||||
total_ingating = g->pg_ingating_time_us + (u64)ingating_time;
|
total_ingating = g->pg_ingating_time_us +
|
||||||
total_ungating = g->pg_ungating_time_us + (u64)ungating_time;
|
(u64)pg_stat_data.ingating_time;
|
||||||
|
total_ungating = g->pg_ungating_time_us +
|
||||||
|
(u64)pg_stat_data.ungating_time;
|
||||||
divisor = total_ingating + total_ungating;
|
divisor = total_ingating + total_ungating;
|
||||||
|
|
||||||
/* We compute the residency on a scale of 1000 */
|
/* We compute the residency on a scale of 1000 */
|
||||||
@@ -5377,21 +5382,28 @@ static int elpg_residency_show(struct seq_file *s, void *data)
|
|||||||
else
|
else
|
||||||
residency = 0;
|
residency = 0;
|
||||||
|
|
||||||
seq_printf(s, "Time in ELPG: %llu us\n"
|
seq_printf(s,
|
||||||
|
"Time in ELPG: %llu us\n"
|
||||||
"Time out of ELPG: %llu us\n"
|
"Time out of ELPG: %llu us\n"
|
||||||
"ELPG residency ratio: %llu\n",
|
"ELPG residency ratio: %llu\n"
|
||||||
total_ingating, total_ungating, residency);
|
"ELPG Entry Count: %u\n"
|
||||||
|
"ELPG Avg Entry latency %u us\n"
|
||||||
|
"ELPG Avg Exit latency %u us\n",
|
||||||
|
total_ingating, total_ungating,
|
||||||
|
residency, pg_stat_data.gating_cnt,
|
||||||
|
pg_stat_data.avg_entry_latency_us,
|
||||||
|
pg_stat_data.avg_exit_latency_us);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int elpg_residency_open(struct inode *inode, struct file *file)
|
static int elpg_stat_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
return single_open(file, elpg_residency_show, inode->i_private);
|
return single_open(file, elpg_stat_show, inode->i_private);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations elpg_residency_fops = {
|
static const struct file_operations elpg_stat_fops = {
|
||||||
.open = elpg_residency_open,
|
.open = elpg_stat_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
.release = single_release,
|
.release = single_release,
|
||||||
@@ -5400,8 +5412,8 @@ static const struct file_operations elpg_residency_fops = {
|
|||||||
static int elpg_transitions_show(struct seq_file *s, void *data)
|
static int elpg_transitions_show(struct seq_file *s, void *data)
|
||||||
{
|
{
|
||||||
struct gk20a *g = s->private;
|
struct gk20a *g = s->private;
|
||||||
u32 ingating_time, ungating_time, total_gating_cnt;
|
struct pmu_pg_stats_data pg_stat_data = { 0 };
|
||||||
u32 gating_cnt = 0;
|
u32 total_gating_cnt;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (g->power_on) {
|
if (g->power_on) {
|
||||||
@@ -5409,12 +5421,11 @@ static int elpg_transitions_show(struct seq_file *s, void *data)
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
gk20a_pmu_get_elpg_residency_gating(g,
|
gk20a_pmu_get_pg_stats(g,
|
||||||
PMU_PG_ELPG_ENGINE_ID_GRAPHICS, &ingating_time,
|
PMU_PG_ELPG_ENGINE_ID_GRAPHICS, &pg_stat_data);
|
||||||
&ungating_time, &gating_cnt);
|
|
||||||
gk20a_idle(g->dev);
|
gk20a_idle(g->dev);
|
||||||
}
|
}
|
||||||
total_gating_cnt = g->pg_gating_cnt + gating_cnt;
|
total_gating_cnt = g->pg_gating_cnt + pg_stat_data.gating_cnt;
|
||||||
|
|
||||||
seq_printf(s, "%u\n", total_gating_cnt);
|
seq_printf(s, "%u\n", total_gating_cnt);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -5589,7 +5600,7 @@ int gk20a_pmu_debugfs_init(struct device *dev)
|
|||||||
|
|
||||||
d = debugfs_create_file(
|
d = debugfs_create_file(
|
||||||
"mscg_residency", S_IRUGO|S_IWUSR, platform->debugfs, g,
|
"mscg_residency", S_IRUGO|S_IWUSR, platform->debugfs, g,
|
||||||
&mscg_residency_fops);
|
&mscg_stat_fops);
|
||||||
if (!d)
|
if (!d)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
@@ -5601,7 +5612,7 @@ int gk20a_pmu_debugfs_init(struct device *dev)
|
|||||||
|
|
||||||
d = debugfs_create_file(
|
d = debugfs_create_file(
|
||||||
"elpg_residency", S_IRUGO|S_IWUSR, platform->debugfs, g,
|
"elpg_residency", S_IRUGO|S_IWUSR, platform->debugfs, g,
|
||||||
&elpg_residency_fops);
|
&elpg_stat_fops);
|
||||||
if (!d)
|
if (!d)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* GK20A PMU (aka. gPMU outside gk20a context)
|
* GK20A PMU (aka. gPMU outside gk20a context)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -566,6 +566,33 @@ struct pmu_sequence {
|
|||||||
void* cb_params;
|
void* cb_params;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pmu_pg_stats_data {
|
||||||
|
u32 gating_cnt;
|
||||||
|
u32 ingating_time;
|
||||||
|
u32 ungating_time;
|
||||||
|
u32 avg_entry_latency_us;
|
||||||
|
u32 avg_exit_latency_us;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pmu_pg_stats_v2 {
|
||||||
|
u32 entry_count;
|
||||||
|
u32 exit_count;
|
||||||
|
u32 abort_count;
|
||||||
|
u32 detection_count;
|
||||||
|
u32 prevention_activate_count;
|
||||||
|
u32 prevention_deactivate_count;
|
||||||
|
u32 powered_up_time_us;
|
||||||
|
u32 entry_latency_us;
|
||||||
|
u32 exit_latency_us;
|
||||||
|
u32 resident_time_us;
|
||||||
|
u32 entry_latency_avg_us;
|
||||||
|
u32 exit_latency_avg_us;
|
||||||
|
u32 entry_latency_max_us;
|
||||||
|
u32 exit_latency_max_us;
|
||||||
|
u32 total_sleep_time_us;
|
||||||
|
u32 total_non_sleep_time_us;
|
||||||
|
};
|
||||||
|
|
||||||
struct pmu_pg_stats_v1 {
|
struct pmu_pg_stats_v1 {
|
||||||
/* Number of time PMU successfully engaged sleep state */
|
/* Number of time PMU successfully engaged sleep state */
|
||||||
u32 entry_count;
|
u32 entry_count;
|
||||||
@@ -825,7 +852,7 @@ int pmu_wait_message_cond(struct pmu_gk20a *pmu, u32 timeout_ms,
|
|||||||
void pmu_handle_fecs_boot_acr_msg(struct gk20a *g, struct pmu_msg *msg,
|
void pmu_handle_fecs_boot_acr_msg(struct gk20a *g, struct pmu_msg *msg,
|
||||||
void *param, u32 handle, u32 status);
|
void *param, u32 handle, u32 status);
|
||||||
void gk20a_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
void gk20a_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
||||||
u32 *ingating_time, u32 *ungating_time, u32 *gating_cnt);
|
struct pmu_pg_stats_data *pg_stat_data);
|
||||||
int gk20a_pmu_reset(struct gk20a *g);
|
int gk20a_pmu_reset(struct gk20a *g);
|
||||||
int pmu_idle(struct pmu_gk20a *pmu);
|
int pmu_idle(struct pmu_gk20a *pmu);
|
||||||
int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable);
|
int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -258,6 +258,23 @@ static int gp106_pg_param_init(struct gk20a *g, u32 pg_engine_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gp106_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
||||||
|
struct pmu_pg_stats_data *pg_stat_data)
|
||||||
|
{
|
||||||
|
struct pmu_gk20a *pmu = &g->pmu;
|
||||||
|
struct pmu_pg_stats_v2 stats;
|
||||||
|
|
||||||
|
pmu_copy_from_dmem(pmu,
|
||||||
|
pmu->stat_dmem_offset[pg_engine_id],
|
||||||
|
(u8 *)&stats, sizeof(struct pmu_pg_stats_v2), 0);
|
||||||
|
|
||||||
|
pg_stat_data->ingating_time = stats.total_sleep_time_us;
|
||||||
|
pg_stat_data->ungating_time = stats.total_non_sleep_time_us;
|
||||||
|
pg_stat_data->gating_cnt = stats.entry_count;
|
||||||
|
pg_stat_data->avg_entry_latency_us = stats.entry_latency_avg_us;
|
||||||
|
pg_stat_data->avg_exit_latency_us = stats.exit_latency_avg_us;
|
||||||
|
}
|
||||||
|
|
||||||
void gp106_init_pmu_ops(struct gpu_ops *gops)
|
void gp106_init_pmu_ops(struct gpu_ops *gops)
|
||||||
{
|
{
|
||||||
gk20a_dbg_fn("");
|
gk20a_dbg_fn("");
|
||||||
@@ -279,7 +296,7 @@ void gp106_init_pmu_ops(struct gpu_ops *gops)
|
|||||||
gops->pmu.lspmuwprinitdone = 0;
|
gops->pmu.lspmuwprinitdone = 0;
|
||||||
gops->pmu.fecsbootstrapdone = false;
|
gops->pmu.fecsbootstrapdone = false;
|
||||||
gops->pmu.write_dmatrfbase = gp10b_write_dmatrfbase;
|
gops->pmu.write_dmatrfbase = gp10b_write_dmatrfbase;
|
||||||
gops->pmu.pmu_elpg_statistics = gp10b_pmu_elpg_statistics;
|
gops->pmu.pmu_elpg_statistics = gp106_pmu_elpg_statistics;
|
||||||
gops->pmu.pmu_pg_init_param = gp106_pg_param_init;
|
gops->pmu.pmu_pg_init_param = gp106_pg_param_init;
|
||||||
gops->pmu.pmu_pg_supported_engines_list = gp106_pmu_pg_engines_list;
|
gops->pmu.pmu_pg_supported_engines_list = gp106_pmu_pg_engines_list;
|
||||||
gops->pmu.pmu_pg_engines_feature_list = gp106_pmu_pg_feature_list;
|
gops->pmu.pmu_pg_engines_feature_list = gp106_pmu_pg_feature_list;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* GP10B PMU
|
* GP10B PMU
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -250,8 +250,8 @@ int gp10b_pg_gr_init(struct gk20a *g, u32 pg_engine_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
static void gp10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
||||||
u32 *ingating_time, u32 *ungating_time, u32 *gating_cnt)
|
struct pmu_pg_stats_data *pg_stat_data)
|
||||||
{
|
{
|
||||||
struct pmu_gk20a *pmu = &g->pmu;
|
struct pmu_gk20a *pmu = &g->pmu;
|
||||||
struct pmu_pg_stats_v1 stats;
|
struct pmu_pg_stats_v1 stats;
|
||||||
@@ -260,9 +260,11 @@ void gp10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
|||||||
pmu->stat_dmem_offset[pg_engine_id],
|
pmu->stat_dmem_offset[pg_engine_id],
|
||||||
(u8 *)&stats, sizeof(struct pmu_pg_stats_v1), 0);
|
(u8 *)&stats, sizeof(struct pmu_pg_stats_v1), 0);
|
||||||
|
|
||||||
*ingating_time = stats.total_sleep_timeus;
|
pg_stat_data->ingating_time = stats.total_sleep_timeus;
|
||||||
*ungating_time = stats.total_nonsleep_timeus;
|
pg_stat_data->ungating_time = stats.total_nonsleep_timeus;
|
||||||
*gating_cnt = stats.entry_count;
|
pg_stat_data->gating_cnt = stats.entry_count;
|
||||||
|
pg_stat_data->avg_entry_latency_us = stats.entrylatency_avgus;
|
||||||
|
pg_stat_data->avg_exit_latency_us = stats.exitlatency_avgus;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gp10b_pmu_setup_elpg(struct gk20a *g)
|
static int gp10b_pmu_setup_elpg(struct gk20a *g)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* GP10B PMU
|
* GP10B PMU
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -20,7 +20,5 @@ void gp10b_init_pmu_ops(struct gpu_ops *gops);
|
|||||||
int gp10b_load_falcon_ucode(struct gk20a *g, u32 falconidmask);
|
int gp10b_load_falcon_ucode(struct gk20a *g, u32 falconidmask);
|
||||||
int gp10b_pg_gr_init(struct gk20a *g, u32 pg_engine_id);
|
int gp10b_pg_gr_init(struct gk20a *g, u32 pg_engine_id);
|
||||||
void gp10b_write_dmatrfbase(struct gk20a *g, u32 addr);
|
void gp10b_write_dmatrfbase(struct gk20a *g, u32 addr);
|
||||||
void gp10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
|
|
||||||
u32 *ingating_time, u32 *ungating_time, u32 *gating_cnt);
|
|
||||||
|
|
||||||
#endif /*__PMU_GP10B_H_*/
|
#endif /*__PMU_GP10B_H_*/
|
||||||
|
|||||||
Reference in New Issue
Block a user