| .. | .. |
|---|
| 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-2022 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 |
|---|
| .. | .. |
|---|
| 70 | 70 | #include "mali_kbase_jd_debugfs.h" |
|---|
| 71 | 71 | #include "mali_kbase_jm.h" |
|---|
| 72 | 72 | #include "mali_kbase_js.h" |
|---|
| 73 | | -#endif /* !MALI_USE_CSF */ |
|---|
| 73 | +#else /* !MALI_USE_CSF */ |
|---|
| 74 | +#include "csf/mali_kbase_debug_csf_fault.h" |
|---|
| 75 | +#endif /* MALI_USE_CSF */ |
|---|
| 74 | 76 | |
|---|
| 75 | 77 | #include "ipa/mali_kbase_ipa.h" |
|---|
| 76 | 78 | |
|---|
| .. | .. |
|---|
| 82 | 84 | |
|---|
| 83 | 85 | #if MALI_USE_CSF |
|---|
| 84 | 86 | #include "csf/mali_kbase_csf.h" |
|---|
| 85 | | -#endif |
|---|
| 86 | 87 | |
|---|
| 87 | | -#ifndef u64_to_user_ptr |
|---|
| 88 | | -/* Introduced in Linux v4.6 */ |
|---|
| 89 | | -#define u64_to_user_ptr(x) ((void __user *)(uintptr_t)x) |
|---|
| 90 | | -#endif |
|---|
| 91 | | - |
|---|
| 92 | | -#if MALI_USE_CSF |
|---|
| 93 | 88 | /* Physical memory group ID for CSF user I/O. |
|---|
| 94 | 89 | */ |
|---|
| 95 | 90 | #define KBASE_MEM_GROUP_CSF_IO BASE_MEM_GROUP_DEFAULT |
|---|
| .. | .. |
|---|
| 109 | 104 | |
|---|
| 110 | 105 | struct kbase_device *kbase_device_alloc(void); |
|---|
| 111 | 106 | /* |
|---|
| 112 | | -* note: configuration attributes member of kbdev needs to have |
|---|
| 113 | | -* been setup before calling kbase_device_init |
|---|
| 114 | | -*/ |
|---|
| 107 | + * note: configuration attributes member of kbdev needs to have |
|---|
| 108 | + * been setup before calling kbase_device_init |
|---|
| 109 | + */ |
|---|
| 115 | 110 | |
|---|
| 116 | 111 | int kbase_device_misc_init(struct kbase_device *kbdev); |
|---|
| 117 | 112 | void kbase_device_misc_term(struct kbase_device *kbdev); |
|---|
| 113 | + |
|---|
| 114 | +#if !MALI_USE_CSF |
|---|
| 115 | +void kbase_enable_quick_reset(struct kbase_device *kbdev); |
|---|
| 116 | +void kbase_disable_quick_reset(struct kbase_device *kbdev); |
|---|
| 117 | +bool kbase_is_quick_reset_enabled(struct kbase_device *kbdev); |
|---|
| 118 | +#endif |
|---|
| 119 | + |
|---|
| 118 | 120 | void kbase_device_free(struct kbase_device *kbdev); |
|---|
| 119 | 121 | int kbase_device_has_feature(struct kbase_device *kbdev, u32 feature); |
|---|
| 120 | 122 | |
|---|
| .. | .. |
|---|
| 256 | 258 | kbasep_js_atom_done_code done_code); |
|---|
| 257 | 259 | void kbase_jd_cancel(struct kbase_device *kbdev, struct kbase_jd_atom *katom); |
|---|
| 258 | 260 | void kbase_jd_zap_context(struct kbase_context *kctx); |
|---|
| 259 | | -bool jd_done_nolock(struct kbase_jd_atom *katom, |
|---|
| 260 | | - struct list_head *completed_jobs_ctx); |
|---|
| 261 | + |
|---|
| 262 | +/* |
|---|
| 263 | + * kbase_jd_done_nolock - Perform the necessary handling of an atom that has completed |
|---|
| 264 | + * the execution. |
|---|
| 265 | + * |
|---|
| 266 | + * @katom: Pointer to the atom that completed the execution |
|---|
| 267 | + * @post_immediately: Flag indicating that completion event can be posted |
|---|
| 268 | + * immediately for @katom and the other atoms depdendent |
|---|
| 269 | + * on @katom which also completed execution. The flag is |
|---|
| 270 | + * false only for the case where the function is called by |
|---|
| 271 | + * kbase_jd_done_worker() on the completion of atom running |
|---|
| 272 | + * on the GPU. |
|---|
| 273 | + * |
|---|
| 274 | + * Note that if this is a soft-job that has had kbase_prepare_soft_job called on it then the caller |
|---|
| 275 | + * is responsible for calling kbase_finish_soft_job *before* calling this function. |
|---|
| 276 | + * |
|---|
| 277 | + * The caller must hold the kbase_jd_context.lock. |
|---|
| 278 | + */ |
|---|
| 279 | +bool kbase_jd_done_nolock(struct kbase_jd_atom *katom, bool post_immediately); |
|---|
| 280 | + |
|---|
| 261 | 281 | void kbase_jd_free_external_resources(struct kbase_jd_atom *katom); |
|---|
| 262 | 282 | void kbase_jd_dep_clear_locked(struct kbase_jd_atom *katom); |
|---|
| 263 | 283 | |
|---|
| .. | .. |
|---|
| 299 | 319 | * virtual address space in a growable memory region and the atom currently |
|---|
| 300 | 320 | * executing on a job slot is the tiler job chain at the start of a renderpass. |
|---|
| 301 | 321 | * |
|---|
| 302 | | - * Return 0 if successful, otherwise a negative error code. |
|---|
| 322 | + * Return: 0 if successful, otherwise a negative error code. |
|---|
| 303 | 323 | */ |
|---|
| 304 | 324 | int kbase_job_slot_softstop_start_rp(struct kbase_context *kctx, |
|---|
| 305 | 325 | struct kbase_va_region *reg); |
|---|
| 306 | 326 | |
|---|
| 327 | +/** |
|---|
| 328 | + * kbase_job_slot_softstop - Soft-stop the specified job slot |
|---|
| 329 | + * |
|---|
| 330 | + * @kbdev: The kbase device |
|---|
| 331 | + * @js: The job slot to soft-stop |
|---|
| 332 | + * @target_katom: The job that should be soft-stopped (or NULL for any job) |
|---|
| 333 | + * Context: |
|---|
| 334 | + * The job slot lock must be held when calling this function. |
|---|
| 335 | + * The job slot must not already be in the process of being soft-stopped. |
|---|
| 336 | + * |
|---|
| 337 | + * Where possible any job in the next register is evicted before the soft-stop. |
|---|
| 338 | + */ |
|---|
| 307 | 339 | void kbase_job_slot_softstop(struct kbase_device *kbdev, int js, |
|---|
| 308 | 340 | struct kbase_jd_atom *target_katom); |
|---|
| 309 | | -void kbase_job_slot_softstop_swflags(struct kbase_device *kbdev, int js, |
|---|
| 310 | | - struct kbase_jd_atom *target_katom, u32 sw_flags); |
|---|
| 311 | | -void kbase_job_slot_hardstop(struct kbase_context *kctx, int js, |
|---|
| 312 | | - struct kbase_jd_atom *target_katom); |
|---|
| 341 | + |
|---|
| 342 | +void kbase_job_slot_softstop_swflags(struct kbase_device *kbdev, unsigned int js, |
|---|
| 343 | + struct kbase_jd_atom *target_katom, u32 sw_flags); |
|---|
| 344 | + |
|---|
| 345 | +/** |
|---|
| 346 | + * kbase_job_check_enter_disjoint - potentiall enter disjoint mode |
|---|
| 347 | + * @kbdev: kbase device |
|---|
| 348 | + * @action: the event which has occurred |
|---|
| 349 | + * @core_reqs: core requirements of the atom |
|---|
| 350 | + * @target_katom: the atom which is being affected |
|---|
| 351 | + * |
|---|
| 352 | + * For a certain soft-stop action, work out whether to enter disjoint |
|---|
| 353 | + * state. |
|---|
| 354 | + * |
|---|
| 355 | + * This does not register multiple disjoint events if the atom has already |
|---|
| 356 | + * started a disjoint period |
|---|
| 357 | + * |
|---|
| 358 | + * @core_reqs can be supplied as 0 if the atom had not started on the hardware |
|---|
| 359 | + * (and so a 'real' soft/hard-stop was not required, but it still interrupted |
|---|
| 360 | + * flow, perhaps on another context) |
|---|
| 361 | + * |
|---|
| 362 | + * kbase_job_check_leave_disjoint() should be used to end the disjoint |
|---|
| 363 | + * state when the soft/hard-stop action is complete |
|---|
| 364 | + */ |
|---|
| 313 | 365 | void kbase_job_check_enter_disjoint(struct kbase_device *kbdev, u32 action, |
|---|
| 314 | 366 | base_jd_core_req core_reqs, struct kbase_jd_atom *target_katom); |
|---|
| 367 | + |
|---|
| 368 | +/** |
|---|
| 369 | + * kbase_job_check_leave_disjoint - potentially leave disjoint state |
|---|
| 370 | + * @kbdev: kbase device |
|---|
| 371 | + * @target_katom: atom which is finishing |
|---|
| 372 | + * |
|---|
| 373 | + * Work out whether to leave disjoint state when finishing an atom that was |
|---|
| 374 | + * originated by kbase_job_check_enter_disjoint(). |
|---|
| 375 | + */ |
|---|
| 315 | 376 | void kbase_job_check_leave_disjoint(struct kbase_device *kbdev, |
|---|
| 316 | 377 | struct kbase_jd_atom *target_katom); |
|---|
| 317 | 378 | |
|---|
| .. | .. |
|---|
| 334 | 395 | * allocation is to be validated. |
|---|
| 335 | 396 | * @info: Pointer to struct @base_jit_alloc_info |
|---|
| 336 | 397 | * which is to be validated. |
|---|
| 337 | | - * @return: 0 if jit allocation is valid; negative error code otherwise |
|---|
| 398 | + * Return: 0 if jit allocation is valid; negative error code otherwise |
|---|
| 338 | 399 | */ |
|---|
| 339 | 400 | int kbasep_jit_alloc_validate(struct kbase_context *kctx, |
|---|
| 340 | 401 | struct base_jit_alloc_info *info); |
|---|
| .. | .. |
|---|
| 374 | 435 | } |
|---|
| 375 | 436 | } |
|---|
| 376 | 437 | |
|---|
| 377 | | -/** |
|---|
| 378 | | - * kbase_mem_copy_from_extres() - Copy from external resources. |
|---|
| 379 | | - * |
|---|
| 380 | | - * @kctx: kbase context within which the copying is to take place. |
|---|
| 381 | | - * @buf_data: Pointer to the information about external resources: |
|---|
| 382 | | - * pages pertaining to the external resource, number of |
|---|
| 383 | | - * pages to copy. |
|---|
| 384 | | - */ |
|---|
| 385 | | -int kbase_mem_copy_from_extres(struct kbase_context *kctx, |
|---|
| 386 | | - struct kbase_debug_copy_buffer *buf_data); |
|---|
| 387 | 438 | #if !MALI_USE_CSF |
|---|
| 388 | 439 | int kbase_process_soft_job(struct kbase_jd_atom *katom); |
|---|
| 389 | 440 | int kbase_prepare_soft_job(struct kbase_jd_atom *katom); |
|---|
| .. | .. |
|---|
| 391 | 442 | void kbase_cancel_soft_job(struct kbase_jd_atom *katom); |
|---|
| 392 | 443 | void kbase_resume_suspended_soft_jobs(struct kbase_device *kbdev); |
|---|
| 393 | 444 | void kbasep_remove_waiting_soft_job(struct kbase_jd_atom *katom); |
|---|
| 394 | | -#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE) |
|---|
| 445 | +#if IS_ENABLED(CONFIG_SYNC_FILE) |
|---|
| 395 | 446 | void kbase_soft_event_wait_callback(struct kbase_jd_atom *katom); |
|---|
| 396 | 447 | #endif |
|---|
| 397 | 448 | int kbase_soft_event_update(struct kbase_context *kctx, |
|---|
| .. | .. |
|---|
| 405 | 456 | void kbasep_as_do_poke(struct work_struct *work); |
|---|
| 406 | 457 | |
|---|
| 407 | 458 | /** |
|---|
| 408 | | - * Check whether a system suspend is in progress, or has already been suspended |
|---|
| 459 | + * kbase_pm_is_suspending - Check whether a system suspend is in progress, |
|---|
| 460 | + * or has already been suspended |
|---|
| 461 | + * |
|---|
| 409 | 462 | * @kbdev: The kbase device structure for the device |
|---|
| 410 | 463 | * |
|---|
| 411 | 464 | * The caller should ensure that either kbdev->pm.active_count_lock is held, or |
|---|
| .. | .. |
|---|
| 474 | 527 | } |
|---|
| 475 | 528 | |
|---|
| 476 | 529 | /** |
|---|
| 530 | + * kbase_pm_lowest_gpu_freq_init() - Find the lowest frequency that the GPU can |
|---|
| 531 | + * run as using the device tree, and save this |
|---|
| 532 | + * within kbdev. |
|---|
| 533 | + * @kbdev: Pointer to kbase device. |
|---|
| 534 | + * |
|---|
| 535 | + * This function could be called from kbase_clk_rate_trace_manager_init, |
|---|
| 536 | + * but is left separate as it can be called as soon as |
|---|
| 537 | + * dev_pm_opp_of_add_table() has been called to initialize the OPP table, |
|---|
| 538 | + * which occurs in power_control_init(). |
|---|
| 539 | + * |
|---|
| 540 | + * Return: 0 in any case. |
|---|
| 541 | + */ |
|---|
| 542 | +int kbase_pm_lowest_gpu_freq_init(struct kbase_device *kbdev); |
|---|
| 543 | + |
|---|
| 544 | +/** |
|---|
| 477 | 545 | * kbase_pm_metrics_start - Start the utilization metrics timer |
|---|
| 478 | 546 | * @kbdev: Pointer to the kbase device for which to start the utilization |
|---|
| 479 | 547 | * metrics calculation thread. |
|---|
| .. | .. |
|---|
| 491 | 559 | */ |
|---|
| 492 | 560 | void kbase_pm_metrics_stop(struct kbase_device *kbdev); |
|---|
| 493 | 561 | |
|---|
| 562 | +#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME) |
|---|
| 563 | +/** |
|---|
| 564 | + * kbase_pm_handle_runtime_suspend - Handle the runtime suspend of GPU |
|---|
| 565 | + * |
|---|
| 566 | + * @kbdev: The kbase device structure for the device (must be a valid pointer) |
|---|
| 567 | + * |
|---|
| 568 | + * This function is called from the runtime suspend callback function for |
|---|
| 569 | + * saving the HW state and powering down GPU, if GPU was in sleep state mode. |
|---|
| 570 | + * It does the following steps |
|---|
| 571 | + * - Powers up the L2 cache and re-activates the MCU. |
|---|
| 572 | + * - Suspend the CSGs |
|---|
| 573 | + * - Halts the MCU |
|---|
| 574 | + * - Powers down the L2 cache. |
|---|
| 575 | + * - Invokes the power_off callback to power down the GPU. |
|---|
| 576 | + * |
|---|
| 577 | + * Return: 0 if the GPU was already powered down or no error was encountered |
|---|
| 578 | + * in the power down, otherwise an error code. |
|---|
| 579 | + */ |
|---|
| 580 | +int kbase_pm_handle_runtime_suspend(struct kbase_device *kbdev); |
|---|
| 581 | + |
|---|
| 582 | +/** |
|---|
| 583 | + * kbase_pm_force_mcu_wakeup_after_sleep - Force the wake up of MCU from sleep |
|---|
| 584 | + * |
|---|
| 585 | + * @kbdev: The kbase device structure for the device (must be a valid pointer) |
|---|
| 586 | + * |
|---|
| 587 | + * This function forces the wake up of MCU from sleep state and wait for |
|---|
| 588 | + * MCU to become active. |
|---|
| 589 | + * It usually gets called from the runtime suspend callback function. |
|---|
| 590 | + * It also gets called from the GPU reset handler or at the time of system |
|---|
| 591 | + * suspend or when User tries to terminate/suspend the on-slot group. |
|---|
| 592 | + * |
|---|
| 593 | + * Note: @gpu_wakeup_override flag that forces the reactivation of MCU is |
|---|
| 594 | + * set by this function and it is the caller's responsibility to |
|---|
| 595 | + * clear the flag. |
|---|
| 596 | + * |
|---|
| 597 | + * Return: 0 if the wake up was successful. |
|---|
| 598 | + */ |
|---|
| 599 | +int kbase_pm_force_mcu_wakeup_after_sleep(struct kbase_device *kbdev); |
|---|
| 600 | +#endif |
|---|
| 601 | + |
|---|
| 494 | 602 | #if !MALI_USE_CSF |
|---|
| 495 | 603 | /** |
|---|
| 496 | | - * Return the atom's ID, as was originally supplied by userspace in |
|---|
| 604 | + * kbase_jd_atom_id - Return the atom's ID, as was originally supplied by userspace in |
|---|
| 497 | 605 | * base_jd_atom::atom_number |
|---|
| 498 | 606 | * @kctx: KBase context pointer |
|---|
| 499 | 607 | * @katom: Atome for which to return ID |
|---|
| 608 | + * |
|---|
| 609 | + * Return: the atom's ID. |
|---|
| 500 | 610 | */ |
|---|
| 501 | | -static inline int kbase_jd_atom_id(struct kbase_context *kctx, struct kbase_jd_atom *katom) |
|---|
| 611 | +static inline int kbase_jd_atom_id(struct kbase_context *kctx, |
|---|
| 612 | + const struct kbase_jd_atom *katom) |
|---|
| 502 | 613 | { |
|---|
| 503 | 614 | int result; |
|---|
| 504 | 615 | |
|---|
| .. | .. |
|---|
| 526 | 637 | #endif /* !MALI_USE_CSF */ |
|---|
| 527 | 638 | |
|---|
| 528 | 639 | /** |
|---|
| 529 | | - * Initialize the disjoint state |
|---|
| 640 | + * kbase_disjoint_init - Initialize the disjoint state |
|---|
| 641 | + * |
|---|
| 642 | + * @kbdev: The kbase device |
|---|
| 530 | 643 | * |
|---|
| 531 | 644 | * The disjoint event count and state are both set to zero. |
|---|
| 532 | 645 | * |
|---|
| .. | .. |
|---|
| 548 | 661 | * The disjoint event counter is also incremented immediately whenever a job is soft stopped |
|---|
| 549 | 662 | * and during context creation. |
|---|
| 550 | 663 | * |
|---|
| 551 | | - * @kbdev: The kbase device |
|---|
| 552 | | - * |
|---|
| 553 | 664 | * Return: 0 on success and non-zero value on failure. |
|---|
| 554 | 665 | */ |
|---|
| 555 | 666 | void kbase_disjoint_init(struct kbase_device *kbdev); |
|---|
| 556 | 667 | |
|---|
| 557 | 668 | /** |
|---|
| 558 | | - * Increase the count of disjoint events |
|---|
| 669 | + * kbase_disjoint_event - Increase the count of disjoint events |
|---|
| 559 | 670 | * called when a disjoint event has happened |
|---|
| 560 | 671 | * |
|---|
| 561 | 672 | * @kbdev: The kbase device |
|---|
| .. | .. |
|---|
| 563 | 674 | void kbase_disjoint_event(struct kbase_device *kbdev); |
|---|
| 564 | 675 | |
|---|
| 565 | 676 | /** |
|---|
| 566 | | - * Increase the count of disjoint events only if the GPU is in a disjoint state |
|---|
| 677 | + * kbase_disjoint_event_potential - Increase the count of disjoint events |
|---|
| 678 | + * only if the GPU is in a disjoint state |
|---|
| 679 | + * |
|---|
| 680 | + * @kbdev: The kbase device |
|---|
| 567 | 681 | * |
|---|
| 568 | 682 | * This should be called when something happens which could be disjoint if the GPU |
|---|
| 569 | 683 | * is in a disjoint state. The state refcount keeps track of this. |
|---|
| 570 | | - * |
|---|
| 571 | | - * @kbdev: The kbase device |
|---|
| 572 | 684 | */ |
|---|
| 573 | 685 | void kbase_disjoint_event_potential(struct kbase_device *kbdev); |
|---|
| 574 | 686 | |
|---|
| 575 | 687 | /** |
|---|
| 576 | | - * Returns the count of disjoint events |
|---|
| 688 | + * kbase_disjoint_event_get - Returns the count of disjoint events |
|---|
| 577 | 689 | * |
|---|
| 578 | 690 | * @kbdev: The kbase device |
|---|
| 579 | | - * @return the count of disjoint events |
|---|
| 691 | + * Return: the count of disjoint events |
|---|
| 580 | 692 | */ |
|---|
| 581 | 693 | u32 kbase_disjoint_event_get(struct kbase_device *kbdev); |
|---|
| 582 | 694 | |
|---|
| 583 | 695 | /** |
|---|
| 584 | | - * Increment the refcount state indicating that the GPU is in a disjoint state. |
|---|
| 696 | + * kbase_disjoint_state_up - Increment the refcount state indicating that |
|---|
| 697 | + * the GPU is in a disjoint state. |
|---|
| 698 | + * |
|---|
| 699 | + * @kbdev: The kbase device |
|---|
| 585 | 700 | * |
|---|
| 586 | 701 | * Also Increment the disjoint event count (calls @ref kbase_disjoint_event) |
|---|
| 587 | 702 | * eventually after the disjoint state has completed @ref kbase_disjoint_state_down |
|---|
| 588 | 703 | * should be called |
|---|
| 589 | | - * |
|---|
| 590 | | - * @kbdev: The kbase device |
|---|
| 591 | 704 | */ |
|---|
| 592 | 705 | void kbase_disjoint_state_up(struct kbase_device *kbdev); |
|---|
| 593 | 706 | |
|---|
| 594 | 707 | /** |
|---|
| 595 | | - * Decrement the refcount state |
|---|
| 708 | + * kbase_disjoint_state_down - Decrement the refcount state |
|---|
| 709 | + * |
|---|
| 710 | + * @kbdev: The kbase device |
|---|
| 596 | 711 | * |
|---|
| 597 | 712 | * Also Increment the disjoint event count (calls @ref kbase_disjoint_event) |
|---|
| 598 | 713 | * |
|---|
| 599 | 714 | * Called after @ref kbase_disjoint_state_up once the disjoint state is over |
|---|
| 600 | | - * |
|---|
| 601 | | - * @kbdev: The kbase device |
|---|
| 602 | 715 | */ |
|---|
| 603 | 716 | void kbase_disjoint_state_down(struct kbase_device *kbdev); |
|---|
| 604 | 717 | |
|---|
| .. | .. |
|---|
| 627 | 740 | void kbase_device_pcm_dev_term(struct kbase_device *const kbdev); |
|---|
| 628 | 741 | |
|---|
| 629 | 742 | /** |
|---|
| 630 | | - * If a job is soft stopped and the number of contexts is >= this value |
|---|
| 631 | | - * it is reported as a disjoint event |
|---|
| 743 | + * KBASE_DISJOINT_STATE_INTERLEAVED_CONTEXT_COUNT_THRESHOLD - If a job is soft stopped |
|---|
| 744 | + * and the number of contexts is >= this value it is reported as a disjoint event |
|---|
| 632 | 745 | */ |
|---|
| 633 | 746 | #define KBASE_DISJOINT_STATE_INTERLEAVED_CONTEXT_COUNT_THRESHOLD 2 |
|---|
| 634 | 747 | |
|---|