aboutsummaryrefslogtreecommitdiffstats
path: root/include/gk20a/dbg_gpu_gk20a.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2023-06-28 18:24:25 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2023-06-28 18:24:25 -0400
commit01e6fac4d61fdd7fff5433942ec93fc2ea1e4df1 (patch)
tree4ef34501728a087be24f4ba0af90f91486bf780b /include/gk20a/dbg_gpu_gk20a.c
parent306a03d18b305e4e573be3b2931978fa10679eb9 (diff)
Include nvgpu headers
These are needed to build on NVIDIA's Jetson boards for the time being. Only a couple structs are required, so it should be fairly easy to remove this dependency at some point in the future.
Diffstat (limited to 'include/gk20a/dbg_gpu_gk20a.c')
-rw-r--r--include/gk20a/dbg_gpu_gk20a.c388
1 files changed, 388 insertions, 0 deletions
diff --git a/include/gk20a/dbg_gpu_gk20a.c b/include/gk20a/dbg_gpu_gk20a.c
new file mode 100644
index 0000000..1686d01
--- /dev/null
+++ b/include/gk20a/dbg_gpu_gk20a.c
@@ -0,0 +1,388 @@
1/*
2 * Tegra GK20A GPU Debugger/Profiler Driver
3 *
4 * Copyright (c) 2013-2019, NVIDIA CORPORATION. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <nvgpu/kmem.h>
26#include <nvgpu/log.h>
27#include <nvgpu/vm.h>
28#include <nvgpu/atomic.h>
29#include <nvgpu/mm.h>
30#include <nvgpu/bug.h>
31#include <nvgpu/io.h>
32#include <nvgpu/utils.h>
33#include <nvgpu/channel.h>
34#include <nvgpu/unit.h>
35#include <nvgpu/power_features/power_features.h>
36
37#include "gk20a.h"
38#include "gr_gk20a.h"
39#include "dbg_gpu_gk20a.h"
40#include "regops_gk20a.h"
41
42#include <nvgpu/hw/gk20a/hw_gr_gk20a.h>
43#include <nvgpu/hw/gk20a/hw_perf_gk20a.h>
44
45static void gk20a_perfbuf_reset_streaming(struct gk20a *g)
46{
47 u32 engine_status;
48 u32 num_unread_bytes;
49
50 g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_PERFMON));
51
52 engine_status = gk20a_readl(g, perf_pmasys_enginestatus_r());
53 WARN_ON(0u ==
54 (engine_status & perf_pmasys_enginestatus_rbufempty_empty_f()));
55
56 gk20a_writel(g, perf_pmasys_control_r(),
57 perf_pmasys_control_membuf_clear_status_doit_f());
58
59 num_unread_bytes = gk20a_readl(g, perf_pmasys_mem_bytes_r());
60 if (num_unread_bytes != 0u) {
61 gk20a_writel(g, perf_pmasys_mem_bump_r(), num_unread_bytes);
62 }
63}
64
65/*
66 * API to get first channel from the list of all channels
67 * bound to the debug session
68 */
69struct channel_gk20a *
70nvgpu_dbg_gpu_get_session_channel(struct dbg_session_gk20a *dbg_s)
71{
72 struct dbg_session_channel_data *ch_data;
73 struct channel_gk20a *ch;
74 struct gk20a *g = dbg_s->g;
75
76 nvgpu_mutex_acquire(&dbg_s->ch_list_lock);
77 if (nvgpu_list_empty(&dbg_s->ch_list)) {
78 nvgpu_mutex_release(&dbg_s->ch_list_lock);
79 return NULL;
80 }
81
82 ch_data = nvgpu_list_first_entry(&dbg_s->ch_list,
83 dbg_session_channel_data,
84 ch_entry);
85 ch = g->fifo.channel + ch_data->chid;
86
87 nvgpu_mutex_release(&dbg_s->ch_list_lock);
88
89 return ch;
90}
91
92void gk20a_dbg_gpu_post_events(struct channel_gk20a *ch)
93{
94 struct dbg_session_data *session_data;
95 struct dbg_session_gk20a *dbg_s;
96 struct gk20a *g = ch->g;
97
98 nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, " ");
99
100 /* guard against the session list being modified */
101 nvgpu_mutex_acquire(&ch->dbg_s_lock);
102
103 nvgpu_list_for_each_entry(session_data, &ch->dbg_s_list,
104 dbg_session_data, dbg_s_entry) {
105 dbg_s = session_data->dbg_s;
106 if (dbg_s->dbg_events.events_enabled) {
107 nvgpu_log(g, gpu_dbg_gpu_dbg, "posting event on session id %d",
108 dbg_s->id);
109 nvgpu_log(g, gpu_dbg_gpu_dbg, "%d events pending",
110 dbg_s->dbg_events.num_pending_events);
111
112 dbg_s->dbg_events.num_pending_events++;
113
114 nvgpu_dbg_session_post_event(dbg_s);
115 }
116 }
117
118 nvgpu_mutex_release(&ch->dbg_s_lock);
119}
120
121bool gk20a_dbg_gpu_broadcast_stop_trigger(struct channel_gk20a *ch)
122{
123 struct dbg_session_data *session_data;
124 struct dbg_session_gk20a *dbg_s;
125 bool broadcast = false;
126 struct gk20a *g = ch->g;
127
128 nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, " ");
129
130 /* guard against the session list being modified */
131 nvgpu_mutex_acquire(&ch->dbg_s_lock);
132
133 nvgpu_list_for_each_entry(session_data, &ch->dbg_s_list,
134 dbg_session_data, dbg_s_entry) {
135 dbg_s = session_data->dbg_s;
136 if (dbg_s->broadcast_stop_trigger) {
137 nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn | gpu_dbg_intr,
138 "stop trigger broadcast enabled");
139 broadcast = true;
140 break;
141 }
142 }
143
144 nvgpu_mutex_release(&ch->dbg_s_lock);
145
146 return broadcast;
147}
148
149int gk20a_dbg_gpu_clear_broadcast_stop_trigger(struct channel_gk20a *ch)
150{
151 struct dbg_session_data *session_data;
152 struct dbg_session_gk20a *dbg_s;
153 struct gk20a *g = ch->g;
154
155 nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, " ");
156
157 /* guard against the session list being modified */
158 nvgpu_mutex_acquire(&ch->dbg_s_lock);
159
160 nvgpu_list_for_each_entry(session_data, &ch->dbg_s_list,
161 dbg_session_data, dbg_s_entry) {
162 dbg_s = session_data->dbg_s;
163 if (dbg_s->broadcast_stop_trigger) {
164 nvgpu_log(g, gpu_dbg_gpu_dbg | gpu_dbg_fn | gpu_dbg_intr,
165 "stop trigger broadcast disabled");
166 dbg_s->broadcast_stop_trigger = false;
167 }
168 }
169
170 nvgpu_mutex_release(&ch->dbg_s_lock);
171
172 return 0;
173}
174
175u32 nvgpu_set_powergate_locked(struct dbg_session_gk20a *dbg_s,
176 bool mode)
177{
178 u32 err = 0U;
179 struct gk20a *g = dbg_s->g;
180
181 if (dbg_s->is_pg_disabled != mode) {
182 if (mode == false) {
183 g->dbg_powergating_disabled_refcount--;
184 }
185
186 /*
187 * Allow powergate disable or enable only if
188 * the global pg disabled refcount is zero
189 */
190 if (g->dbg_powergating_disabled_refcount == 0) {
191 err = g->ops.dbg_session_ops.dbg_set_powergate(dbg_s,
192 mode);
193 }
194
195 if (mode) {
196 g->dbg_powergating_disabled_refcount++;
197 }
198
199 dbg_s->is_pg_disabled = mode;
200 }
201
202 return err;
203}
204
205int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate)
206{
207 int err = 0;
208 struct gk20a *g = dbg_s->g;
209
210 /* This function must be called with g->dbg_sessions_lock held */
211
212 nvgpu_log(g, gpu_dbg_fn|gpu_dbg_gpu_dbg, "%s powergate mode = %s",
213 g->name, disable_powergate ? "disable" : "enable");