2 * Copyright (C) 2010 ARM Limited. All rights reserved.
4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
7 * A copy of the licence is included with the program, and can also be obtained from Free Software
8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
11 #ifndef __MALI_PMM_STATE_H__
12 #define __MALI_PMM_STATE_H__
20 * @addtogroup pmmapi Power Management Module APIs
24 * @defgroup pmmapi_state Power Management Module State
29 /* Check that the subset is really a subset of cores */
30 #define MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( cores, subset ) \
31 MALI_DEBUG_ASSERT( ((~(cores)) & (subset)) == 0 )
35 #define MALI_PMM_LOCK(pmm) \
36 _mali_osk_lock_wait( pmm->lock, _MALI_OSK_LOCKMODE_RW )
37 #define MALI_PMM_UNLOCK(pmm) \
38 _mali_osk_lock_signal( pmm->lock, _MALI_OSK_LOCKMODE_RW )
39 #define MALI_PMM_LOCK_TERM(pmm) \
40 _mali_osk_lock_term( pmm->lock )
42 /* Notification type for messages */
43 #define MALI_PMM_NOTIFICATION_TYPE 0
45 /** @brief Status of the PMM state machine
47 typedef enum mali_pmm_status_tag
49 MALI_PMM_STATUS_IDLE, /**< PMM is waiting next event */
50 MALI_PMM_STATUS_POLICY_POWER_DOWN, /**< Policy initiated power down */
51 MALI_PMM_STATUS_POLICY_POWER_UP, /**< Policy initiated power down */
52 MALI_PMM_STATUS_OS_WAITING, /**< PMM is waiting for OS power up */
53 MALI_PMM_STATUS_OS_POWER_DOWN, /**< OS initiated power down */
54 MALI_PMM_STATUS_DVFS_PAUSE, /**< PMM DVFS Status Pause */
55 MALI_PMM_STATUS_OS_POWER_UP, /**< OS initiated power up */
56 MALI_PMM_STATUS_OFF, /**< PMM is not active */
60 /** @brief Internal state of the PMM
62 typedef struct _mali_pmm_internal_state
64 mali_pmm_status status; /**< PMM state machine */
65 mali_pmm_policy policy; /**< PMM policy */
66 mali_bool check_policy; /**< PMM policy needs checking */
67 mali_pmm_state state; /**< PMM state */
68 mali_pmm_core_mask cores_registered; /**< Bitmask of cores registered */
69 mali_pmm_core_mask cores_powered; /**< Bitmask of cores powered up */
70 mali_pmm_core_mask cores_idle; /**< Bitmask of cores idle */
71 mali_pmm_core_mask cores_pend_down; /**< Bitmask of cores pending power down */
72 mali_pmm_core_mask cores_pend_up; /**< Bitmask of cores pending power up */
73 mali_pmm_core_mask cores_ack_down; /**< Bitmask of cores acknowledged power down */
74 mali_pmm_core_mask cores_ack_up; /**< Bitmask of cores acknowledged power up */
76 _mali_osk_notification_queue_t *queue; /**< PMM event queue */
77 _mali_osk_notification_queue_t *iqueue; /**< PMM internal event queue */
78 _mali_osk_irq_t *irq; /**< PMM irq handler */
79 _mali_osk_lock_t *lock; /**< PMM lock */
81 mali_pmm_message_data os_data; /**< OS data sent via the OS events */
83 mali_bool pmu_initialized; /**< PMU initialized */
85 _mali_osk_atomic_t messages_queued; /**< PMM event messages queued */
86 u32 waiting; /**< PMM waiting events - due to busy */
87 u32 no_events; /**< PMM called to process when no events */
89 u32 missed; /**< PMM missed events due to OOM */
90 mali_bool fatal_power_err; /**< PMM has had a fatal power error? */
91 u32 is_dvfs_active; /**< PMM DVFS activity */
93 #if MALI_STATE_TRACKING
94 mali_pmm_status mali_last_pmm_status; /**< The previous PMM status */
95 mali_pmm_event_id mali_new_event_status;/**< The type of the last PMM event */
96 mali_bool mali_pmm_lock_acquired; /**< Is the PMM lock held somewhere or not */
99 #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
100 u32 messages_sent; /**< Total event messages sent */
101 u32 messages_received; /**< Total event messages received */
102 u32 imessages_sent; /**< Total event internal messages sent */
103 u32 imessages_received; /**< Total event internal messages received */
105 } _mali_pmm_internal_state_t;
107 /** @brief Sets that a policy needs a check before processing events
109 * A timer or something has expired that needs dealing with
111 void malipmm_set_policy_check(void);
113 /** @brief Update the PMM externally viewable state depending on the current PMM internal state
115 * @param pmm internal PMM state
116 * @return MALI_TRUE if the timeout is valid, else MALI_FALSE
118 void pmm_update_system_state( _mali_pmm_internal_state_t *pmm );
120 /** @brief Returns the core mask from the event data - if applicable
122 * @param pmm internal PMM state
123 * @param event event message to get the core mask from
124 * @return mask of cores that is relevant to this event message
126 mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event );
128 /** @brief Sort out which cores need to be powered up from the given core mask
130 * All cores that can be powered up will be put into a pending state
132 * @param pmm internal PMM state
133 * @param cores mask of cores to check if they need to be powered up
134 * @return mask of cores that need to be powered up, this can be 0 if all cores
135 * are powered up already
137 mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
139 /** @brief Sort out which cores need to be powered down from the given core mask
141 * All cores that can be powered down will be put into a pending state. If they
142 * can be powered down immediately they will also be acknowledged that they can be
143 * powered down. If the immediate_only flag is set, then only those cores that
144 * can be acknowledged for power down will be put into a pending state.
146 * @param pmm internal PMM state
147 * @param cores mask of cores to check if they need to be powered down
148 * @param immediate_only MALI_TRUE means that only cores that can power down now will
149 * be put into a pending state
150 * @return mask of cores that need to be powered down, this can be 0 if all cores
151 * are powered down already
153 mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only );
155 /** @brief Cancel an invokation to power down (pmm_invoke_power_down)
157 * @param pmm internal PMM state
159 void pmm_power_down_cancel( _mali_pmm_internal_state_t *pmm );
161 /** @brief Check if a call to invoke power down should succeed, or fail
163 * This will report MALI_FALSE if some of the cores are still active and need
164 * to acknowledge that they are ready to power down
166 * @param pmm internal PMM state
167 * @return MALI_TRUE if the pending cores to power down have acknowledged they
168 * can power down, else MALI_FALSE
170 mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm );
172 /** @brief Try to make all the pending cores power down
174 * If all the pending cores have acknowledged they can power down, this will call the
175 * PMU power down function to turn them off
177 * @param pmm internal PMM state
178 * @return MALI_TRUE if the pending cores have been powered down, else MALI_FALSE
180 mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode );
182 /** @brief Check if all the pending cores to power up have done so
184 * This will report MALI_FALSE if some of the cores are still powered off
185 * and have not acknowledged that they have powered up
187 * @param pmm internal PMM state
188 * @return MALI_TRUE if the pending cores to power up have acknowledged they
189 * are now powered up, else MALI_FALSE
191 mali_bool pmm_power_up_okay( _mali_pmm_internal_state_t *pmm );
193 /** @brief Try to make all the pending cores power up
195 * If all the pending cores have acknowledged they have powered up, this will
196 * make the cores start processing jobs again, else this will call the PMU
197 * power up function to turn them on, and the PMM is then expected to wait for an
198 * interrupt to acknowledge the power up
200 * @param pmm internal PMM state
201 * @return MALI_TRUE if the pending cores have been powered up, else MALI_FALSE
203 mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm );
205 /** @brief Set the cores that are now active in the system
207 * Updates which cores are active and returns which cores are still idle
209 * @param pmm internal PMM state
210 * @param cores mask of cores to set to active
211 * @return mask of all the cores that are idle
213 mali_pmm_core_mask pmm_cores_set_active( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
215 /** @brief Set the cores that are now idle in the system
217 * Updates which cores are idle and returns which cores are still idle
219 * @param pmm internal PMM state
220 * @param cores mask of cores to set to idle
221 * @return mask of all the cores that are idle
223 mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
225 /** @brief Set the cores that have acknowledged a pending power down
227 * Updates which cores have acknowledged the pending power down and are now ready
230 * @param pmm internal PMM state
231 * @param cores mask of cores that have acknowledged the pending power down
232 * @return mask of all the cores that have acknowledged the power down
234 mali_pmm_core_mask pmm_cores_set_down_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
236 /** @brief Set the cores that have acknowledged a pending power up
238 * Updates which cores have acknowledged the pending power up and are now
239 * fully powered and ready to run jobs
241 * @param pmm internal PMM state
242 * @param cores mask of cores that have acknowledged the pending power up
243 * @return mask of all the cores that have acknowledged the power up
245 mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
248 /** @brief Tries to reset the PMM and PMU hardware to a known state after any fatal issues
250 * This will try and make all the cores powered up and reset the PMM state
251 * to its initial state after core registration - all cores powered but not
253 * All events in the event queues will be thrown away.
255 * @note: Any pending power down will be cancelled including the OS calling for power down
257 void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm );
259 /** @brief Save the OS specific data for an OS power up/down event
261 * @param pmm internal PMM state
262 * @param data OS specific event data
264 void pmm_save_os_event_data(_mali_pmm_internal_state_t *pmm, mali_pmm_message_data data);
266 /** @brief Retrieve the OS specific data for an OS power up/down event
268 * This will clear the stored OS data, as well as return it.
270 * @param pmm internal PMM state
271 * @return OS specific event data that was saved previously
273 mali_pmm_message_data pmm_retrieve_os_event_data(_mali_pmm_internal_state_t *pmm);
276 /** @brief Get a human readable name for the cores in a core mask
278 * @param core the core mask
279 * @return string containing a name relating to the given core mask
281 const char *pmm_trace_get_core_name( mali_pmm_core_mask core );
283 /** @} */ /* End group pmmapi_state */
284 /** @} */ /* End group pmmapi */
290 #endif /* __MALI_PMM_STATE_H__ */