diff --git a/drivers/gpu/nvgpu/common/pmu/pg/pg_sw_ga10b.c b/drivers/gpu/nvgpu/common/pmu/pg/pg_sw_ga10b.c index d1cad1f3e..88ecd1473 100644 --- a/drivers/gpu/nvgpu/common/pmu/pg/pg_sw_ga10b.c +++ b/drivers/gpu/nvgpu/common/pmu/pg/pg_sw_ga10b.c @@ -342,6 +342,9 @@ static void ga10b_pg_rpc_handler(struct gk20a *g, struct nvgpu_pmu *pmu, nvgpu_err(g, "Invalid pg_engine_id"); } break; + case NV_PMU_RPC_ID_PG_PG_CTRL_STATS_GET: + nvgpu_pmu_dbg(g, "Reply to PG_STATS_GET"); + break; default: nvgpu_err(g, "unsupported PG rpc function : 0x%x", rpc->function); @@ -352,25 +355,27 @@ static void ga10b_pg_rpc_handler(struct gk20a *g, struct nvgpu_pmu *pmu, static int ga10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id, struct pmu_pg_stats_data *pg_stat_data) { - struct nvgpu_pmu *pmu = g->pmu; - struct pmu_pg_stats_v3 stats; - int err; + struct pmu_rpc_struct_lpwr_pg_ctrl_stats_get rpc; + int status = 0; - err = nvgpu_falcon_copy_from_dmem(pmu->flcn, - pmu->pg->stat_dmem_offset[pg_engine_id], - (u8 *)&stats, (u32)sizeof(struct pmu_pg_stats_v3), 0); - if (err != 0) { - nvgpu_err(g, "PMU falcon DMEM copy failed"); - return err; + (void) memset(&rpc, 0, + sizeof(struct pmu_rpc_struct_lpwr_pg_ctrl_stats_get)); + + rpc.ctrl_id = (u32)pg_engine_id; + PMU_RPC_EXECUTE_CPB(status, g->pmu, PG, PG_CTRL_STATS_GET, &rpc, 0); + + if (status != 0) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", status); + return status; } - 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; + pg_stat_data->ingating_time = rpc.stats.total_sleep_time_us; + pg_stat_data->ungating_time = rpc.stats.total_non_sleep_time_us; + pg_stat_data->gating_cnt = rpc.stats.entry_count; + pg_stat_data->avg_entry_latency_us = rpc.stats.entry_latency_avg_us; + pg_stat_data->avg_exit_latency_us = rpc.stats.exit_latency_avg_us; - return err; + return status; } static int ga10b_pmu_pg_handle_async_cmd_resp(struct gk20a *g, u32 ctrl_id, diff --git a/drivers/gpu/nvgpu/common/pmu/pg/pg_sw_ga10b.h b/drivers/gpu/nvgpu/common/pmu/pg/pg_sw_ga10b.h index f2a5fe672..f6c49ca23 100644 --- a/drivers/gpu/nvgpu/common/pmu/pg/pg_sw_ga10b.h +++ b/drivers/gpu/nvgpu/common/pmu/pg/pg_sw_ga10b.h @@ -324,6 +324,31 @@ struct pmu_pg_stats_v3 u32 hw_disallow_reason_mask; }; +/* + * Defines the structure that holds data used to execute PG_CTRL_STATS_GET RPC. + */ +struct pmu_rpc_struct_lpwr_pg_ctrl_stats_get { + /*! + * Must be first field in RPC structure. + */ + struct nv_pmu_rpc_header hdr; + /*! + * PgCtrl statistics + */ + struct pmu_pg_stats_v3 stats; + /*! + * Control ID + */ + u8 ctrl_id; + /*! + * Must be last field in RPC structure. + * Used as variable size scrach space on + * RM managed DMEM heap for this RPC. + */ + u32 scratch[1]; +}; + + void nvgpu_ga10b_pg_sw_init(struct gk20a *g, struct nvgpu_pmu_pg *pg); u32 ga10b_pmu_pg_engines_list(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/pg.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/pg.h index e03eb02f5..94ade0bd8 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/pg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/pg.h @@ -44,7 +44,8 @@ #define NV_PMU_RPC_ID_PG_ALLOW 0x04U #define NV_PMU_RPC_ID_PG_DISALLOW 0x05U #define NV_PMU_RPC_ID_PG_THRESHOLD_UPDATE 0x06U -#define NV_PMU_RPC_ID_PG_SFM_UPDATE 0x08U +#define NV_PMU_RPC_ID_PG_PG_CTRL_STATS_GET 0x07U +#define NV_PMU_RPC_ID_PG_SFM_UPDATE 0x09U /* PG unit RPC functions sent by PMU */ #define PMU_NV_RPC_ID_LPWR_PG_ASYNC_CMD_RESP 0x00U