From 1b04326f400489f25399167ef9f1c931a576656e Mon Sep 17 00:00:00 2001 From: Peter Daifuku Date: Thu, 9 Jun 2016 16:09:52 -0700 Subject: gpu: nvgpu: vgpu: dbg_set_powergate support Add support for dbg_set_powergate when virtualized Jira VFND-1905 Change-Id: I0d81c8863b3eda4ae4fee42e5a95d2fc9d78b174 Signed-off-by: Peter Daifuku Reviewed-on: http://git-master/r/1162048 (cherry picked from commit 0dfc55f390a10e21ae13e14dd2f16e89a3bddfa7) Reviewed-on: http://git-master/r/1167182 (cherry picked from commit 4e34a1844558d93da5ad208532ec28aeda228f95) Reviewed-on: http://git-master/r/1174701 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Richard Zhao Reviewed-by: Vladislav Buzov --- drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 28 ++++++++++++------------- drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h | 1 + drivers/gpu/nvgpu/vgpu/dbg_vgpu.c | 36 ++++++++++++++++++++++++++++++++- include/linux/tegra_vgpu.h | 6 ++++++ 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index 5e57502e..a23758ab 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c @@ -31,8 +31,11 @@ #include "hw_gr_gk20a.h" #include "hw_perf_gk20a.h" +static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode); + struct dbg_gpu_session_ops dbg_gpu_session_ops_gk20a = { .exec_reg_ops = exec_regops_gk20a, + .dbg_set_powergate = dbg_set_powergate, }; /* @@ -116,11 +119,6 @@ static int gk20a_dbg_gpu_do_dev_open(struct inode *inode, dbg_session->is_profiler = is_profiler; dbg_session->is_pg_disabled = false; dbg_session->is_timeout_disabled = false; - /* For vgpu, all power-gating features are currently disabled - * in the server. Set is_pg_disable to true to reflect this - * on the client side. */ - if (gk20a_gpu_is_virtual(dev)) - dbg_session->is_pg_disabled = true; init_waitqueue_head(&dbg_session->dbg_events.wait_queue); INIT_LIST_HEAD(&dbg_session->ch_list); @@ -344,9 +342,6 @@ int gk20a_dbg_gpu_clear_broadcast_stop_trigger(struct channel_gk20a *ch) return 0; } -static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, - __u32 powermode); - static int nvgpu_dbg_timeout_enable(struct dbg_session_gk20a *dbg_s, int timeout_mode) { @@ -483,7 +478,8 @@ int gk20a_dbg_gpu_dev_release(struct inode *inode, struct file *filp) * calling powergate/timeout enable ioctl */ mutex_lock(&g->dbg_sessions_lock); - dbg_set_powergate(dbg_s, NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE); + dbg_s->ops->dbg_set_powergate(dbg_s, + NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE); nvgpu_dbg_timeout_enable(dbg_s, NVGPU_DBG_GPU_IOCTL_TIMEOUT_ENABLE); mutex_unlock(&g->dbg_sessions_lock); @@ -1018,8 +1014,11 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, * on other channels */ mutex_lock(&g->dbg_sessions_lock); - if (!dbg_s->is_pg_disabled) { - powergate_err = dbg_set_powergate(dbg_s, + if (!dbg_s->is_pg_disabled && !gk20a_gpu_is_virtual(dbg_s->dev)) { + /* In the virtual case, the server will handle + * disabling/enabling powergating when processing reg ops + */ + powergate_err = dbg_s->ops->dbg_set_powergate(dbg_s, NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE); is_pg_disabled = true; } @@ -1028,7 +1027,7 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, err = dbg_s->ops->exec_reg_ops(dbg_s, ops, args->num_ops); /* enable powergate, if previously disabled */ if (is_pg_disabled) { - powergate_err = dbg_set_powergate(dbg_s, + powergate_err = dbg_s->ops->dbg_set_powergate(dbg_s, NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE); } } @@ -1056,8 +1055,7 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s, return err; } -static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, - __u32 powermode) +static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) { int err = 0; struct gk20a *g = get_gk20a(dbg_s->dev); @@ -1168,7 +1166,7 @@ static int nvgpu_ioctl_powergate_gk20a(struct dbg_session_gk20a *dbg_s, dev_name(dbg_s->dev), args->mode); mutex_lock(&g->dbg_sessions_lock); - err = dbg_set_powergate(dbg_s, args->mode); + err = dbg_s->ops->dbg_set_powergate(dbg_s, args->mode); mutex_unlock(&g->dbg_sessions_lock); return err; } diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h index d569a6cd..55ff54b9 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.h @@ -38,6 +38,7 @@ struct dbg_gpu_session_ops { int (*exec_reg_ops)(struct dbg_session_gk20a *dbg_s, struct nvgpu_dbg_gpu_reg_op *ops, u64 num_ops); + int (*dbg_set_powergate)(struct dbg_session_gk20a *dbg_s, u32 mode); }; struct dbg_gpu_session_events { diff --git a/drivers/gpu/nvgpu/vgpu/dbg_vgpu.c b/drivers/gpu/nvgpu/vgpu/dbg_vgpu.c index a9533e03..38f072de 100644 --- a/drivers/gpu/nvgpu/vgpu/dbg_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/dbg_vgpu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -69,7 +69,41 @@ fail: return err; } +static int vgpu_dbg_set_powergate(struct dbg_session_gk20a *dbg_s, __u32 mode) +{ + struct gk20a_platform *platform = gk20a_get_platform(dbg_s->g->dev); + struct tegra_vgpu_cmd_msg msg; + struct tegra_vgpu_set_powergate_params *p = &msg.params.set_powergate; + int err = 0; + + gk20a_dbg_fn(""); + + /* Just return if requested mode is the same as the session's mode */ + switch (mode) { + case NVGPU_DBG_GPU_POWERGATE_MODE_DISABLE: + if (dbg_s->is_pg_disabled) + return 0; + dbg_s->is_pg_disabled = true; + break; + case NVGPU_DBG_GPU_POWERGATE_MODE_ENABLE: + if (!dbg_s->is_pg_disabled) + return 0; + dbg_s->is_pg_disabled = false; + break; + default: + return -EINVAL; + } + + msg.cmd = TEGRA_VGPU_CMD_SET_POWERGATE; + msg.handle = platform->virt_handle; + p->mode = mode; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + return err; +} + void vgpu_dbg_init(void) { dbg_gpu_session_ops_gk20a.exec_reg_ops = vgpu_exec_regops; + dbg_gpu_session_ops_gk20a.dbg_set_powergate = vgpu_dbg_set_powergate; } diff --git a/include/linux/tegra_vgpu.h b/include/linux/tegra_vgpu.h index 196b08ca..6e8f5d53 100644 --- a/include/linux/tegra_vgpu.h +++ b/include/linux/tegra_vgpu.h @@ -96,6 +96,7 @@ enum { TEGRA_VGPU_CMD_CHANNEL_FORCE_RESET = 57, TEGRA_VGPU_CMD_CHANNEL_ENABLE = 58, TEGRA_VGPU_CMD_READ_PTIMER = 59, + TEGRA_VGPU_CMD_SET_POWERGATE = 60, }; struct tegra_vgpu_connect_params { @@ -394,6 +395,10 @@ struct tegra_vgpu_read_ptimer_params { u64 time; }; +struct tegra_vgpu_set_powergate_params { + u32 mode; +}; + struct tegra_vgpu_cmd_msg { u32 cmd; int ret; @@ -435,6 +440,7 @@ struct tegra_vgpu_cmd_msg { struct tegra_vgpu_tsg_timeslice_params tsg_timeslice; struct tegra_vgpu_tsg_runlist_interleave_params tsg_interleave; struct tegra_vgpu_read_ptimer_params read_ptimer; + struct tegra_vgpu_set_powergate_params set_powergate; char padding[192]; } params; }; -- cgit v1.2.2