.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note |
---|
2 | 2 | /* |
---|
3 | 3 | * |
---|
4 | | - * (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved. |
---|
| 4 | + * (C) COPYRIGHT 2010-2023 ARM Limited. All rights reserved. |
---|
5 | 5 | * |
---|
6 | 6 | * This program is free software and is provided to you under the terms of the |
---|
7 | 7 | * GNU General Public License version 2 as published by the Free Software |
---|
.. | .. |
---|
35 | 35 | #include <mali_kbase.h> |
---|
36 | 36 | #include <mali_kbase_defs.h> |
---|
37 | 37 | #include <mali_kbase_hwaccess_instr.h> |
---|
| 38 | +#include <mali_kbase_hwaccess_time.h> |
---|
38 | 39 | #include <mali_kbase_hw.h> |
---|
39 | 40 | #include <mali_kbase_config_defaults.h> |
---|
40 | 41 | #include <linux/priority_control_manager.h> |
---|
41 | 42 | |
---|
42 | 43 | #include <tl/mali_kbase_timeline.h> |
---|
| 44 | +#include "mali_kbase_kinstr_prfcnt.h" |
---|
43 | 45 | #include "mali_kbase_vinstr.h" |
---|
44 | | -#include "mali_kbase_hwcnt_context.h" |
---|
45 | | -#include "mali_kbase_hwcnt_virtualizer.h" |
---|
| 46 | +#include "hwcnt/mali_kbase_hwcnt_context.h" |
---|
| 47 | +#include "hwcnt/mali_kbase_hwcnt_virtualizer.h" |
---|
46 | 48 | |
---|
47 | 49 | #include "mali_kbase_device.h" |
---|
48 | 50 | #include "mali_kbase_device_internal.h" |
---|
49 | 51 | #include "backend/gpu/mali_kbase_pm_internal.h" |
---|
50 | 52 | #include "backend/gpu/mali_kbase_irq_internal.h" |
---|
51 | 53 | #include "mali_kbase_regs_history_debugfs.h" |
---|
| 54 | +#include "mali_kbase_pbha.h" |
---|
52 | 55 | |
---|
53 | 56 | #ifdef CONFIG_MALI_ARBITER_SUPPORT |
---|
54 | 57 | #include "arbiter/mali_kbase_arbiter_pm.h" |
---|
55 | 58 | #endif /* CONFIG_MALI_ARBITER_SUPPORT */ |
---|
56 | 59 | |
---|
57 | | -/* NOTE: Magic - 0x45435254 (TRCE in ASCII). |
---|
58 | | - * Supports tracing feature provided in the base module. |
---|
59 | | - * Please keep it in sync with the value of base module. |
---|
60 | | - */ |
---|
61 | | -#define TRACE_BUFFER_HEADER_SPECIAL 0x45435254 |
---|
| 60 | +#if defined(CONFIG_DEBUG_FS) && !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI) |
---|
62 | 61 | |
---|
63 | 62 | /* Number of register accesses for the buffer that we allocate during |
---|
64 | 63 | * initialization time. The buffer size can be changed later via debugfs. |
---|
65 | 64 | */ |
---|
66 | 65 | #define KBASEP_DEFAULT_REGISTER_HISTORY_SIZE ((u16)512) |
---|
| 66 | + |
---|
| 67 | +#endif /* defined(CONFIG_DEBUG_FS) && !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI) */ |
---|
67 | 68 | |
---|
68 | 69 | static DEFINE_MUTEX(kbase_dev_list_lock); |
---|
69 | 70 | static LIST_HEAD(kbase_dev_list); |
---|
.. | .. |
---|
161 | 162 | /** |
---|
162 | 163 | * mali_oom_notifier_handler - Mali driver out-of-memory handler |
---|
163 | 164 | * |
---|
164 | | - * @nb - notifier block - used to retrieve kbdev pointer |
---|
165 | | - * @action - action (unused) |
---|
166 | | - * @data - data pointer (unused) |
---|
| 165 | + * @nb: notifier block - used to retrieve kbdev pointer |
---|
| 166 | + * @action: action (unused) |
---|
| 167 | + * @data: data pointer (unused) |
---|
| 168 | + * |
---|
167 | 169 | * This function simply lists memory usage by the Mali driver, per GPU device, |
---|
168 | 170 | * for diagnostic purposes. |
---|
| 171 | + * |
---|
| 172 | + * Return: NOTIFY_OK on success, NOTIFY_BAD otherwise. |
---|
169 | 173 | */ |
---|
170 | 174 | static int mali_oom_notifier_handler(struct notifier_block *nb, |
---|
171 | 175 | unsigned long action, void *data) |
---|
.. | .. |
---|
187 | 191 | |
---|
188 | 192 | mutex_lock(&kbdev->kctx_list_lock); |
---|
189 | 193 | |
---|
190 | | - list_for_each_entry (kctx, &kbdev->kctx_list, kctx_list_link) { |
---|
| 194 | + list_for_each_entry(kctx, &kbdev->kctx_list, kctx_list_link) { |
---|
191 | 195 | struct pid *pid_struct; |
---|
192 | 196 | struct task_struct *task; |
---|
193 | 197 | unsigned long task_alloc_total = |
---|
.. | .. |
---|
273 | 277 | if (err) |
---|
274 | 278 | goto dma_set_mask_failed; |
---|
275 | 279 | |
---|
| 280 | + |
---|
| 281 | + /* There is no limit for Mali, so set to max. */ |
---|
| 282 | + if (kbdev->dev->dma_parms) |
---|
| 283 | + err = dma_set_max_seg_size(kbdev->dev, UINT_MAX); |
---|
| 284 | + if (err) |
---|
| 285 | + goto dma_set_mask_failed; |
---|
| 286 | + |
---|
276 | 287 | kbdev->nr_hw_address_spaces = kbdev->gpu_props.num_address_spaces; |
---|
277 | 288 | |
---|
278 | 289 | err = kbase_device_all_as_init(kbdev); |
---|
279 | 290 | if (err) |
---|
280 | 291 | goto dma_set_mask_failed; |
---|
281 | 292 | |
---|
282 | | - err = kbase_ktrace_init(kbdev); |
---|
| 293 | + err = kbase_pbha_read_dtb(kbdev); |
---|
283 | 294 | if (err) |
---|
284 | 295 | goto term_as; |
---|
285 | 296 | |
---|
.. | .. |
---|
291 | 302 | |
---|
292 | 303 | kbdev->pm.dvfs_period = DEFAULT_PM_DVFS_PERIOD; |
---|
293 | 304 | |
---|
294 | | - kbdev->reset_timeout_ms = DEFAULT_RESET_TIMEOUT_MS; |
---|
| 305 | +#if MALI_USE_CSF |
---|
| 306 | + kbdev->reset_timeout_ms = kbase_get_timeout_ms(kbdev, CSF_CSG_SUSPEND_TIMEOUT); |
---|
| 307 | +#else |
---|
| 308 | + kbdev->reset_timeout_ms = JM_DEFAULT_RESET_TIMEOUT_MS; |
---|
| 309 | +#endif /* MALI_USE_CSF */ |
---|
295 | 310 | |
---|
296 | 311 | kbdev->mmu_mode = kbase_mmu_mode_get_aarch64(); |
---|
297 | | - |
---|
| 312 | + kbdev->mmu_as_inactive_wait_time_ms = |
---|
| 313 | + kbase_get_timeout_ms(kbdev, MMU_AS_INACTIVE_WAIT_TIMEOUT); |
---|
298 | 314 | mutex_init(&kbdev->kctx_list_lock); |
---|
299 | 315 | INIT_LIST_HEAD(&kbdev->kctx_list); |
---|
300 | 316 | |
---|
.. | .. |
---|
307 | 323 | "Unable to register OOM notifier for Mali - but will continue\n"); |
---|
308 | 324 | kbdev->oom_notifier_block.notifier_call = NULL; |
---|
309 | 325 | } |
---|
| 326 | + |
---|
| 327 | +#if !MALI_USE_CSF |
---|
| 328 | + spin_lock_init(&kbdev->quick_reset_lock); |
---|
| 329 | + kbdev->quick_reset_enabled = true; |
---|
| 330 | + kbdev->num_of_atoms_hw_completed = 0; |
---|
| 331 | +#endif |
---|
| 332 | + |
---|
| 333 | +#if MALI_USE_CSF && IS_ENABLED(CONFIG_SYNC_FILE) |
---|
| 334 | + atomic_set(&kbdev->live_fence_metadata, 0); |
---|
| 335 | +#endif |
---|
310 | 336 | return 0; |
---|
311 | 337 | |
---|
312 | 338 | term_as: |
---|
.. | .. |
---|
325 | 351 | #if KBASE_KTRACE_ENABLE |
---|
326 | 352 | kbase_debug_assert_register_hook(NULL, NULL); |
---|
327 | 353 | #endif |
---|
328 | | - |
---|
329 | | - kbase_ktrace_term(kbdev); |
---|
330 | | - |
---|
331 | 354 | kbase_device_all_as_term(kbdev); |
---|
| 355 | + |
---|
332 | 356 | |
---|
333 | 357 | if (kbdev->oom_notifier_block.notifier_call) |
---|
334 | 358 | unregister_oom_notifier(&kbdev->oom_notifier_block); |
---|
| 359 | + |
---|
| 360 | +#if MALI_USE_CSF && IS_ENABLED(CONFIG_SYNC_FILE) |
---|
| 361 | + if (atomic_read(&kbdev->live_fence_metadata) > 0) |
---|
| 362 | + dev_warn(kbdev->dev, "Terminating Kbase device with live fence metadata!"); |
---|
| 363 | +#endif |
---|
335 | 364 | } |
---|
| 365 | + |
---|
| 366 | +#if !MALI_USE_CSF |
---|
| 367 | +void kbase_enable_quick_reset(struct kbase_device *kbdev) |
---|
| 368 | +{ |
---|
| 369 | + spin_lock(&kbdev->quick_reset_lock); |
---|
| 370 | + |
---|
| 371 | + kbdev->quick_reset_enabled = true; |
---|
| 372 | + kbdev->num_of_atoms_hw_completed = 0; |
---|
| 373 | + |
---|
| 374 | + spin_unlock(&kbdev->quick_reset_lock); |
---|
| 375 | +} |
---|
| 376 | + |
---|
| 377 | +void kbase_disable_quick_reset(struct kbase_device *kbdev) |
---|
| 378 | +{ |
---|
| 379 | + spin_lock(&kbdev->quick_reset_lock); |
---|
| 380 | + |
---|
| 381 | + kbdev->quick_reset_enabled = false; |
---|
| 382 | + kbdev->num_of_atoms_hw_completed = 0; |
---|
| 383 | + |
---|
| 384 | + spin_unlock(&kbdev->quick_reset_lock); |
---|
| 385 | +} |
---|
| 386 | + |
---|
| 387 | +bool kbase_is_quick_reset_enabled(struct kbase_device *kbdev) |
---|
| 388 | +{ |
---|
| 389 | + return kbdev->quick_reset_enabled; |
---|
| 390 | +} |
---|
| 391 | +#endif |
---|
336 | 392 | |
---|
337 | 393 | void kbase_device_free(struct kbase_device *kbdev) |
---|
338 | 394 | { |
---|
.. | .. |
---|
395 | 451 | kbase_vinstr_term(kbdev->vinstr_ctx); |
---|
396 | 452 | } |
---|
397 | 453 | |
---|
398 | | -#if defined(CONFIG_DEBUG_FS) && !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI) |
---|
| 454 | +int kbase_device_kinstr_prfcnt_init(struct kbase_device *kbdev) |
---|
| 455 | +{ |
---|
| 456 | + return kbase_kinstr_prfcnt_init(kbdev->hwcnt_gpu_virt, |
---|
| 457 | + &kbdev->kinstr_prfcnt_ctx); |
---|
| 458 | +} |
---|
| 459 | + |
---|
| 460 | +void kbase_device_kinstr_prfcnt_term(struct kbase_device *kbdev) |
---|
| 461 | +{ |
---|
| 462 | + kbase_kinstr_prfcnt_term(kbdev->kinstr_prfcnt_ctx); |
---|
| 463 | +} |
---|
| 464 | + |
---|
399 | 465 | int kbase_device_io_history_init(struct kbase_device *kbdev) |
---|
400 | 466 | { |
---|
401 | 467 | return kbase_io_history_init(&kbdev->io_history, |
---|
.. | .. |
---|
406 | 472 | { |
---|
407 | 473 | kbase_io_history_term(&kbdev->io_history); |
---|
408 | 474 | } |
---|
409 | | -#endif |
---|
410 | 475 | |
---|
411 | 476 | int kbase_device_misc_register(struct kbase_device *kbdev) |
---|
412 | 477 | { |
---|
.. | .. |
---|
455 | 520 | { |
---|
456 | 521 | int err; |
---|
457 | 522 | |
---|
458 | | - err = kbasep_platform_device_init(kbdev); |
---|
| 523 | + err = kbase_ktrace_init(kbdev); |
---|
459 | 524 | if (err) |
---|
460 | 525 | return err; |
---|
| 526 | + |
---|
| 527 | + |
---|
| 528 | + err = kbasep_platform_device_init(kbdev); |
---|
| 529 | + if (err) |
---|
| 530 | + goto ktrace_term; |
---|
461 | 531 | |
---|
462 | 532 | err = kbase_pm_runtime_init(kbdev); |
---|
463 | 533 | if (err) |
---|
464 | 534 | goto fail_runtime_pm; |
---|
465 | 535 | |
---|
| 536 | + /* This spinlock is initialized before doing the first access to GPU |
---|
| 537 | + * registers and installing interrupt handlers. |
---|
| 538 | + */ |
---|
| 539 | + spin_lock_init(&kbdev->hwaccess_lock); |
---|
| 540 | + |
---|
466 | 541 | /* Ensure we can access the GPU registers */ |
---|
467 | 542 | kbase_pm_register_access_enable(kbdev); |
---|
468 | 543 | |
---|
469 | | - /* Find out GPU properties based on the GPU feature registers */ |
---|
| 544 | + /* |
---|
| 545 | + * Find out GPU properties based on the GPU feature registers. |
---|
| 546 | + * Note that this does not populate the few properties that depend on |
---|
| 547 | + * hw_features being initialized. Those are set by kbase_gpuprops_set_features |
---|
| 548 | + * soon after this in the init process. |
---|
| 549 | + */ |
---|
470 | 550 | kbase_gpuprops_set(kbdev); |
---|
471 | 551 | |
---|
472 | 552 | /* We're done accessing the GPU registers for now. */ |
---|
473 | 553 | kbase_pm_register_access_disable(kbdev); |
---|
474 | 554 | |
---|
475 | | - /* This spinlock has to be initialized before installing interrupt |
---|
476 | | - * handlers that require to hold it to process interrupts. |
---|
477 | | - */ |
---|
478 | | - spin_lock_init(&kbdev->hwaccess_lock); |
---|
479 | 555 | #ifdef CONFIG_MALI_ARBITER_SUPPORT |
---|
480 | 556 | if (kbdev->arb.arb_if) |
---|
481 | 557 | err = kbase_arbiter_pm_install_interrupts(kbdev); |
---|
.. | .. |
---|
493 | 569 | kbase_pm_runtime_term(kbdev); |
---|
494 | 570 | fail_runtime_pm: |
---|
495 | 571 | kbasep_platform_device_term(kbdev); |
---|
| 572 | +ktrace_term: |
---|
| 573 | + kbase_ktrace_term(kbdev); |
---|
496 | 574 | |
---|
497 | 575 | return err; |
---|
498 | 576 | } |
---|
.. | .. |
---|
509 | 587 | #endif /* CONFIG_MALI_ARBITER_SUPPORT */ |
---|
510 | 588 | kbase_pm_runtime_term(kbdev); |
---|
511 | 589 | kbasep_platform_device_term(kbdev); |
---|
| 590 | + kbase_ktrace_term(kbdev); |
---|
512 | 591 | } |
---|
513 | 592 | |
---|
514 | 593 | int kbase_device_late_init(struct kbase_device *kbdev) |
---|