/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
/*
|
*
|
* (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
|
*
|
* This program is free software and is provided to you under the terms of the
|
* GNU General Public License version 2 as published by the Free Software
|
* Foundation, and any use by you of this program is subject to the terms
|
* of such GNU license.
|
*
|
* This program is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* GNU General Public License for more details.
|
*
|
* You should have received a copy of the GNU General Public License
|
* along with this program; if not, you can access it online at
|
* http://www.gnu.org/licenses/gpl-2.0.html.
|
*
|
*/
|
|
/**
|
* @file
|
* Mali arbiter power manager state machine and APIs
|
*/
|
|
#ifndef _MALI_KBASE_ARBITER_PM_H_
|
#define _MALI_KBASE_ARBITER_PM_H_
|
|
#include "mali_kbase_arbif.h"
|
|
/**
|
* enum kbase_vm_state - Current PM Arbitration state.
|
*
|
* @KBASE_VM_STATE_INITIALIZING: Special state before arbiter is initialized.
|
* @KBASE_VM_STATE_INITIALIZING_WITH_GPU: Initialization after GPU
|
* has been granted.
|
* @KBASE_VM_STATE_SUSPENDED: KBase is suspended by OS and GPU is not assigned.
|
* @KBASE_VM_STATE_STOPPED: GPU is not assigned to KBase and is not required.
|
* @KBASE_VM_STATE_STOPPED_GPU_REQUESTED: GPU is not assigned to KBase
|
* but a request has been made.
|
* @KBASE_VM_STATE_STARTING: GPU is assigned and KBase is getting ready to run.
|
* @KBASE_VM_STATE_IDLE: GPU is assigned but KBase has no work to do
|
* @KBASE_VM_STATE_ACTIVE: GPU is assigned and KBase is busy using it
|
* @KBASE_VM_STATE_SUSPEND_PENDING: OS is going into suspend mode.
|
* @KBASE_VM_STATE_SUSPEND_WAIT_FOR_GRANT: OS is going into suspend mode but GPU
|
* has already been requested.
|
* In this situation we must wait for
|
* the Arbiter to send a GRANTED message
|
* and respond immediately with
|
* a STOPPED message before entering
|
* the suspend mode.
|
* @KBASE_VM_STATE_STOPPING_IDLE: Arbiter has sent a stopped message and there
|
* is currently no work to do on the GPU.
|
* @KBASE_VM_STATE_STOPPING_ACTIVE: Arbiter has sent a stopped message when
|
* KBase has work to do.
|
*/
|
enum kbase_vm_state {
|
KBASE_VM_STATE_INITIALIZING,
|
KBASE_VM_STATE_INITIALIZING_WITH_GPU,
|
KBASE_VM_STATE_SUSPENDED,
|
KBASE_VM_STATE_STOPPED,
|
KBASE_VM_STATE_STOPPED_GPU_REQUESTED,
|
KBASE_VM_STATE_STARTING,
|
KBASE_VM_STATE_IDLE,
|
KBASE_VM_STATE_ACTIVE,
|
KBASE_VM_STATE_SUSPEND_PENDING,
|
KBASE_VM_STATE_SUSPEND_WAIT_FOR_GRANT,
|
KBASE_VM_STATE_STOPPING_IDLE,
|
KBASE_VM_STATE_STOPPING_ACTIVE
|
};
|
|
/**
|
* kbase_arbiter_pm_early_init() - Initialize arbiter for VM Paravirtualized use
|
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
*
|
* Initialize the arbiter and other required resources during the runtime
|
* and request the GPU for the VM for the first time.
|
*
|
* Return: 0 if successful, otherwise a standard Linux error code
|
*/
|
int kbase_arbiter_pm_early_init(struct kbase_device *kbdev);
|
|
/**
|
* kbase_arbiter_pm_early_term() - Shutdown arbiter and free resources.
|
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
*
|
* Clean up all the resources
|
*/
|
void kbase_arbiter_pm_early_term(struct kbase_device *kbdev);
|
|
/**
|
* kbase_arbiter_pm_release_interrupts() - Release the GPU interrupts
|
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
*
|
* Releases interrupts and set the interrupt flag to false
|
*/
|
void kbase_arbiter_pm_release_interrupts(struct kbase_device *kbdev);
|
|
/**
|
* kbase_arbiter_pm_install_interrupts() - Install the GPU interrupts
|
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
*
|
* Install interrupts and set the interrupt_install flag to true.
|
*/
|
int kbase_arbiter_pm_install_interrupts(struct kbase_device *kbdev);
|
|
/**
|
* kbase_arbiter_pm_vm_event() - Dispatch VM event to the state machine
|
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
*
|
* The state machine function. Receives events and transitions states
|
* according the event received and the current state
|
*/
|
void kbase_arbiter_pm_vm_event(struct kbase_device *kbdev,
|
enum kbase_arbif_evt event);
|
|
/**
|
* kbase_arbiter_pm_ctx_active_handle_suspend() - Handle suspend operation for
|
* arbitration mode
|
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
* @suspend_handler: The handler code for how to handle a suspend
|
* that might occur
|
*
|
* This function handles a suspend event from the driver,
|
* communicating with the arbiter and waiting synchronously for the GPU
|
* to be granted again depending on the VM state.
|
*
|
* Return: 0 if success, 1 if failure due to system suspending/suspended
|
*/
|
int kbase_arbiter_pm_ctx_active_handle_suspend(struct kbase_device *kbdev,
|
enum kbase_pm_suspend_handler suspend_handler);
|
|
|
/**
|
* kbase_arbiter_pm_vm_stopped() - Handle stop event for the VM
|
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
*
|
* This function handles a stop event for the VM.
|
* It will update the VM state and forward the stop event to the driver.
|
*/
|
void kbase_arbiter_pm_vm_stopped(struct kbase_device *kbdev);
|
|
/**
|
* kbase_arbiter_set_max_config() - Set the max config data in kbase device.
|
* @kbdev: The kbase device structure for the device (must be a valid pointer).
|
* @max_l2_slices: The maximum number of L2 slices.
|
* @max_core_mask: The largest core mask.
|
*
|
* This function handles a stop event for the VM.
|
* It will update the VM state and forward the stop event to the driver.
|
*/
|
void kbase_arbiter_set_max_config(struct kbase_device *kbdev,
|
uint32_t max_l2_slices,
|
uint32_t max_core_mask);
|
|
/**
|
* kbase_arbiter_pm_gpu_assigned() - Determine if this VM has access to the GPU
|
* @kbdev: The kbase device structure for the device (must be a valid pointer)
|
*
|
* Return: 0 if the VM does not have access, 1 if it does, and a negative number
|
* if an error occurred
|
*/
|
int kbase_arbiter_pm_gpu_assigned(struct kbase_device *kbdev);
|
|
extern struct kbase_clk_rate_trace_op_conf arb_clk_rate_trace_ops;
|
|
/**
|
* struct kbase_arbiter_freq - Holding the GPU clock frequency data retrieved
|
* from arbiter
|
* @arb_freq: GPU clock frequency value
|
* @arb_freq_lock: Mutex protecting access to arbfreq value
|
* @nb: Notifier block to receive rate change callbacks
|
* @freq_updated: Flag to indicate whether a frequency changed has just been
|
* communicated to avoid "GPU_GRANTED when not expected" warning
|
*/
|
struct kbase_arbiter_freq {
|
uint32_t arb_freq;
|
struct mutex arb_freq_lock;
|
struct notifier_block *nb;
|
bool freq_updated;
|
};
|
|
/**
|
* kbase_arbiter_pm_update_gpu_freq() - Update GPU frequency
|
* @arb_freq: Pointer to GPU clock frequency data
|
* @freq: The new frequency
|
*
|
* Updates the GPU frequency and triggers any notifications
|
*/
|
void kbase_arbiter_pm_update_gpu_freq(struct kbase_arbiter_freq *arb_freq,
|
uint32_t freq);
|
|
#endif /*_MALI_KBASE_ARBITER_PM_H_ */
|