aboutsummaryrefslogtreecommitdiffstats
path: root/include/gk20a/css_gr_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/css_gr_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/css_gr_gk20a.c')
-rw-r--r--include/gk20a/css_gr_gk20a.c636
1 files changed, 636 insertions, 0 deletions
diff --git a/include/gk20a/css_gr_gk20a.c b/include/gk20a/css_gr_gk20a.c
new file mode 100644
index 0000000..28a3d49
--- /dev/null
+++ b/include/gk20a/css_gr_gk20a.c
@@ -0,0 +1,636 @@
1/*
2 * GK20A Cycle stats snapshots support (subsystem for gr_gk20a).
3 *
4 * Copyright (c) 2015-2018, 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/bitops.h>
26#include <nvgpu/kmem.h>
27#include <nvgpu/lock.h>
28#include <nvgpu/dma.h>
29#include <nvgpu/mm.h>
30#include <nvgpu/sizes.h>
31#include <nvgpu/barrier.h>
32#include <nvgpu/log.h>
33#include <nvgpu/bug.h>
34#include <nvgpu/io.h>
35#include <nvgpu/utils.h>
36#include <nvgpu/channel.h>
37#include <nvgpu/unit.h>
38
39#include "gk20a.h"
40#include "css_gr_gk20a.h"
41
42#include <nvgpu/hw/gk20a/hw_perf_gk20a.h>
43
44/* check client for pointed perfmon ownership */
45#define CONTAINS_PERFMON(cl, pm) \
46 ((cl)->perfmon_start <= (pm) && \
47 ((pm) - (cl)->perfmon_start) < (cl)->perfmon_count)
48
49/* address of fifo entry by offset */
50#define CSS_FIFO_ENTRY(fifo, offs) \
51 ((struct gk20a_cs_snapshot_fifo_entry *)(((char *)(fifo)) + (offs)))
52
53/* calculate area capacity in number of fifo entries */
54#define CSS_FIFO_ENTRY_CAPACITY(s) \
55 (((s) - sizeof(struct gk20a_cs_snapshot_fifo)) \
56 / sizeof(struct gk20a_cs_snapshot_fifo_entry))
57
58/* reserved to indicate failures with data */
59#define CSS_FIRST_PERFMON_ID 32
60/* should correlate with size of gk20a_cs_snapshot_fifo_entry::perfmon_id */
61#define CSS_MAX_PERFMON_IDS 256
62
63/* reports whether the hw queue overflowed */
64bool css_hw_get_overflow_status(struct gk20a *g)
65{
66 const u32 st = perf_pmasys_control_membuf_status_overflowed_f();
67 return st == (gk20a_readl(g, perf_pmasys_control_r()) & st);
68}
69
70/* returns how many pending snapshot entries are pending */
71u32 css_hw_get_pending_snapshots(struct gk20a *g)
72{
73 return gk20a_readl(g, perf_pmasys_mem_bytes_r()) /
74 sizeof(struct gk20a_cs_snapshot_fifo_entry);
75}
76
77/* informs hw how many snapshots have been processed (frees up fifo space) */
78void css_hw_set_handled_snapshots(struct gk20a *g, u32 done)
79{
80 if (done > 0) {
81 gk20a_writel(g, perf_pmasys_mem_bump_r(),
82 done * sizeof(struct gk20a_cs_snapshot_fifo_entry));
83 }
84}
85
86/* disable streaming to memory */
87static void css_hw_reset_streaming(struct gk20a *g)
88{
89 u32 engine_status;
90
91 /* reset the perfmon */
92 g->ops.mc.reset(g, g->ops.mc.reset_mask(g, NVGPU_UNIT_PERFMON));
93
94 /* RBUFEMPTY must be set -- otherwise we'll pick up */
95 /* snapshot that have been queued up from earlier */
96 engine_status = gk20a_readl(g, perf_pmasys_enginestatus_r());
97 WARN_ON(0 == (engine_status
98 & perf_pmasys_enginestatus_rbufempty_empty_f()));
99
100 /* turn off writes */
101 gk20a_writel(g, perf_pmasys_control_r(),
102 perf_pmasys_control_membuf_clear_status_doit_f());
103
104 /* pointing all pending snapshots as handled */
105 css_hw_set_handled_snapshots(g, css_hw_get_pending_snapshots(g));
106}
107
108/*
109 * WARNING: all css_gr_XXX functions are local and expected to be called
110 * from locked context (protected by cs_lock)
111 */
112
113static int css_gr_create_shared_data(struct gr_gk20a *gr)
114{
115 struct gk20a_cs_snapshot *data;
116
117 if (gr->cs_data)
118 return 0;
119
120 data = nvgpu_kzalloc(gr->g, sizeof(*data));
121 if (!data)
122 return -ENOMEM;
123
124 nvgpu_init_list_node(&data->clients);
125 gr->cs_data = data;
126
127 return 0;
128}
129
130int css_hw_enable_snapshot(struct channel_gk20a *ch,
131 struct gk20a_cs_snapshot_client *cs_client)
132{
133 struct gk20a *g = ch->g;
134 struct mm_gk20a *mm = &g->mm;
135 struct gr_gk20a *gr = &g->gr;
136 struct gk20a_cs_snapshot *data = gr->cs_data;
137 u32 snapshot_size = cs_client->snapshot_size;
138 int ret;
139
140 u32 virt_addr_lo;
141 u32 virt_addr_hi;
142 u32 inst_pa_page;
143
144 if (data->hw_snapshot)
145 return 0;
146
147 if (snapshot_size < CSS_MIN_HW_SNAPSHOT_SIZE)
148 snapshot_size = CSS_MIN_HW_SNAPSHOT_SIZE;
149
150 ret = nvgpu_dma_alloc_map_sys(g->mm.pmu.vm, snapshot_size,
151 &data->hw_memdesc);
152 if (ret)
153 return ret;
154
155 /* perf output buffer may not cross a 4GB boundary - with a separate */
156 /* va smaller than that, it won't but check anyway */
157 if (!data->hw_memdesc.cpu_va ||
158 data->hw_memdesc.size < snapshot_size ||
159 data->hw_memdesc.gpu_va + u64_lo32(snapshot_size) > SZ_4G) {
160 ret = -EFAULT;
161 goto failed_allocation;
162 }
163
164 data->hw_snapshot =
165 (struct gk20a_cs_snapshot_fifo_entry *)data->hw_memdesc.cpu_va;
166 data->hw_end = data->hw_snapshot +
167 snapshot_size / sizeof(struct gk20a_cs_snapshot_fifo_entry);
168 data->hw_get = data->hw_snapshot;
169 memset(data->hw_snapshot, 0xff, snapshot_size);
170
171 /* address and size are aligned to 32 bytes, the lowest bits read back
172 * as zeros */
173 virt_addr_lo = u64_lo32(data->hw_memdesc.gpu_va);
174 virt_addr_hi = u64_hi32(data->hw_memdesc.gpu_va);
175
176 css_hw_reset_streaming(g);
177
178 gk20a_writel(g, perf_pmasys_outbase_r(), virt_addr_lo);
179 gk20a_writel(g, perf_pmasys_outbaseupper_r(),
180 perf_pmasys_outbaseupper_ptr_f(virt_addr_hi));
181 gk20a_writel(g, perf_pmasys_outsize_r(), snapshot_size);
182
183 /* this field is aligned to 4K */
184 inst_pa_page = nvgpu_inst_block_addr(g, &g->mm.hwpm.inst_block) >> 12;
185
186 /* A write to MEM_BLOCK triggers the block bind operation. MEM_BLOCK
187 * should be written last */
188 gk20a_writel(g, perf_pmasys_mem_block_r(),
189 perf_pmasys_mem_block_base_f(inst_pa_page) |
190 nvgpu_aperture_mask(g, &mm->hwpm.inst_block,
191 perf_pmasys_mem_block_target_sys_ncoh_f(),
192 perf_pmasys_mem_block_target_sys_coh_f(),
193 perf_pmasys_mem_block_target_lfb_f()) |
194 perf_pmasys_mem_block_valid_true_f());
195
196 nvgpu_log_info(g, "cyclestats: buffer for hardware snapshots enabled\n");
197
198 return 0;
199
200failed_allocation:
201 if (data->hw_memdesc.size) {
202 nvgpu_dma_unmap_free(g->mm.pmu.vm, &data->hw_memdesc);
203 memset(&data->hw_memdesc, 0, sizeof(data->hw_memdesc));
204 }
205 data->hw_snapshot = NULL;
206
207 return ret;
208}
209
210void css_hw_disable_snapshot(struct gr_gk20a *gr)
211{
212 struct gk20a *g = gr->g;