aboutsummaryrefslogtreecommitdiffstats
path: root/include/gk20a/gk20a.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2024-09-25 16:09:09 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2024-09-25 16:09:09 -0400
commitf347fde22f1297e4f022600d201780d5ead78114 (patch)
tree76be305d6187003a1e0486ff6e91efb1062ae118 /include/gk20a/gk20a.c
parent8340d234d78a7d0f46c11a584de538148b78b7cb (diff)
Delete no-longer-needed nvgpu headersHEADmasterjbakita-wip
The dependency on these was removed in commit 8340d234.
Diffstat (limited to 'include/gk20a/gk20a.c')
-rw-r--r--include/gk20a/gk20a.c595
1 files changed, 0 insertions, 595 deletions
diff --git a/include/gk20a/gk20a.c b/include/gk20a/gk20a.c
deleted file mode 100644
index 1a11716..0000000
--- a/include/gk20a/gk20a.c
+++ /dev/null
@@ -1,595 +0,0 @@
1/*
2 * GK20A Graphics
3 *
4 * Copyright (c) 2011-2021, 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/nvgpu_common.h>
26#include <nvgpu/kmem.h>
27#include <nvgpu/allocator.h>
28#include <nvgpu/timers.h>
29#include <nvgpu/soc.h>
30#include <nvgpu/enabled.h>
31#include <nvgpu/pmu.h>
32#include <nvgpu/gmmu.h>
33#include <nvgpu/ltc.h>
34#include <nvgpu/vidmem.h>
35#include <nvgpu/mm.h>
36#include <nvgpu/ctxsw_trace.h>
37#include <nvgpu/soc.h>
38#include <nvgpu/clk_arb.h>
39#include <nvgpu/therm.h>
40#include <nvgpu/mc.h>
41#include <nvgpu/channel_sync.h>
42#include <nvgpu/nvgpu_err.h>
43
44#include <trace/events/gk20a.h>
45
46#include "gk20a.h"
47
48#include "dbg_gpu_gk20a.h"
49#include "pstate/pstate.h"
50
51void __nvgpu_check_gpu_state(struct gk20a *g)
52{
53 u32 boot_0 = 0xffffffff;
54
55 boot_0 = nvgpu_mc_boot_0(g, NULL, NULL, NULL);
56 if (boot_0 == 0xffffffff) {
57 nvgpu_err(g, "GPU has disappeared from bus!!");
58 nvgpu_err(g, "Rebooting system!!");
59 nvgpu_kernel_restart(NULL);
60 }
61}
62
63void __gk20a_warn_on_no_regs(void)
64{
65 WARN_ONCE(1, "Attempted access to GPU regs after unmapping!");
66}
67
68static void gk20a_mask_interrupts(struct gk20a *g)
69{
70 if (g->ops.mc.intr_mask != NULL) {
71 g->ops.mc.intr_mask(g);
72 }
73
74 if (g->ops.mc.log_pending_intrs != NULL) {
75 g->ops.mc.log_pending_intrs(g);
76 }
77}
78
79int gk20a_prepare_poweroff(struct gk20a *g)
80{
81 int ret = 0;
82
83 nvgpu_log_fn(g, " ");
84
85 if (g->ops.fifo.channel_suspend) {
86 ret = g->ops.fifo.channel_suspend(g);
87 if (ret) {
88 return ret;
89 }
90 }
91
92 /* disable elpg before gr or fifo suspend */
93 if (g->ops.pmu.is_pmu_supported(g)) {
94 ret |= nvgpu_pmu_destroy(g);
95 }
96
97 if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) {
98 ret |= nvgpu_sec2_destroy(g);
99 }
100
101 ret |= gk20a_gr_suspend(g);
102 ret |= nvgpu_mm_suspend(g);
103 ret |= gk20a_fifo_suspend(g);
104
105 gk20a_ce_suspend(g);
106
107 /* Disable GPCPLL */
108 if (g->ops.clk.suspend_clk_support) {
109 ret |= g->ops.clk.suspend_clk_support(g);
110 }
111
112 if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) {
113 gk20a_deinit_pstate_support(g);
114 }
115
116 gk20a_mask_interrupts(g);
117
118 g->power_on = false;
119
120 return ret;
121}
122
123int gk20a_finalize_poweron(struct gk20a *g)
124{
125 int err = 0;
126#if defined(CONFIG_TEGRA_GK20A_NVHOST)
127 u32 nr_pages;
128#endif
129
130 u32 fuse_status;
131
132 nvgpu_log_fn(g, " ");
133
134 if (g->power_on) {
135 return 0;
136 }
137
138 g->power_on = true;
139
140 /*
141 * Before probing the GPU make sure the GPU's state is cleared. This is
142 * relevant for rebind operations.
143 */
144 if (g->ops.xve.reset_gpu && !g->gpu_reset_done) {
145 g->ops.xve.reset_gpu(g);
146 g->gpu_reset_done = true;
147 }
148
149 if (g->ops.clock_gating.slcg_acb_load_gating_prod != NULL) {
150 g->ops.clock_gating.slcg_acb_load_gating_prod(g, true);
151 }
152
153 /*
154 * Do this early so any early VMs that get made are capable of mapping
155 * buffers.
156 */
157 err = nvgpu_pd_cache_init(g);
158 if (err) {
159 return err;
160 }
161
162 /* init interface layer support for PMU falcon */
163 err = nvgpu_flcn_sw_init(g, FALCON_ID_PMU);
164 if (err != 0) {
165 nvgpu_err(g, "failed to sw init FALCON_ID_PMU");
166 goto done;
167 }
168 err = nvgpu_flcn_sw_init(g, FALCON_ID_SEC2);
169 if (err != 0) {
170 nvgpu_err(g, "failed to sw init FALCON_ID_SEC2");
171 goto done;
172 }
173 err = nvgpu_flcn_sw_init(g, FALCON_ID_NVDEC);
174 if (err != 0) {
175 nvgpu_err(g, "failed to sw init FALCON_ID_NVDEC");
176 goto done;
177 }
178 err = nvgpu_flcn_sw_init(g, FALCON_ID_GSPLITE);
179 if (err != 0) {
180 nvgpu_err(g, "failed to sw init FALCON_ID_GSPLITE");
181 goto done;
182 }
183
184 if (g->ops.acr.acr_sw_init != NULL &&
185 nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) {
186 g->ops.acr.acr_sw_init(g, &g->acr);
187 }
188
189 if (g->ops.bios.init) {
190 err = g->ops.bios.init(g);
191 }
192 if (err) {
193 goto done;
194 }
195
196 g->ops.bus.init_hw(g);
197
198 if (g->ops.clk.disable_slowboot) {
199 g->ops.clk.disable_slowboot(g);
200 }
201
202 g->ops.priv_ring.enable_priv_ring(g);
203
204 /* TBD: move this after graphics init in which blcg/slcg is enabled.
205 This function removes SlowdownOnBoot which applies 32x divider
206 on gpcpll bypass path. The purpose of slowdown is to save power
207 during boot but it also significantly slows down gk20a init on
208 simulation and emulation. We should remove SOB after graphics power
209 saving features (blcg/slcg) are enabled. For now, do it here. */
210 if (g->ops.clk.init_clk_support) {
211 err = g->ops.clk.init_clk_support(g);
212 if (err) {
213 nvgpu_err(g, "failed to init gk20a clk");
214 goto done;
215 }
216 }
217
218 if (nvgpu_is_enabled(g, NVGPU_SUPPORT_NVLINK)) {
219 err = g->ops.nvlink.init(g);
220 if (err) {
221 nvgpu_err(g, "failed to init nvlink");
222 goto done;
223 }
224 }
225
226 if (g->ops.fb.init_fbpa) {
227 err = g->ops.fb.init_fbpa(g);
228 if (err) {
229 nvgpu_err(g, "failed to init fbpa");
230 goto done;
231 }
232 }
233
234 if (g->ops.fb.mem_unlock) {
235 err = g->ops.fb.mem_unlock(g);
236 if (err) {
237 nvgpu_err(g, "failed to unlock memory");
238 goto done;
239 }
240 }
241
242 err = g->ops.fifo.reset_enable_hw(g);
243
244 if (err) {
245 nvgpu_err(g, "failed to reset gk20a fifo");
246 goto done;
247 }
248
249 err = nvgpu_init_ltc_support(g);
250 if (err) {
251 nvgpu_err(g, "failed to init ltc");
252 goto done;
253 }
254
255 err = nvgpu_init_mm_support(g);
256 if (err) {
257 nvgpu_err(g, "failed to init gk20a mm");
258 goto done;
259 }
260
261 err = gk20a_init_fifo_support(g);
262 if (err) {
263 nvgpu_err(g, "failed to init gk20a fifo");
264 goto done;
265 }
266
267 if (g->ops.therm.elcg_init_idle_filters) {
268 g->ops.therm.elcg_init_idle_filters(g);
269 }
270
271 g->ops.mc.intr_enable(g);
272
273 /*
274 * Power gate the chip as per the TPC PG mask
275 * and the fuse_status register.
276 * If TPC PG mask is invalid halt the GPU poweron.
277 */
278 g->can_tpc_powergate = false;
279 fuse_status = g->ops.fuse.fuse_status_opt_tpc_gpc(g, 0);
280
281 if (g->ops.tpc.tpc_powergate) {
282 err = g->ops.tpc.tpc_powergate(g, fuse_status);
283 }
284
285 if (err) {
286 nvgpu_err(g, "failed to power ON GPU");
287 goto done;
288 }
289
290 nvgpu_mutex_acquire(&g->tpc_pg_lock);
291
292 if (g->can_tpc_powergate) {
293 if (g->ops.gr.powergate_tpc != NULL)
294 g->ops.gr.powergate_tpc(g);
295 }
296
297 err = gk20a_enable_gr_hw(g);
298 if (err) {
299 nvgpu_err(g, "failed to enable gr");
300 nvgpu_mutex_release(&g->tpc_pg_lock);
301 goto done;
302 }
303
304 if (g->ops.pmu.is_pmu_supported(g)) {
305 if (g->ops.pmu.prepare_ucode) {
306 err = g->ops.pmu.prepare_ucode(g);
307 }
308 if (err) {
309 nvgpu_err(g, "failed to init pmu ucode");
310 nvgpu_mutex_release(&g->tpc_pg_lock);
311 goto done;
312 }
313 }
314
315 if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) {
316 err = gk20a_init_pstate_support(g);
317 if (err) {
318 nvgpu_err(g, "failed to init pstates");
319 nvgpu_mutex_release(&g->tpc_pg_lock);
320 goto done;
321 }
322 }
323
324 if (g->acr.bootstrap_hs_acr != NULL &&
325 nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) {
326 err = g->acr.bootstrap_hs_acr(g, &g->acr, &g->acr.acr);
327 if (err != 0) {
328 nvgpu_err(g, "ACR bootstrap failed");
329 nvgpu_mutex_release(&g->tpc_pg_lock);
330 goto done;
331 }
332 }
333
334 if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SEC2_RTOS)) {
335 err = nvgpu_init_sec2_support(g);
336 if (err != 0) {
337 nvgpu_err(g, "failed to init sec2");
338 nvgpu_mutex_release(&g->tpc_pg_lock);
339 goto done;
340 }
341 }
342
343 if (g->ops.pmu.is_pmu_supported(g)) {
344 err = nvgpu_init_pmu_support(g);
345 if (err) {
346 nvgpu_err(g, "failed to init gk20a pmu");
347 nvgpu_mutex_release(&g->tpc_pg_lock);
348 goto done;
349 }
350 }
351
352 err = gk20a_init_gr_support(g);
353 if (err) {
354 nvgpu_err(g, "failed to init gk20a gr");
355 nvgpu_mutex_release(&g->tpc_pg_lock);
356 goto done;
357 }
358
359 nvgpu_mutex_release(&g->tpc_pg_lock);
360
361 if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) {
362 err = gk20a_init_pstate_pmu_support(g);
363 if (err) {
364 nvgpu_err(g, "failed to init pstates");
365 goto done;
366 }
367 }
368
369 if (g->ops.pmu_ver.clk.clk_set_boot_clk && nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) {
370 g->ops.pmu_ver.clk.clk_set_boot_clk(g);
371 } else {
372 err = nvgpu_clk_arb_init_arbiter(g);
373 if (err) {
374 nvgpu_err(g, "failed to init clk arb");
375 goto done;
376 }
377 }
378
379 err = nvgpu_init_therm_support(g);
380 if (err) {
381 nvgpu_err(g, "failed to init gk20a therm");
382 goto done;
383 }
384
385 err = g->ops.chip_init_gpu_characteristics(g);
386 if (err) {
387 nvgpu_err(g, "failed to init gk20a gpu characteristics");
388 goto done;
389 }
390
391#ifdef CONFIG_GK20A_CTXSW_TRACE
392 err = gk20a_ctxsw_trace_init(g);
393 if (err)
394 nvgpu_warn(g, "could not initialize ctxsw tracing");
395#endif
396
397 /* Restore the debug setting */
398 g->ops.fb.set_debug_mode(g, g->mmu_debug_ctrl);
399
400 gk20a_init_ce_support(g);
401
402 if (g->ops.xve.available_speeds) {
403 u32 speed;
404
405 if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_ASPM) && g->ops.xve.disable_aspm) {
406 g->ops.xve.disable_aspm(g);
407 }
408
409 g->ops.xve.available_speeds(g, &speed);
410
411 /* Set to max speed */
412 speed = 1 << (fls(speed) - 1);
413 err = g->ops.xve.set_speed(g, speed);
414 if (err) {
415 nvgpu_err(g, "Failed to set PCIe bus speed!");
416 goto done;
417 }
418 }
419
420#if defined(CONFIG_TEGRA_GK20A_NVHOST)
421 if (nvgpu_has_syncpoints(g) && g->syncpt_unit_size) {
422 if (!nvgpu_mem_is_valid(&g->syncpt_mem)) {
423 nr_pages = DIV_ROUND_UP(g->syncpt_unit_size, PAGE_SIZE);
424 __nvgpu_mem_create_from_phys(g, &g->syncpt_mem,
425 g->syncpt_unit_base, nr_pages);
426 }
427 }
428#endif
429
430 if (g->ops.fifo.channel_resume) {
431 g->ops.fifo.channel_resume(g);
432 }
433
434done:
435 if (err) {
436 g->power_on = false;
437 }
438
439 return err;
440}
441
442int gk20a_wait_for_idle(struct gk20a *g)
443{
444 int wait_length = 150; /* 3 second overall max wait. */
445 int target_usage_count = 0;
446
447 if (!g) {
448 return -ENODEV;
449 }
450
451 while ((nvgpu_atomic_read(&g->usage_count) != target_usage_count)
452 && (wait_length-- >= 0)) {
453 nvgpu_msleep(20);
454 }
455
456 if (wait_length < 0) {
457 nvgpu_warn(g, "Timed out waiting for idle (%d)!\n",
458 nvgpu_atomic_read(&g->usage_count));
459 return -ETIMEDOUT;
460 }
461
462 return 0;
463}
464
465int gk20a_init_gpu_characteristics(struct gk20a *g)
466{
467 __nvgpu_set_enabled(g, NVGPU_SUPPORT_PARTIAL_MAPPINGS, true);
468 __nvgpu_set_enabled(g, NVGPU_SUPPORT_MAP_DIRECT_KIND_CTRL, true);
469 __nvgpu_set_enabled(g, NVGPU_SUPPORT_MAP_BUFFER_BATCH, true);
470
471 if (IS_ENABLED(CONFIG_SYNC)) {
472 __nvgpu_set_enabled(g, NVGPU_SUPPORT_SYNC_FENCE_FDS, true);
473 }
474
475 if (g->ops.mm.support_sparse && g->ops.mm.support_sparse(g)) {
476 __nvgpu_set_enabled(g, NVGPU_SUPPORT_SPARSE_ALLOCS, true);
477 }
478
479 /*
480 * Fast submits are supported as long as the user doesn't request
481 * anything that depends on job tracking. (Here, fast means strictly no
482 * metadata, just the gpfifo contents are copied and gp_put updated).
483 */
484 __nvgpu_set_enabled(g,
485 NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_NO_JOBTRACKING,
486 true);
487
488 /*
489 * Sync framework requires deferred job cleanup, wrapping syncs in FDs,
490 * and other heavy stuff, which prevents deterministic submits. This is
491 * supported otherwise, provided that the user doesn't request anything
492 * that depends on deferred cleanup.
493 */
494 if (!nvgpu_channel_sync_needs_os_fence_framework(g)) {
495 __nvgpu_set_enabled(g,
496 NVGPU_SUPPORT_DETERMINISTIC_SUBMIT_FULL,
497 true);
498 }
499
500 __nvgpu_set_enabled(g, NVGPU_SUPPORT_DETERMINISTIC_OPTS, true);
501
502 __nvgpu_set_enabled(g, NVGPU_SUPPORT_USERSPACE_MANAGED_AS, true);
503 __nvgpu_set_enabled(g, NVGPU_SUPPORT_TSG, true);
504
505 if (g->ops.clk_arb.get_arbiter_clk_domains != NULL &&
506 g->ops.clk.support_clk_freq_controller) {
507 __nvgpu_set_enabled(g, NVGPU_SUPPORT_CLOCK_CONTROLS, true);
508 }
509
510 g->ops.gr.detect_sm_arch(g);
511
512 if (g->ops.gr.init_cyclestats) {
513 g->ops.gr.init_cyclestats(g);
514 }
515
516 g->ops.gr.get_rop_l2_en_mask(g);
517
518 return 0;
519}
520
521/*
522 * Free the gk20a struct.
523 */
524static void gk20a_free_cb(struct nvgpu_ref *refcount)
525{
526 struct gk20a *g = container_of(refcount,
527 struct gk20a, refcount);
528
529#ifdef CONFIG_NVGPU_SUPPORT_LINUX_ECC_ERROR_REPORTING
530 nvgpu_deinit_ecc_reporting(g);
531#endif
532
533 nvgpu_log(g, gpu_dbg_shutdown, "Freeing GK20A struct!");
534
535 gk20a_ce_destroy(g);
536
537 if (g->remove_support) {
538 g->remove_support(g);
539 }
540
541 if (g->free) {
542 g->free(g);
543 }
544}
545
546/**
547 * gk20a_get() - Increment ref count on driver
548 *
549 * @g The driver to increment
550 * This will fail if the driver is in the process of being released. In that
551 * case it will return NULL. Otherwise a pointer to the driver passed in will
552 * be returned.
553 */
554struct gk20a * __must_check gk20a_get(struct gk20a *g)
555{
556 int success;
557
558 /*
559 * Handle the possibility we are still freeing the gk20a struct while
560 * gk20a_get() is called. Unlikely but plausible race condition. Ideally
561 * the code will never be in such a situation that this race is
562 * possible.
563 */
564 success = nvgpu_ref_get_unless_zero(&g->refcount);
565
566 nvgpu_log(g, gpu_dbg_shutdown, "GET: refs currently %d %s",
567 nvgpu_atomic_read(&g->refcount.refcount),
568 success ? "" : "(FAILED)");
569
570 return success ? g : NULL;
571}
572
573/**
574 * gk20a_put() - Decrement ref count on driver
575 *
576 * @g - The driver to decrement
577 *
578 * Decrement the driver ref-count. If neccesary also free the underlying driver
579 * memory
580 */
581void gk20a_put(struct gk20a *g)
582{
583 /*
584 * Note - this is racy, two instances of this could run before the
585 * actual kref_put(0 runs, you could see something like:
586 *
587 * ... PUT: refs currently 2
588 * ... PUT: refs currently 2
589 * ... Freeing GK20A struct!
590 */
591 nvgpu_log(g, gpu_dbg_shutdown, "PUT: refs currently %d",
592 nvgpu_atomic_read(&g->refcount.refcount));
593
594 nvgpu_ref_put(&g->refcount, gk20a_free_cb);
595}