Initial commit
[kernel/linux-3.0.git] / drivers / media / video / samsung / mali_r2p3 / common / pmm / mali_pmm_state.h
1 /*
2  * Copyright (C) 2010 ARM Limited. All rights reserved.
3  * 
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.
6  * 
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.
9  */
10
11 #ifndef __MALI_PMM_STATE_H__
12 #define __MALI_PMM_STATE_H__
13
14 #ifdef __cplusplus
15 extern "C"
16 {
17 #endif
18
19 /**
20  * @addtogroup pmmapi Power Management Module APIs
21  *
22  * @{
23  *
24  * @defgroup pmmapi_state Power Management Module State
25  *
26  * @{
27  */
28
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 )
32
33
34 /* Locking macros */
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 )
41
42 /* Notification type for messages */
43 #define MALI_PMM_NOTIFICATION_TYPE 0
44
45 /** @brief Status of the PMM state machine
46  */
47 typedef enum mali_pmm_status_tag
48 {
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 */
57 } mali_pmm_status;
58
59
60 /** @brief Internal state of the PMM
61  */
62 typedef struct _mali_pmm_internal_state
63 {
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 */
75
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 */
80
81         mali_pmm_message_data os_data;          /**< OS data sent via the OS events */
82
83         mali_bool pmu_initialized;              /**< PMU initialized */
84
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 */
88
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 */
92
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 */
97 #endif
98
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 */
104 #endif
105 } _mali_pmm_internal_state_t;
106
107 /** @brief Sets that a policy needs a check before processing events
108  *
109  * A timer or something has expired that needs dealing with
110  */
111 void malipmm_set_policy_check(void);
112
113 /** @brief Update the PMM externally viewable state depending on the current PMM internal state
114  *
115  * @param pmm internal PMM state
116  * @return MALI_TRUE if the timeout is valid, else MALI_FALSE
117  */
118 void pmm_update_system_state( _mali_pmm_internal_state_t *pmm );
119
120 /** @brief Returns the core mask from the event data - if applicable
121  *
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
125  */
126 mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event );
127
128 /** @brief Sort out which cores need to be powered up from the given core mask
129  *
130  * All cores that can be powered up will be put into a pending state
131  *
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
136  */
137 mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
138
139 /** @brief Sort out which cores need to be powered down from the given core mask
140  *
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.
145  *
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
152  */
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 );
154
155 /** @brief Cancel an invokation to power down (pmm_invoke_power_down)
156  *
157  * @param pmm internal PMM state
158  */
159 void pmm_power_down_cancel( _mali_pmm_internal_state_t *pmm );
160
161 /** @brief Check if a call to invoke power down should succeed, or fail
162  *
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
165  *
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
169  */
170 mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm );
171
172 /** @brief Try to make all the pending cores power down
173  *
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
176  *
177  * @param pmm internal PMM state
178  * @return MALI_TRUE if the pending cores have been powered down, else MALI_FALSE
179  */
180 mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm,  mali_power_mode power_mode );
181
182 /** @brief Check if all the pending cores to power up have done so
183  *
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
186  *
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
190  */
191 mali_bool pmm_power_up_okay( _mali_pmm_internal_state_t *pmm );
192
193 /** @brief Try to make all the pending cores power up
194  *
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
199  *
200  * @param pmm internal PMM state
201  * @return MALI_TRUE if the pending cores have been powered up, else MALI_FALSE
202  */
203 mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm );
204
205 /** @brief Set the cores that are now active in the system
206  *
207  * Updates which cores are active and returns which cores are still idle
208  *
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
212  */
213 mali_pmm_core_mask pmm_cores_set_active( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
214
215 /** @brief Set the cores that are now idle in the system
216  *
217  * Updates which cores are idle and returns which cores are still idle
218  *
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
222  */
223 mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
224
225 /** @brief Set the cores that have acknowledged a pending power down
226  *
227  * Updates which cores have acknowledged the pending power down and are now ready
228  * to be turned off
229  *
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
233  */
234 mali_pmm_core_mask pmm_cores_set_down_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
235
236 /** @brief Set the cores that have acknowledged a pending power up
237  *
238  * Updates which cores have acknowledged the pending power up and are now
239  * fully powered and ready to run jobs
240  *
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
244  */
245 mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
246
247
248 /** @brief Tries to reset the PMM and PMU hardware to a known state after any fatal issues
249  *
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
252  * pending or active.
253  * All events in the event queues will be thrown away.
254  *
255  * @note: Any pending power down will be cancelled including the OS calling for power down
256  */
257 void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm );
258
259 /** @brief Save the OS specific data for an OS power up/down event
260  *
261  * @param pmm internal PMM state
262  * @param data OS specific event data
263  */
264 void pmm_save_os_event_data(_mali_pmm_internal_state_t *pmm, mali_pmm_message_data data);
265
266 /** @brief Retrieve the OS specific data for an OS power up/down event
267  *
268  * This will clear the stored OS data, as well as return it.
269  *
270  * @param pmm internal PMM state
271  * @return OS specific event data that was saved previously
272  */
273 mali_pmm_message_data pmm_retrieve_os_event_data(_mali_pmm_internal_state_t *pmm);
274
275
276 /** @brief Get a human readable name for the cores in a core mask
277  *
278  * @param core the core mask
279  * @return string containing a name relating to the given core mask
280  */
281 const char *pmm_trace_get_core_name( mali_pmm_core_mask core );
282
283 /** @} */ /* End group pmmapi_state */
284 /** @} */ /* End group pmmapi */
285
286 #ifdef __cplusplus
287 }
288 #endif
289
290 #endif /* __MALI_PMM_STATE_H__ */