tizen 2.4 release
[kernel/linux-3.0.git] / drivers / gpu / arm / mali400 / r4p0_rel0 / common / mali_group.h
1 /*
2  * Copyright (C) 2011-2012 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_GROUP_H__
12 #define __MALI_GROUP_H__
13
14 #include "linux/jiffies.h"
15 #include "mali_osk.h"
16 #include "mali_l2_cache.h"
17 #include "mali_mmu.h"
18 #include "mali_gp.h"
19 #include "mali_pp.h"
20 #include "mali_session.h"
21
22 /**
23  * @brief Default max runtime [ms] for a core job - used by timeout timers
24  */
25 #define MALI_MAX_JOB_RUNTIME_DEFAULT 4000
26
27 /** @brief A mali group object represents a MMU and a PP and/or a GP core.
28  *
29  */
30 #define MALI_MAX_NUMBER_OF_GROUPS 10
31
32 enum mali_group_core_state {
33         MALI_GROUP_STATE_IDLE,
34         MALI_GROUP_STATE_WORKING,
35         MALI_GROUP_STATE_OOM,
36         MALI_GROUP_STATE_IN_VIRTUAL,
37         MALI_GROUP_STATE_JOINING_VIRTUAL,
38         MALI_GROUP_STATE_LEAVING_VIRTUAL,
39         MALI_GROUP_STATE_DISABLED,
40 };
41
42 /* Forward declaration from mali_pm_domain.h */
43 struct mali_pm_domain;
44
45 /**
46  * The structure represents a render group
47  * A render group is defined by all the cores that share the same Mali MMU
48  */
49
50 struct mali_group {
51         struct mali_mmu_core        *mmu;
52         struct mali_session_data    *session;
53
54         mali_bool                   power_is_on;
55         enum mali_group_core_state  state;
56
57         struct mali_gp_core         *gp_core;
58         struct mali_gp_job          *gp_running_job;
59
60         struct mali_pp_core         *pp_core;
61         struct mali_pp_job          *pp_running_job;
62         u32                         pp_running_sub_job;
63
64         struct mali_l2_cache_core   *l2_cache_core[2];
65         u32                         l2_cache_core_ref_count[2];
66
67         struct mali_dlbu_core       *dlbu_core;
68         struct mali_bcast_unit      *bcast_core;
69
70 #ifdef MALI_UPPER_HALF_SCHEDULING
71         _mali_osk_spinlock_irq_t        *lock;
72 #else
73         _mali_osk_spinlock_t            *lock;
74 #endif
75
76         _mali_osk_list_t            pp_scheduler_list;
77
78         /* List used for virtual groups. For a virtual group, the list represents the
79          * head element. */
80         _mali_osk_list_t            group_list;
81
82         struct mali_group           *pm_domain_list;
83         struct mali_pm_domain       *pm_domain;
84
85         /* Parent virtual group (if any) */
86         struct mali_group           *parent_group;
87
88         _mali_osk_wq_work_t         *bottom_half_work_mmu;
89         _mali_osk_wq_work_t         *bottom_half_work_gp;
90         _mali_osk_wq_work_t         *bottom_half_work_pp;
91
92         _mali_osk_timer_t           *timeout_timer;
93         mali_bool                   core_timed_out;
94 };
95
96 /** @brief Create a new Mali group object
97  *
98  * @param cluster Pointer to the cluster to which the group is connected.
99  * @param mmu Pointer to the MMU that defines this group
100  * @return A pointer to a new group object
101  */
102 struct mali_group *mali_group_create(struct mali_l2_cache_core *core,
103                                      struct mali_dlbu_core *dlbu,
104                                      struct mali_bcast_unit *bcast);
105
106 _mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group, struct mali_mmu_core* mmu_core);
107 void mali_group_remove_mmu_core(struct mali_group *group);
108
109 _mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core);
110 void mali_group_remove_gp_core(struct mali_group *group);
111
112 _mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core);
113 void mali_group_remove_pp_core(struct mali_group *group);
114
115 void mali_group_set_pm_domain(struct mali_group *group, struct mali_pm_domain *domain);
116
117 void mali_group_delete(struct mali_group *group);
118
119 /** @brief Virtual groups */
120 void mali_group_add_group(struct mali_group *parent, struct mali_group *child, mali_bool update_hw);
121 void mali_group_remove_group(struct mali_group *parent, struct mali_group *child);
122 struct mali_group *mali_group_acquire_group(struct mali_group *parent);
123
124 MALI_STATIC_INLINE mali_bool mali_group_is_virtual(struct mali_group *group)
125 {
126 #if defined(CONFIG_MALI450)
127         return (NULL != group->dlbu_core);
128 #else
129         return MALI_FALSE;
130 #endif
131 }
132
133 /** @brief Check if a group is considered as part of a virtual group
134  *
135  * @note A group is considered to be "part of" a virtual group also during the transition
136  *       in to / out of the virtual group.
137  */
138 MALI_STATIC_INLINE mali_bool mali_group_is_in_virtual(struct mali_group *group)
139 {
140 #if defined(CONFIG_MALI450)
141         return (MALI_GROUP_STATE_IN_VIRTUAL == group->state ||
142                 MALI_GROUP_STATE_JOINING_VIRTUAL == group->state ||
143                 MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state);
144 #else
145         return MALI_FALSE;
146 #endif
147 }
148
149 /** @brief Reset group
150  *
151  * This function will reset the entire group, including all the cores present in the group.
152  *
153  * @param group Pointer to the group to reset
154  */
155 void mali_group_reset(struct mali_group *group);
156
157 /** @brief Zap MMU TLB on all groups
158  *
159  * Zap TLB on group if \a session is active.
160  */
161 void mali_group_zap_session(struct mali_group* group, struct mali_session_data *session);
162
163 /** @brief Get pointer to GP core object
164  */
165 struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group);
166
167 /** @brief Get pointer to PP core object
168  */
169 struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group);
170
171 /** @brief Lock group object
172  *
173  * Most group functions will lock the group object themselves. The expection is
174  * the group_bottom_half which requires the group to be locked on entry.
175  *
176  * @param group Pointer to group to lock
177  */
178 void mali_group_lock(struct mali_group *group);
179
180 /** @brief Unlock group object
181  *
182  * @param group Pointer to group to unlock
183  */
184 void mali_group_unlock(struct mali_group *group);
185 #ifdef DEBUG
186 void mali_group_assert_locked(struct mali_group *group);
187 #define MALI_ASSERT_GROUP_LOCKED(group) mali_group_assert_locked(group)
188 #else
189 #define MALI_ASSERT_GROUP_LOCKED(group)
190 #endif
191
192 /** @brief Start GP job
193  */
194 void mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job);
195 /** @brief Start fragment of PP job
196  */
197 void mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job);
198
199 /** @brief Resume GP job that suspended waiting for more heap memory
200  */
201 struct mali_gp_job *mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr);
202 /** @brief Abort GP job
203  *
204  * Used to abort suspended OOM jobs when user space failed to allocte more memory.
205  */
206 void mali_group_abort_gp_job(struct mali_group *group, u32 job_id);
207 /** @brief Abort all GP jobs from \a session
208  *
209  * Used on session close when terminating all running and queued jobs from \a session.
210  */
211 void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session);
212
213 mali_bool mali_group_power_is_on(struct mali_group *group);
214 void mali_group_power_on_group(struct mali_group *group);
215 void mali_group_power_off_group(struct mali_group *group, mali_bool power_status);
216 void mali_group_power_on(void);
217
218 /** @brief Prepare group for power off
219  *
220  * Update the group's state and prepare for the group to be powered off.
221  *
222  * If do_power_change is MALI_FALSE group session will be set to NULL so that
223  * no more activity will happen to this group, but the power state flag will be
224  * left unchanged.
225  *
226  * @do_power_change MALI_TRUE if power status is to be updated
227  */
228 void mali_group_power_off(mali_bool do_power_change);
229
230 struct mali_group *mali_group_get_glob_group(u32 index);
231 u32 mali_group_get_glob_num_groups(void);
232
233 u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size);
234
235 /* MMU-related functions */
236 _mali_osk_errcode_t mali_group_upper_half_mmu(void * data);
237
238 /* GP-related functions */
239 _mali_osk_errcode_t mali_group_upper_half_gp(void *data);
240
241 /* PP-related functions */
242 _mali_osk_errcode_t mali_group_upper_half_pp(void *data);
243
244 /** @brief Check if group is enabled
245  *
246  * @param group group to check
247  * @return MALI_TRUE if enabled, MALI_FALSE if not
248  */
249 mali_bool mali_group_is_enabled(struct mali_group *group);
250
251 /** @brief Enable group
252  *
253  * An enabled job is put on the idle scheduler list and can be used to handle jobs.  Does nothing if
254  * group is already enabled.
255  *
256  * @param group group to enable
257  */
258 void mali_group_enable(struct mali_group *group);
259
260 /** @brief Disable group
261  *
262  * A disabled group will no longer be used by the scheduler.  If part of a virtual group, the group
263  * will be removed before being disabled.  Cores part of a disabled group is safe to power down.
264  *
265  * @param group group to disable
266  */
267 void mali_group_disable(struct mali_group *group);
268
269 MALI_STATIC_INLINE mali_bool mali_group_virtual_disable_if_empty(struct mali_group *group)
270 {
271         mali_bool empty = MALI_FALSE;
272
273         MALI_ASSERT_GROUP_LOCKED(group);
274         MALI_DEBUG_ASSERT(mali_group_is_virtual(group));
275
276         if (_mali_osk_list_empty(&group->group_list)) {
277                 group->state = MALI_GROUP_STATE_DISABLED;
278                 group->session = NULL;
279
280                 empty = MALI_TRUE;
281         }
282
283         return empty;
284 }
285
286 MALI_STATIC_INLINE mali_bool mali_group_virtual_enable_if_empty(struct mali_group *group)
287 {
288         mali_bool empty = MALI_FALSE;
289
290         MALI_ASSERT_GROUP_LOCKED(group);
291         MALI_DEBUG_ASSERT(mali_group_is_virtual(group));
292
293         if (_mali_osk_list_empty(&group->group_list)) {
294                 MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
295
296                 group->state = MALI_GROUP_STATE_IDLE;
297
298                 empty = MALI_TRUE;
299         }
300
301         return empty;
302 }
303
304 /* Get group used l2 domain and core domain ref */
305 void mali_group_get_pm_domain_ref(struct mali_group *group);
306 /* Put group used l2 domain and core domain ref */
307 void mali_group_put_pm_domain_ref(struct mali_group *group);
308
309 #endif /* __MALI_GROUP_H__ */