summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu/gr_vgpu.c')
-rw-r--r--drivers/gpu/nvgpu/vgpu/gr_vgpu.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
index 5c637d25..7ffe96fe 100644
--- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
@@ -1085,6 +1085,83 @@ static int vgpu_gr_clear_sm_error_state(struct gk20a *g,
1085 return 0; 1085 return 0;
1086} 1086}
1087 1087
1088static int vgpu_gr_suspend_resume_contexts(struct gk20a *g,
1089 struct dbg_session_gk20a *dbg_s,
1090 int *ctx_resident_ch_fd, u32 cmd)
1091{
1092 struct dbg_session_channel_data *ch_data;
1093 struct tegra_vgpu_cmd_msg *msg;
1094 struct tegra_vgpu_suspend_resume_contexts *p;
1095 size_t size_out = offsetof(struct tegra_vgpu_cmd_msg,
1096 params.suspend_contexts.chids);
1097 size_t size_in;
1098 size_t n;
1099 int channel_fd = -1;
1100 int err = 0;
1101
1102 mutex_lock(&g->dbg_sessions_lock);
1103 mutex_lock(&dbg_s->ch_list_lock);
1104
1105 n = 0;
1106 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry)
1107 n++;
1108
1109 size_in = size_out + n * sizeof(u16);
1110
1111 msg = kmalloc(size_in, GFP_KERNEL);
1112 if (!msg)
1113 return -ENOMEM;
1114
1115 msg->cmd = cmd;
1116 msg->handle = vgpu_get_handle(g);
1117 p = &msg->params.suspend_contexts;
1118 p->num_channels = n;
1119 n = 0;
1120 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
1121 p->chids[n++] = (u16)ch_data->chid;
1122 }
1123
1124 err = vgpu_comm_sendrecv(msg, size_in, size_out);
1125 if (err || msg->ret) {
1126 err = -ENOMEM;
1127 goto fail;
1128 }
1129
1130 if (p->resident_chid != (u16)~0) {
1131 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
1132 if (ch_data->chid == p->resident_chid) {
1133 channel_fd = ch_data->channel_fd;
1134 break;
1135 }
1136 }
1137 }
1138
1139fail:
1140 mutex_unlock(&dbg_s->ch_list_lock);
1141 mutex_unlock(&g->dbg_sessions_lock);
1142
1143 *ctx_resident_ch_fd = channel_fd;
1144 kfree(msg);
1145
1146 return err;
1147}
1148
1149static int vgpu_gr_suspend_contexts(struct gk20a *g,
1150 struct dbg_session_gk20a *dbg_s,
1151 int *ctx_resident_ch_fd)
1152{
1153 return vgpu_gr_suspend_resume_contexts(g, dbg_s,
1154 ctx_resident_ch_fd, TEGRA_VGPU_CMD_SUSPEND_CONTEXTS);
1155}
1156
1157static int vgpu_gr_resume_contexts(struct gk20a *g,
1158 struct dbg_session_gk20a *dbg_s,
1159 int *ctx_resident_ch_fd)
1160{
1161 return vgpu_gr_suspend_resume_contexts(g, dbg_s,
1162 ctx_resident_ch_fd, TEGRA_VGPU_CMD_RESUME_CONTEXTS);
1163}
1164
1088void vgpu_gr_handle_sm_esr_event(struct gk20a *g, 1165void vgpu_gr_handle_sm_esr_event(struct gk20a *g,
1089 struct tegra_vgpu_sm_esr_info *info) 1166 struct tegra_vgpu_sm_esr_info *info)
1090{ 1167{
@@ -1133,6 +1210,8 @@ void vgpu_init_gr_ops(struct gpu_ops *gops)
1133 gops->gr.update_smpc_ctxsw_mode = vgpu_gr_update_smpc_ctxsw_mode; 1210 gops->gr.update_smpc_ctxsw_mode = vgpu_gr_update_smpc_ctxsw_mode;
1134 gops->gr.update_hwpm_ctxsw_mode = vgpu_gr_update_hwpm_ctxsw_mode; 1211 gops->gr.update_hwpm_ctxsw_mode = vgpu_gr_update_hwpm_ctxsw_mode;
1135 gops->gr.clear_sm_error_state = vgpu_gr_clear_sm_error_state; 1212 gops->gr.clear_sm_error_state = vgpu_gr_clear_sm_error_state;
1213 gops->gr.suspend_contexts = vgpu_gr_suspend_contexts;
1214 gops->gr.resume_contexts = vgpu_gr_resume_contexts;
1136 gops->gr.dump_gr_regs = NULL; 1215 gops->gr.dump_gr_regs = NULL;
1137 gops->gr.set_boosted_ctx = NULL; 1216 gops->gr.set_boosted_ctx = NULL;
1138 gops->gr.update_boosted_ctx = NULL; 1217 gops->gr.update_boosted_ctx = NULL;