diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 80 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 8 |
3 files changed, 85 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index 1397549e..1f1b164f 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Tegra GK20A GPU Debugger/Profiler Driver | 2 | * Tegra GK20A GPU Debugger/Profiler Driver |
3 | * | 3 | * |
4 | * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2013-2016, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
@@ -867,7 +867,7 @@ static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm( | |||
867 | if (ch_is_curr_ctx) { | 867 | if (ch_is_curr_ctx) { |
868 | switch (action) { | 868 | switch (action) { |
869 | case NVGPU_DBG_GPU_SUSPEND_ALL_SMS: | 869 | case NVGPU_DBG_GPU_SUSPEND_ALL_SMS: |
870 | gk20a_suspend_all_sms(g); | 870 | gk20a_suspend_all_sms(g, 0, false); |
871 | break; | 871 | break; |
872 | 872 | ||
873 | case NVGPU_DBG_GPU_RESUME_ALL_SMS: | 873 | case NVGPU_DBG_GPU_RESUME_ALL_SMS: |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 6f4669f2..7f02dc43 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -7021,7 +7021,42 @@ int gk20a_gr_wait_for_sm_lock_down(struct gk20a *g, u32 gpc, u32 tpc, | |||
7021 | return -EAGAIN; | 7021 | return -EAGAIN; |
7022 | } | 7022 | } |
7023 | 7023 | ||
7024 | void gk20a_suspend_all_sms(struct gk20a *g) | 7024 | void gk20a_suspend_single_sm(struct gk20a *g, |
7025 | u32 gpc, u32 tpc, | ||
7026 | u32 global_esr_mask, bool check_errors) | ||
7027 | { | ||
7028 | u32 offset; | ||
7029 | int err; | ||
7030 | u32 dbgr_control0; | ||
7031 | |||
7032 | offset = proj_gpc_stride_v() * gpc + | ||
7033 | proj_tpc_in_gpc_stride_v() * tpc; | ||
7034 | |||
7035 | /* if an SM debugger isn't attached, skip suspend */ | ||
7036 | if (!gk20a_gr_sm_debugger_attached(g)) { | ||
7037 | gk20a_err(dev_from_gk20a(g), | ||
7038 | "SM debugger not attached, skipping suspend!\n"); | ||
7039 | return; | ||
7040 | } | ||
7041 | |||
7042 | /* assert stop trigger. */ | ||
7043 | dbgr_control0 = gk20a_readl(g, | ||
7044 | gr_gpc0_tpc0_sm_dbgr_control0_r() + offset); | ||
7045 | dbgr_control0 |= gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_enable_f(); | ||
7046 | gk20a_writel(g, gr_gpc0_tpc0_sm_dbgr_control0_r() + offset, | ||
7047 | dbgr_control0); | ||
7048 | |||
7049 | err = gk20a_gr_wait_for_sm_lock_down(g, gpc, tpc, | ||
7050 | global_esr_mask, check_errors); | ||
7051 | if (err) { | ||
7052 | gk20a_err(dev_from_gk20a(g), | ||
7053 | "SuspendSm failed\n"); | ||
7054 | return; | ||
7055 | } | ||
7056 | } | ||
7057 | |||
7058 | void gk20a_suspend_all_sms(struct gk20a *g, | ||
7059 | u32 global_esr_mask, bool check_errors) | ||
7025 | { | 7060 | { |
7026 | struct gr_gk20a *gr = &g->gr; | 7061 | struct gr_gk20a *gr = &g->gr; |
7027 | u32 gpc, tpc; | 7062 | u32 gpc, tpc; |
@@ -7030,8 +7065,8 @@ void gk20a_suspend_all_sms(struct gk20a *g) | |||
7030 | 7065 | ||
7031 | /* if an SM debugger isn't attached, skip suspend */ | 7066 | /* if an SM debugger isn't attached, skip suspend */ |
7032 | if (!gk20a_gr_sm_debugger_attached(g)) { | 7067 | if (!gk20a_gr_sm_debugger_attached(g)) { |
7033 | gk20a_err(dev_from_gk20a(g), "SM debugger not attached, " | 7068 | gk20a_err(dev_from_gk20a(g), |
7034 | "skipping suspend!\n"); | 7069 | "SM debugger not attached, skipping suspend!\n"); |
7035 | return; | 7070 | return; |
7036 | } | 7071 | } |
7037 | 7072 | ||
@@ -7048,7 +7083,8 @@ void gk20a_suspend_all_sms(struct gk20a *g) | |||
7048 | for (gpc = 0; gpc < gr->gpc_count; gpc++) { | 7083 | for (gpc = 0; gpc < gr->gpc_count; gpc++) { |
7049 | for (tpc = 0; tpc < gr->tpc_count; tpc++) { | 7084 | for (tpc = 0; tpc < gr->tpc_count; tpc++) { |
7050 | err = | 7085 | err = |
7051 | gk20a_gr_wait_for_sm_lock_down(g, gpc, tpc, 0, false); | 7086 | gk20a_gr_wait_for_sm_lock_down(g, gpc, tpc, |
7087 | global_esr_mask, check_errors); | ||
7052 | if (err) { | 7088 | if (err) { |
7053 | gk20a_err(dev_from_gk20a(g), | 7089 | gk20a_err(dev_from_gk20a(g), |
7054 | "SuspendAllSms failed\n"); | 7090 | "SuspendAllSms failed\n"); |
@@ -7058,6 +7094,42 @@ void gk20a_suspend_all_sms(struct gk20a *g) | |||
7058 | } | 7094 | } |
7059 | } | 7095 | } |
7060 | 7096 | ||
7097 | void gk20a_resume_single_sm(struct gk20a *g, | ||
7098 | u32 gpc, u32 tpc) | ||
7099 | { | ||
7100 | u32 dbgr_control0; | ||
7101 | u32 offset; | ||
7102 | /* | ||
7103 | * The following requires some clarification. Despite the fact that both | ||
7104 | * RUN_TRIGGER and STOP_TRIGGER have the word "TRIGGER" in their | ||
7105 | * names, only one is actually a trigger, and that is the STOP_TRIGGER. | ||
7106 | * Merely writing a 1(_TASK) to the RUN_TRIGGER is not sufficient to | ||
7107 | * resume the gpu - the _STOP_TRIGGER must explicitly be set to 0 | ||
7108 | * (_DISABLE) as well. | ||
7109 | |||
7110 | * Advice from the arch group: Disable the stop trigger first, as a | ||
7111 | * separate operation, in order to ensure that the trigger has taken | ||
7112 | * effect, before enabling the run trigger. | ||
7113 | */ | ||
7114 | |||
7115 | offset = proj_gpc_stride_v() * gpc + | ||
7116 | proj_tpc_in_gpc_stride_v() * tpc; | ||
7117 | |||
7118 | /*De-assert stop trigger */ | ||
7119 | dbgr_control0 = | ||
7120 | gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r() + offset); | ||
7121 | dbgr_control0 = set_field(dbgr_control0, | ||
7122 | gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_m(), | ||
7123 | gr_gpcs_tpcs_sm_dbgr_control0_stop_trigger_disable_f()); | ||
7124 | gk20a_writel(g, | ||
7125 | gr_gpcs_tpcs_sm_dbgr_control0_r() + offset, dbgr_control0); | ||
7126 | |||
7127 | /* Run trigger */ | ||
7128 | dbgr_control0 |= gr_gpcs_tpcs_sm_dbgr_control0_run_trigger_task_f(); | ||
7129 | gk20a_writel(g, | ||
7130 | gr_gpc0_tpc0_sm_dbgr_control0_r() + offset, dbgr_control0); | ||
7131 | } | ||
7132 | |||
7061 | void gk20a_resume_all_sms(struct gk20a *g) | 7133 | void gk20a_resume_all_sms(struct gk20a *g) |
7062 | { | 7134 | { |
7063 | u32 dbgr_control0; | 7135 | u32 dbgr_control0; |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index 9fc45ec0..29c2dcf6 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h | |||
@@ -498,8 +498,14 @@ void gr_gk20a_load_ctxsw_ucode_boot(struct gk20a *g, u64 addr_base, | |||
498 | void gr_gk20a_free_tsg_gr_ctx(struct tsg_gk20a *c); | 498 | void gr_gk20a_free_tsg_gr_ctx(struct tsg_gk20a *c); |
499 | int gr_gk20a_disable_ctxsw(struct gk20a *g); | 499 | int gr_gk20a_disable_ctxsw(struct gk20a *g); |
500 | int gr_gk20a_enable_ctxsw(struct gk20a *g); | 500 | int gr_gk20a_enable_ctxsw(struct gk20a *g); |
501 | void gk20a_resume_single_sm(struct gk20a *g, | ||
502 | u32 gpc, u32 tpc); | ||
501 | void gk20a_resume_all_sms(struct gk20a *g); | 503 | void gk20a_resume_all_sms(struct gk20a *g); |
502 | void gk20a_suspend_all_sms(struct gk20a *g); | 504 | void gk20a_suspend_single_sm(struct gk20a *g, |
505 | u32 gpc, u32 tpc, | ||
506 | u32 global_esr_mask, bool check_errors); | ||
507 | void gk20a_suspend_all_sms(struct gk20a *g, | ||
508 | u32 global_esr_mask, bool check_errors); | ||
503 | int gk20a_gr_lock_down_sm(struct gk20a *g, | 509 | int gk20a_gr_lock_down_sm(struct gk20a *g, |
504 | u32 gpc, u32 tpc, u32 global_esr_mask); | 510 | u32 gpc, u32 tpc, u32 global_esr_mask); |
505 | bool gk20a_is_channel_ctx_resident(struct channel_gk20a *ch); | 511 | bool gk20a_is_channel_ctx_resident(struct channel_gk20a *ch); |