diff options
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/gr_gv11b.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c index 28284b45..c1dc7920 100644 --- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "gk20a/gk20a.h" | 29 | #include "gk20a/gk20a.h" |
30 | #include "gk20a/gr_gk20a.h" | 30 | #include "gk20a/gr_gk20a.h" |
31 | #include "gk20a/dbg_gpu_gk20a.h" | 31 | #include "gk20a/dbg_gpu_gk20a.h" |
32 | #include "gk20a/regops_gk20a.h" | ||
32 | 33 | ||
33 | #include "gm20b/gr_gm20b.h" | 34 | #include "gm20b/gr_gm20b.h" |
34 | 35 | ||
@@ -2613,6 +2614,65 @@ fail: | |||
2613 | return err; | 2614 | return err; |
2614 | } | 2615 | } |
2615 | 2616 | ||
2617 | static int gv11b_gr_set_sm_debug_mode(struct gk20a *g, | ||
2618 | struct channel_gk20a *ch, u64 sms, bool enable) | ||
2619 | { | ||
2620 | struct nvgpu_dbg_gpu_reg_op *ops; | ||
2621 | unsigned int i = 0, sm_id; | ||
2622 | int err; | ||
2623 | |||
2624 | ops = nvgpu_kcalloc(g, g->gr.no_of_sm, sizeof(*ops)); | ||
2625 | if (!ops) | ||
2626 | return -ENOMEM; | ||
2627 | for (sm_id = 0; sm_id < g->gr.no_of_sm; sm_id++) { | ||
2628 | u32 gpc, tpc, sm; | ||
2629 | u32 reg_offset, reg_mask, reg_val; | ||
2630 | |||
2631 | if (!(sms & (1 << sm_id))) | ||
2632 | continue; | ||
2633 | |||
2634 | gpc = g->gr.sm_to_cluster[sm_id].gpc_index; | ||
2635 | tpc = g->gr.sm_to_cluster[sm_id].tpc_index; | ||
2636 | sm = g->gr.sm_to_cluster[sm_id].sm_index; | ||
2637 | |||
2638 | reg_offset = gk20a_gr_gpc_offset(g, gpc) + | ||
2639 | gk20a_gr_tpc_offset(g, tpc) + | ||
2640 | gv11b_gr_sm_offset(g, sm); | ||
2641 | |||
2642 | ops[i].op = REGOP(WRITE_32); | ||
2643 | ops[i].type = REGOP(TYPE_GR_CTX); | ||
2644 | ops[i].offset = gr_gpc0_tpc0_sm0_dbgr_control0_r() + reg_offset; | ||
2645 | |||
2646 | reg_mask = 0; | ||
2647 | reg_val = 0; | ||
2648 | if (enable) { | ||
2649 | nvgpu_log(g, gpu_dbg_gpu_dbg, | ||
2650 | "SM:%d debuggger mode ON", sm); | ||
2651 | reg_mask |= | ||
2652 | gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_m(); | ||
2653 | reg_val |= | ||
2654 | gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_on_f(); | ||
2655 | } else { | ||
2656 | nvgpu_log(g, gpu_dbg_gpu_dbg, | ||
2657 | "SM:%d debuggger mode Off", sm); | ||
2658 | reg_mask |= | ||
2659 | gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_m(); | ||
2660 | reg_val |= | ||
2661 | gr_gpc0_tpc0_sm0_dbgr_control0_debugger_mode_off_f(); | ||
2662 | } | ||
2663 | |||
2664 | ops[i].and_n_mask_lo = reg_mask; | ||
2665 | ops[i].value_lo = reg_val; | ||
2666 | i++; | ||
2667 | } | ||
2668 | |||
2669 | err = gr_gk20a_exec_ctx_ops(ch, ops, i, i, 0); | ||
2670 | if (err) | ||
2671 | nvgpu_err(g, "Failed to access register\n"); | ||
2672 | nvgpu_kfree(g, ops); | ||
2673 | return err; | ||
2674 | } | ||
2675 | |||
2616 | void gv11b_init_gr(struct gpu_ops *gops) | 2676 | void gv11b_init_gr(struct gpu_ops *gops) |
2617 | { | 2677 | { |
2618 | gp10b_init_gr(gops); | 2678 | gp10b_init_gr(gops); |
@@ -2678,4 +2738,5 @@ void gv11b_init_gr(struct gpu_ops *gops) | |||
2678 | gops->gr.trigger_suspend = gv11b_gr_sm_trigger_suspend; | 2738 | gops->gr.trigger_suspend = gv11b_gr_sm_trigger_suspend; |
2679 | gops->gr.bpt_reg_info = gv11b_gr_bpt_reg_info; | 2739 | gops->gr.bpt_reg_info = gv11b_gr_bpt_reg_info; |
2680 | gops->gr.update_sm_error_state = gv11b_gr_update_sm_error_state; | 2740 | gops->gr.update_sm_error_state = gv11b_gr_update_sm_error_state; |
2741 | gops->gr.set_sm_debug_mode = gv11b_gr_set_sm_debug_mode; | ||
2681 | } | 2742 | } |