summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 4c88751e..3354c05e 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -8458,6 +8458,123 @@ static void gr_gk20a_get_access_map(struct gk20a *g,
8458 *num_entries = ARRAY_SIZE(wl_addr_gk20a); 8458 *num_entries = ARRAY_SIZE(wl_addr_gk20a);
8459} 8459}
8460 8460
8461/*
8462 * gr_gk20a_suspend_context()
8463 * This API should be called with dbg_session lock held
8464 * and ctxsw disabled
8465 * Returns bool value indicating if context was resident
8466 * or not
8467 */
8468bool gr_gk20a_suspend_context(struct channel_gk20a *ch)
8469{
8470 struct gk20a *g = ch->g;
8471 bool ctx_resident = false;
8472
8473 if (gk20a_is_channel_ctx_resident(ch)) {
8474 gk20a_suspend_all_sms(g, 0, false);
8475 ctx_resident = true;
8476 } else {
8477 gk20a_disable_channel_tsg(g, ch);
8478 }
8479
8480 return ctx_resident;
8481}
8482
8483bool gr_gk20a_resume_context(struct channel_gk20a *ch)
8484{
8485 struct gk20a *g = ch->g;
8486 bool ctx_resident = false;
8487
8488 if (gk20a_is_channel_ctx_resident(ch)) {
8489 gk20a_resume_all_sms(g);
8490 ctx_resident = true;
8491 } else {
8492 gk20a_enable_channel_tsg(g, ch);
8493 }
8494
8495 return ctx_resident;
8496}
8497
8498int gr_gk20a_suspend_contexts(struct gk20a *g,
8499 struct dbg_session_gk20a *dbg_s,
8500 int *ctx_resident_ch_fd)
8501{
8502 int local_ctx_resident_ch_fd = -1;
8503 bool ctx_resident;
8504 struct channel_gk20a *ch;
8505 struct dbg_session_channel_data *ch_data;
8506 int err = 0;
8507
8508 mutex_lock(&g->dbg_sessions_lock);
8509
8510 err = gr_gk20a_disable_ctxsw(g);
8511 if (err) {
8512 gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw");
8513 goto clean_up;
8514 }
8515
8516 mutex_lock(&dbg_s->ch_list_lock);
8517
8518 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
8519 ch = g->fifo.channel + ch_data->chid;
8520
8521 ctx_resident = gr_gk20a_suspend_context(ch);
8522 if (ctx_resident)
8523 local_ctx_resident_ch_fd = ch_data->channel_fd;
8524 }
8525
8526 mutex_unlock(&dbg_s->ch_list_lock);
8527
8528 err = gr_gk20a_enable_ctxsw(g);
8529 if (err)
8530 gk20a_err(dev_from_gk20a(g), "unable to restart ctxsw!\n");
8531
8532 *ctx_resident_ch_fd = local_ctx_resident_ch_fd;
8533
8534clean_up:
8535 mutex_unlock(&g->dbg_sessions_lock);
8536
8537 return err;
8538}
8539
8540int gr_gk20a_resume_contexts(struct gk20a *g,
8541 struct dbg_session_gk20a *dbg_s,
8542 int *ctx_resident_ch_fd)
8543{
8544 int local_ctx_resident_ch_fd = -1;
8545 bool ctx_resident;
8546 struct channel_gk20a *ch;
8547 int err = 0;
8548 struct dbg_session_channel_data *ch_data;
8549
8550 mutex_lock(&g->dbg_sessions_lock);
8551
8552 err = gr_gk20a_disable_ctxsw(g);
8553 if (err) {
8554 gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw");
8555 goto clean_up;
8556 }
8557
8558 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
8559 ch = g->fifo.channel + ch_data->chid;
8560
8561 ctx_resident = gr_gk20a_resume_context(ch);
8562 if (ctx_resident)
8563 local_ctx_resident_ch_fd = ch_data->channel_fd;
8564 }
8565
8566 err = gr_gk20a_enable_ctxsw(g);
8567 if (err)
8568 gk20a_err(dev_from_gk20a(g), "unable to restart ctxsw!\n");
8569
8570 *ctx_resident_ch_fd = local_ctx_resident_ch_fd;
8571
8572clean_up:
8573 mutex_unlock(&g->dbg_sessions_lock);
8574
8575 return err;
8576}
8577
8461void gk20a_init_gr_ops(struct gpu_ops *gops) 8578void gk20a_init_gr_ops(struct gpu_ops *gops)
8462{ 8579{
8463 gops->gr.access_smpc_reg = gr_gk20a_access_smpc_reg; 8580 gops->gr.access_smpc_reg = gr_gk20a_access_smpc_reg;
@@ -8522,4 +8639,5 @@ void gk20a_init_gr_ops(struct gpu_ops *gops)
8522 gops->gr.record_sm_error_state = gk20a_gr_record_sm_error_state; 8639 gops->gr.record_sm_error_state = gk20a_gr_record_sm_error_state;
8523 gops->gr.update_sm_error_state = gk20a_gr_update_sm_error_state; 8640 gops->gr.update_sm_error_state = gk20a_gr_update_sm_error_state;
8524 gops->gr.clear_sm_error_state = gk20a_gr_clear_sm_error_state; 8641 gops->gr.clear_sm_error_state = gk20a_gr_clear_sm_error_state;
8642 gops->gr.suspend_contexts = gr_gk20a_suspend_contexts;
8525} 8643}