From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:20:52 +0000
Subject: [PATCH] add new system file
---
kernel/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_pm_internal.h | 348 +++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 274 insertions(+), 74 deletions(-)
diff --git a/kernel/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_pm_internal.h b/kernel/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_pm_internal.h
index 9ec5890..e66ce57 100644
--- a/kernel/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_pm_internal.h
+++ b/kernel/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_pm_internal.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
- * (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
+ * (C) COPYRIGHT 2010-2022 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
@@ -35,18 +35,18 @@
/**
* kbase_pm_dev_idle - The GPU is idle.
*
- * The OS may choose to turn off idle devices
- *
* @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
+ * The OS may choose to turn off idle devices
*/
void kbase_pm_dev_idle(struct kbase_device *kbdev);
/**
* kbase_pm_dev_activate - The GPU is active.
*
- * The OS should avoid opportunistically turning off the GPU while it is active
- *
* @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
+ * The OS should avoid opportunistically turning off the GPU while it is active
*/
void kbase_pm_dev_activate(struct kbase_device *kbdev);
@@ -54,13 +54,13 @@
* kbase_pm_get_present_cores - Get details of the cores that are present in
* the device.
*
- * This function can be called by the active power policy to return a bitmask of
- * the cores (of a specified type) present in the GPU device and also a count of
- * the number of cores.
- *
* @kbdev: The kbase device structure for the device (must be a valid
* pointer)
* @type: The type of core (see the enum kbase_pm_core_type enumeration)
+ *
+ * This function can be called by the active power policy to return a bitmask of
+ * the cores (of a specified type) present in the GPU device and also a count of
+ * the number of cores.
*
* Return: The bit mask of cores present
*/
@@ -71,12 +71,12 @@
* kbase_pm_get_active_cores - Get details of the cores that are currently
* active in the device.
*
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ * @type: The type of core (see the enum kbase_pm_core_type enumeration)
+ *
* This function can be called by the active power policy to return a bitmask of
* the cores (of a specified type) that are actively processing work (i.e.
* turned on *and* busy).
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
- * @type: The type of core (see the enum kbase_pm_core_type enumeration)
*
* Return: The bit mask of active cores
*/
@@ -87,12 +87,12 @@
* kbase_pm_get_trans_cores - Get details of the cores that are currently
* transitioning between power states.
*
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ * @type: The type of core (see the enum kbase_pm_core_type enumeration)
+ *
* This function can be called by the active power policy to return a bitmask of
* the cores (of a specified type) that are currently transitioning between
* power states.
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
- * @type: The type of core (see the enum kbase_pm_core_type enumeration)
*
* Return: The bit mask of transitioning cores
*/
@@ -103,12 +103,12 @@
* kbase_pm_get_ready_cores - Get details of the cores that are currently
* powered and ready for jobs.
*
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ * @type: The type of core (see the enum kbase_pm_core_type enumeration)
+ *
* This function can be called by the active power policy to return a bitmask of
* the cores (of a specified type) that are powered and ready for jobs (they may
* or may not be currently executing jobs).
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
- * @type: The type of core (see the enum kbase_pm_core_type enumeration)
*
* Return: The bit mask of ready cores
*/
@@ -119,13 +119,13 @@
* kbase_pm_clock_on - Turn the clock for the device on, and enable device
* interrupts.
*
- * This function can be used by a power policy to turn the clock for the GPU on.
- * It should be modified during integration to perform the necessary actions to
- * ensure that the GPU is fully powered and clocked.
- *
* @kbdev: The kbase device structure for the device (must be a valid
* pointer)
* @is_resume: true if clock on due to resume after suspend, false otherwise
+ *
+ * This function can be used by a power policy to turn the clock for the GPU on.
+ * It should be modified during integration to perform the necessary actions to
+ * ensure that the GPU is fully powered and clocked.
*/
void kbase_pm_clock_on(struct kbase_device *kbdev, bool is_resume);
@@ -133,12 +133,16 @@
* kbase_pm_clock_off - Disable device interrupts, and turn the clock for the
* device off.
*
+ * @kbdev: The kbase device structure for the device (must be a valid
+ * pointer)
+ *
* This function can be used by a power policy to turn the clock for the GPU
* off. It should be modified during integration to perform the necessary
* actions to turn the clock off (if this is possible in the integration).
*
- * @kbdev: The kbase device structure for the device (must be a valid
- * pointer)
+ * If runtime PM is enabled and @power_runtime_gpu_idle_callback is used
+ * then this function would usually be invoked from the runtime suspend
+ * callback function.
*
* Return: true if clock was turned off, or
* false if clock can not be turned off due to pending page/bus fault
@@ -149,22 +153,22 @@
/**
* kbase_pm_enable_interrupts - Enable interrupts on the device.
*
- * Interrupts are also enabled after a call to kbase_pm_clock_on().
- *
* @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
+ * Interrupts are also enabled after a call to kbase_pm_clock_on().
*/
void kbase_pm_enable_interrupts(struct kbase_device *kbdev);
/**
* kbase_pm_disable_interrupts - Disable interrupts on the device.
*
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
* This prevents delivery of Power Management interrupts to the CPU so that
* kbase_pm_update_state() will not be called from the IRQ handler
* until kbase_pm_enable_interrupts() or kbase_pm_clock_on() is called.
*
* Interrupts are also disabled after a call to kbase_pm_clock_off().
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_disable_interrupts(struct kbase_device *kbdev);
@@ -172,9 +176,9 @@
* kbase_pm_disable_interrupts_nolock - Version of kbase_pm_disable_interrupts()
* that does not take the hwaccess_lock
*
- * Caller must hold the hwaccess_lock.
- *
* @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
+ * Caller must hold the hwaccess_lock.
*/
void kbase_pm_disable_interrupts_nolock(struct kbase_device *kbdev);
@@ -193,12 +197,11 @@
/**
* kbase_pm_reset_done - The GPU has been reset successfully.
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* This function must be called by the GPU interrupt handler when the
* RESET_COMPLETED bit is set. It signals to the power management initialization
* code that the GPU has been successfully reset.
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_reset_done(struct kbase_device *kbdev);
@@ -206,6 +209,7 @@
/**
* kbase_pm_wait_for_desired_state - Wait for the desired power state to be
* reached
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Wait for the L2 and MCU state machines to reach the states corresponding
* to the values of 'kbase_pm_is_l2_desired' and 'kbase_pm_is_mcu_desired'.
@@ -220,8 +224,6 @@
* power off in progress and kbase_pm_context_active() was called instead of
* kbase_csf_scheduler_pm_active().
*
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
- *
* Return: 0 on success, error code on error
*/
int kbase_pm_wait_for_desired_state(struct kbase_device *kbdev);
@@ -229,6 +231,7 @@
/**
* kbase_pm_wait_for_desired_state - Wait for the desired power state to be
* reached
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Wait for the L2 and shader power state machines to reach the states
* corresponding to the values of 'l2_desired' and 'shaders_desired'.
@@ -242,9 +245,7 @@
* NOTE: This may not wait until the correct state is reached if there is a
* power off in progress. To correctly wait for the desired state the caller
* must ensure that this is not the case by, for example, calling
- * kbase_pm_wait_for_poweroff_complete()
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ * kbase_pm_wait_for_poweroff_work_complete()
*
* Return: 0 on success, error code on error
*/
@@ -254,6 +255,8 @@
/**
* kbase_pm_wait_for_l2_powered - Wait for the L2 cache to be powered on
*
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
* Wait for the L2 to be powered on, and for the L2 and the state machines of
* its dependent stack components to stabilise.
*
@@ -262,23 +265,51 @@
* Unlike kbase_pm_update_state(), the caller must not hold hwaccess_lock,
* because this function will take that lock itself.
*
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
- *
* Return: 0 on success, error code on error
*/
int kbase_pm_wait_for_l2_powered(struct kbase_device *kbdev);
+
+#if MALI_USE_CSF
+/**
+ * kbase_pm_wait_for_cores_down_scale - Wait for the downscaling of shader cores
+ *
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
+ * This function can be called to ensure that the downscaling of cores is
+ * effectively complete and it would be safe to lower the voltage.
+ * The function assumes that caller had exercised the MCU state machine for the
+ * downscale request through the kbase_pm_update_state() function.
+ *
+ * This function needs to be used by the caller to safely wait for the completion
+ * of downscale request, instead of kbase_pm_wait_for_desired_state().
+ * The downscale request would trigger a state change in MCU state machine
+ * and so when MCU reaches the stable ON state, it can be inferred that
+ * downscaling is complete. But it has been observed that the wake up of the
+ * waiting thread can get delayed by few milli seconds and by the time the
+ * thread wakes up the power down transition could have started (after the
+ * completion of downscale request).
+ * On the completion of power down transition another wake up signal would be
+ * sent, but again by the time thread wakes up the power up transition can begin.
+ * And the power up transition could then get blocked inside the platform specific
+ * callback_power_on() function due to the thread that called into Kbase (from the
+ * platform specific code) to perform the downscaling and then ended up waiting
+ * for the completion of downscale request.
+ *
+ * Return: 0 on success, error code on error or remaining jiffies on timeout.
+ */
+int kbase_pm_wait_for_cores_down_scale(struct kbase_device *kbdev);
+#endif
/**
* kbase_pm_update_dynamic_cores_onoff - Update the L2 and shader power state
* machines after changing shader core
* availability
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* It can be called in any status, so need to check the l2 and shader core
* power status in this function or it will break shader/l2 state machine
*
* Caller must hold hwaccess_lock
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_update_dynamic_cores_onoff(struct kbase_device *kbdev);
@@ -301,6 +332,8 @@
* kbase_pm_state_machine_init - Initialize the state machines, primarily the
* shader poweroff timer
* @kbdev: Device pointer
+ *
+ * Return: 0 on success, error code on error
*/
int kbase_pm_state_machine_init(struct kbase_device *kbdev);
@@ -314,22 +347,21 @@
* kbase_pm_update_cores_state - Update the desired state of shader cores from
* the Power Policy, and begin any power
* transitions.
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* This function will update the desired_xx_state members of
* struct kbase_pm_device_data by calling into the current Power Policy. It will
* then begin power transitions to make the hardware acheive the desired shader
* core state.
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_update_cores_state(struct kbase_device *kbdev);
/**
* kbasep_pm_metrics_init - Initialize the metrics gathering framework.
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* This must be called before other metric gathering APIs are called.
*
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Return: 0 on success, error code on error
*/
@@ -337,29 +369,27 @@
/**
* kbasep_pm_metrics_term - Terminate the metrics gathering framework.
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* This must be called when metric gathering is no longer required. It is an
* error to call any metrics gathering function (other than
* kbasep_pm_metrics_init()) after calling this function.
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbasep_pm_metrics_term(struct kbase_device *kbdev);
/**
* kbase_pm_report_vsync - Function to be called by the frame buffer driver to
* update the vsync metric.
+ * @kbdev: The kbase device structure for the device (must be a
+ * valid pointer)
+ * @buffer_updated: True if the buffer has been updated on this VSync,
+ * false otherwise
*
* This function should be called by the frame buffer driver to update whether
* the system is hitting the vsync target or not. buffer_updated should be true
* if the vsync corresponded with a new frame being displayed, otherwise it
* should be false. This function does not need to be called every vsync, but
* only when the value of @buffer_updated differs from a previous call.
- *
- * @kbdev: The kbase device structure for the device (must be a
- * valid pointer)
- * @buffer_updated: True if the buffer has been updated on this VSync,
- * false otherwise
*/
void kbase_pm_report_vsync(struct kbase_device *kbdev, int buffer_updated);
@@ -377,6 +407,7 @@
/**
* kbase_pm_request_gpu_cycle_counter - Mark that the GPU cycle counter is
* needed
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* If the caller is the first caller then the GPU cycle counters will be enabled
* along with the l2 cache
@@ -384,13 +415,13 @@
* The GPU must be powered when calling this function (i.e.
* kbase_pm_context_active() must have been called).
*
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_request_gpu_cycle_counter(struct kbase_device *kbdev);
/**
* kbase_pm_request_gpu_cycle_counter_l2_is_on - Mark GPU cycle counter is
* needed (l2 cache already on)
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* This is a version of the above function
* (kbase_pm_request_gpu_cycle_counter()) suitable for being called when the
@@ -401,14 +432,13 @@
* The GPU must be powered when calling this function (i.e.
* kbase_pm_context_active() must have been called) and the l2 cache must be
* powered on.
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_request_gpu_cycle_counter_l2_is_on(struct kbase_device *kbdev);
/**
* kbase_pm_release_gpu_cycle_counter - Mark that the GPU cycle counter is no
* longer in use
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* If the caller is the last caller then the GPU cycle counters will be
* disabled. A request must have been made before a call to this.
@@ -416,37 +446,48 @@
* Caller must not hold the hwaccess_lock, as it will be taken in this function.
* If the caller is already holding this lock then
* kbase_pm_release_gpu_cycle_counter_nolock() must be used instead.
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_release_gpu_cycle_counter(struct kbase_device *kbdev);
/**
* kbase_pm_release_gpu_cycle_counter_nolock - Version of kbase_pm_release_gpu_cycle_counter()
* that does not take hwaccess_lock
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Caller must hold the hwaccess_lock.
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_release_gpu_cycle_counter_nolock(struct kbase_device *kbdev);
/**
- * kbase_pm_wait_for_poweroff_complete - Wait for the poweroff workqueue to
- * complete
+ * kbase_pm_wait_for_poweroff_work_complete - Wait for the poweroff workqueue to
+ * complete
*
* @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
+ * This function effectively just waits for the @gpu_poweroff_wait_work work
+ * item to complete, if it was enqueued. GPU may not have been powered down
+ * before this function returns.
*/
-void kbase_pm_wait_for_poweroff_complete(struct kbase_device *kbdev);
+void kbase_pm_wait_for_poweroff_work_complete(struct kbase_device *kbdev);
+
+/**
+ * kbase_pm_wait_for_gpu_power_down - Wait for the GPU power down to complete
+ *
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
+ * This function waits for the actual gpu power down to complete.
+ */
+void kbase_pm_wait_for_gpu_power_down(struct kbase_device *kbdev);
/**
* kbase_pm_runtime_init - Initialize runtime-pm for Mali GPU platform device
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Setup the power management callbacks and initialize/enable the runtime-pm
* for the Mali GPU platform device, using the callback function. This must be
* called before the kbase_pm_register_access_enable() function.
*
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ * Return: 0 on success, error code on error
*/
int kbase_pm_runtime_init(struct kbase_device *kbdev);
@@ -459,6 +500,7 @@
/**
* kbase_pm_register_access_enable - Enable access to GPU registers
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Enables access to the GPU registers before power management has powered up
* the GPU with kbase_pm_powerup().
@@ -469,13 +511,12 @@
*
* This should only be used before power management is powered up with
* kbase_pm_powerup()
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_register_access_enable(struct kbase_device *kbdev);
/**
* kbase_pm_register_access_disable - Disable early register access
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Disables access to the GPU registers enabled earlier by a call to
* kbase_pm_register_access_enable().
@@ -486,8 +527,6 @@
*
* This should only be used before power management is powered up with
* kbase_pm_powerup()
- *
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
*/
void kbase_pm_register_access_disable(struct kbase_device *kbdev);
@@ -498,6 +537,7 @@
/**
* kbase_pm_metrics_is_active - Check if the power management metrics
* collection is active.
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Note that this returns if the power management metrics collection was
* active at the time of calling, it is possible that after the call the metrics
@@ -505,7 +545,6 @@
*
* The caller must handle the consequence that the state may have changed.
*
- * @kbdev: The kbase device structure for the device (must be a valid pointer)
* Return: true if metrics collection was active else false.
*/
bool kbase_pm_metrics_is_active(struct kbase_device *kbdev);
@@ -541,12 +580,13 @@
/**
* kbase_platform_dvfs_event - Report utilisation to DVFS code for CSF GPU
*
- * Function provided by platform specific code when DVFS is enabled to allow
- * the power management metrics system to report utilisation.
- *
* @kbdev: The kbase device structure for the device (must be a
* valid pointer)
* @utilisation: The current calculated utilisation by the metrics system.
+ *
+ * Function provided by platform specific code when DVFS is enabled to allow
+ * the power management metrics system to report utilisation.
+ *
* Return: Returns 0 on failure and non zero on success.
*/
int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation);
@@ -554,15 +594,15 @@
/**
* kbase_platform_dvfs_event - Report utilisation to DVFS code for JM GPU
*
- * Function provided by platform specific code when DVFS is enabled to allow
- * the power management metrics system to report utilisation.
- *
* @kbdev: The kbase device structure for the device (must be a
* valid pointer)
* @utilisation: The current calculated utilisation by the metrics system.
* @util_gl_share: The current calculated gl share of utilisation.
* @util_cl_share: The current calculated cl share of utilisation per core
* group.
+ * Function provided by platform specific code when DVFS is enabled to allow
+ * the power management metrics system to report utilisation.
+ *
* Return: Returns 0 on failure and non zero on success.
*/
int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation,
@@ -635,6 +675,7 @@
*/
void kbase_pm_reset_complete(struct kbase_device *kbdev);
+#if !MALI_USE_CSF
/**
* kbase_pm_protected_override_enable - Enable the protected mode override
* @kbdev: Device pointer
@@ -707,6 +748,7 @@
* to enter protected mode.
*/
void kbase_pm_protected_entry_override_disable(struct kbase_device *kbdev);
+#endif
/* If true, the driver should explicitly control corestack power management,
* instead of relying on the Power Domain Controller.
@@ -735,6 +777,21 @@
* Return: true if MCU needs to be enabled.
*/
bool kbase_pm_is_mcu_desired(struct kbase_device *kbdev);
+
+/**
+ * kbase_pm_is_mcu_inactive - Check if the MCU is inactive (i.e. either
+ * it is disabled or it is in sleep)
+ *
+ * @kbdev: kbase device
+ * @state: state of the MCU state machine.
+ *
+ * This function must be called with hwaccess_lock held.
+ * L2 cache can be turned off if this function returns true.
+ *
+ * Return: true if MCU is inactive
+ */
+bool kbase_pm_is_mcu_inactive(struct kbase_device *kbdev,
+ enum kbase_mcu_state state);
/**
* kbase_pm_idle_groups_sched_suspendable - Check whether the scheduler can be
@@ -774,7 +831,7 @@
/**
* kbase_pm_no_mcu_core_pwroff - Check whether the PM is required to keep the
- * MCU core powered in accordance to the active
+ * MCU shader Core powered in accordance to the active
* power management policy
*
* @kbdev: Device pointer
@@ -788,7 +845,48 @@
return kbdev->pm.backend.csf_pm_sched_flags &
CSF_DYNAMIC_PM_CORE_KEEP_ON;
}
+
+/**
+ * kbase_pm_mcu_is_in_desired_state - Check if MCU is in stable ON/OFF state.
+ *
+ * @kbdev: Device pointer
+ *
+ * Return: true if MCU is in stable ON/OFF state.
+ */
+static inline bool kbase_pm_mcu_is_in_desired_state(struct kbase_device *kbdev)
+{
+ bool in_desired_state = true;
+
+ if (kbase_pm_is_mcu_desired(kbdev) && kbdev->pm.backend.mcu_state != KBASE_MCU_ON)
+ in_desired_state = false;
+ else if (!kbase_pm_is_mcu_desired(kbdev) &&
+ (kbdev->pm.backend.mcu_state != KBASE_MCU_OFF) &&
+ (kbdev->pm.backend.mcu_state != KBASE_MCU_IN_SLEEP))
+ in_desired_state = false;
+
+ return in_desired_state;
+}
+
#endif
+
+/**
+ * kbase_pm_l2_is_in_desired_state - Check if L2 is in stable ON/OFF state.
+ *
+ * @kbdev: Device pointer
+ *
+ * Return: true if L2 is in stable ON/OFF state.
+ */
+static inline bool kbase_pm_l2_is_in_desired_state(struct kbase_device *kbdev)
+{
+ bool in_desired_state = true;
+
+ if (kbase_pm_is_l2_desired(kbdev) && kbdev->pm.backend.l2_state != KBASE_L2_ON)
+ in_desired_state = false;
+ else if (!kbase_pm_is_l2_desired(kbdev) && kbdev->pm.backend.l2_state != KBASE_L2_OFF)
+ in_desired_state = false;
+
+ return in_desired_state;
+}
/**
* kbase_pm_lock - Lock all necessary mutexes to perform PM actions
@@ -818,4 +916,106 @@
#endif /* !MALI_USE_CSF */
}
+#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
+/**
+ * kbase_pm_gpu_sleep_allowed - Check if the GPU is allowed to be put in sleep
+ *
+ * @kbdev: Device pointer
+ *
+ * This function is called on GPU idle notification and if it returns false then
+ * GPU power down will be triggered by suspending the CSGs and halting the MCU.
+ *
+ * Return: true if the GPU is allowed to be in the sleep state.
+ */
+static inline bool kbase_pm_gpu_sleep_allowed(struct kbase_device *kbdev)
+{
+ /* If the autosuspend_delay has been set to 0 then it doesn't make
+ * sense to first put GPU to sleep state and then power it down,
+ * instead would be better to power it down right away.
+ * Also need to do the same when autosuspend_delay is set to a negative
+ * value, which implies that runtime pm is effectively disabled by the
+ * kernel.
+ * A high positive value of autosuspend_delay can be used to keep the
+ * GPU in sleep state for a long time.
+ */
+ if (unlikely(!kbdev->dev->power.autosuspend_delay ||
+ (kbdev->dev->power.autosuspend_delay < 0)))
+ return false;
+
+ return kbdev->pm.backend.gpu_sleep_supported;
+}
+
+/**
+ * kbase_pm_enable_db_mirror_interrupt - Enable the doorbell mirror interrupt to
+ * detect the User doorbell rings.
+ *
+ * @kbdev: Device pointer
+ *
+ * This function is called just before sending the sleep request to MCU firmware
+ * so that User doorbell rings can be detected whilst GPU remains in the sleep
+ * state.
+ *
+ */
+static inline void kbase_pm_enable_db_mirror_interrupt(struct kbase_device *kbdev)
+{
+ lockdep_assert_held(&kbdev->hwaccess_lock);
+
+ if (!kbdev->pm.backend.db_mirror_interrupt_enabled) {
+ u32 irq_mask = kbase_reg_read(kbdev,
+ GPU_CONTROL_REG(GPU_IRQ_MASK));
+
+ WARN_ON(irq_mask & DOORBELL_MIRROR);
+
+ kbase_reg_write(kbdev, GPU_CONTROL_REG(GPU_IRQ_MASK),
+ irq_mask | DOORBELL_MIRROR);
+ kbdev->pm.backend.db_mirror_interrupt_enabled = true;
+ }
+}
+
+/**
+ * kbase_pm_disable_db_mirror_interrupt - Disable the doorbell mirror interrupt.
+ *
+ * @kbdev: Device pointer
+ *
+ * This function is called when doorbell mirror interrupt is received or MCU
+ * needs to be reactivated by enabling the doorbell notification.
+ */
+static inline void kbase_pm_disable_db_mirror_interrupt(struct kbase_device *kbdev)
+{
+ lockdep_assert_held(&kbdev->hwaccess_lock);
+
+ if (kbdev->pm.backend.db_mirror_interrupt_enabled) {
+ u32 irq_mask = kbase_reg_read(kbdev,
+ GPU_CONTROL_REG(GPU_IRQ_MASK));
+
+ kbase_reg_write(kbdev, GPU_CONTROL_REG(GPU_IRQ_MASK),
+ irq_mask & ~DOORBELL_MIRROR);
+ kbdev->pm.backend.db_mirror_interrupt_enabled = false;
+ }
+}
+#endif
+
+/**
+ * kbase_pm_l2_allow_mmu_page_migration - L2 state allows MMU page migration or not
+ *
+ * @kbdev: The kbase device structure for the device (must be a valid pointer)
+ *
+ * Check whether the L2 state is in power transition phase or not. If it is, the MMU
+ * page migration should be deferred. The caller must hold hwaccess_lock, and, if MMU
+ * page migration is intended, immediately start the MMU migration action without
+ * dropping the lock. When page migration begins, a flag is set in kbdev that would
+ * prevent the L2 state machine traversing into power transition phases, until
+ * the MMU migration action ends.
+ *
+ * Return: true if MMU page migration is allowed
+ */
+static inline bool kbase_pm_l2_allow_mmu_page_migration(struct kbase_device *kbdev)
+{
+ struct kbase_pm_backend_data *backend = &kbdev->pm.backend;
+
+ lockdep_assert_held(&kbdev->hwaccess_lock);
+
+ return (backend->l2_state != KBASE_L2_PEND_ON && backend->l2_state != KBASE_L2_PEND_OFF);
+}
+
#endif /* _KBASE_BACKEND_PM_INTERNAL_H_ */
--
Gitblit v1.6.2