2 * Copyright (C) 2011-2014 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_GROUP_H__
12 #define __MALI_GROUP_H__
15 #include "mali_l2_cache.h"
19 #include "mali_session.h"
20 #include "mali_osk_profiling.h"
23 * @brief Default max runtime [ms] for a core job - used by timeout timers
25 #define MALI_MAX_JOB_RUNTIME_DEFAULT 5000
27 extern int mali_max_job_runtime;
29 #define MALI_MAX_NUMBER_OF_GROUPS 10
30 #define MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS 8
32 enum mali_group_state {
33 MALI_GROUP_STATE_INACTIVE,
34 MALI_GROUP_STATE_ACTIVATION_PENDING,
35 MALI_GROUP_STATE_ACTIVE,
39 * The structure represents a render group
40 * A render group is defined by all the cores that share the same Mali MMU
44 struct mali_mmu_core *mmu;
45 struct mali_session_data *session;
47 enum mali_group_state state;
48 mali_bool power_is_on;
51 unsigned long start_time; /* in ticks */
53 struct mali_gp_core *gp_core;
54 struct mali_gp_job *gp_running_job;
56 struct mali_pp_core *pp_core;
57 struct mali_pp_job *pp_running_job;
58 u32 pp_running_sub_job;
60 struct mali_pm_domain *pm_domain;
62 struct mali_l2_cache_core *l2_cache_core[2];
63 u32 l2_cache_core_ref_count[2];
65 /* Parent virtual group (if any) */
66 struct mali_group *parent_group;
68 struct mali_dlbu_core *dlbu_core;
69 struct mali_bcast_unit *bcast_core;
71 /* Used for working groups which needs to be disabled */
72 mali_bool disable_requested;
74 /* Used by group to link child groups (for virtual group) */
75 _mali_osk_list_t group_list;
77 /* Used by executor module in order to link groups of same state */
78 _mali_osk_list_t executor_list;
80 /* Used by PM domains to link groups of same domain */
81 _mali_osk_list_t pm_domain_list;
83 _mali_osk_wq_work_t *bottom_half_work_mmu;
84 _mali_osk_wq_work_t *bottom_half_work_gp;
85 _mali_osk_wq_work_t *bottom_half_work_pp;
87 _mali_osk_timer_t *timeout_timer;
90 /** @brief Create a new Mali group object
92 * @return A pointer to a new group object
94 struct mali_group *mali_group_create(struct mali_l2_cache_core *core,
95 struct mali_dlbu_core *dlbu,
96 struct mali_bcast_unit *bcast,
99 void mali_group_delete(struct mali_group *group);
101 _mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group,
102 struct mali_mmu_core *mmu_core);
103 void mali_group_remove_mmu_core(struct mali_group *group);
105 _mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group,
106 struct mali_gp_core *gp_core);
107 void mali_group_remove_gp_core(struct mali_group *group);
109 _mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group,
110 struct mali_pp_core *pp_core);
111 void mali_group_remove_pp_core(struct mali_group *group);
113 MALI_STATIC_INLINE const char *mali_group_core_description(
114 struct mali_group *group)
116 MALI_DEBUG_ASSERT_POINTER(group);
117 if (NULL != group->pp_core) {
118 return mali_pp_core_description(group->pp_core);
120 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
121 return mali_gp_core_description(group->gp_core);
125 MALI_STATIC_INLINE mali_bool mali_group_is_virtual(struct mali_group *group)
127 MALI_DEBUG_ASSERT_POINTER(group);
129 #if defined(CONFIG_MALI450)
130 return (NULL != group->dlbu_core);
136 /** @brief Check if a group is a part of a virtual group or not
138 MALI_STATIC_INLINE mali_bool mali_group_is_in_virtual(struct mali_group *group)
140 MALI_DEBUG_ASSERT_POINTER(group);
141 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
143 #if defined(CONFIG_MALI450)
144 return (NULL != group->parent_group) ? MALI_TRUE : MALI_FALSE;
150 /** @brief Reset group
152 * This function will reset the entire group,
153 * including all the cores present in the group.
155 * @param group Pointer to the group to reset
157 void mali_group_reset(struct mali_group *group);
159 MALI_STATIC_INLINE struct mali_session_data *mali_group_get_session(
160 struct mali_group *group)
162 MALI_DEBUG_ASSERT_POINTER(group);
163 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
165 return group->session;
168 MALI_STATIC_INLINE void mali_group_clear_session(struct mali_group *group)
170 MALI_DEBUG_ASSERT_POINTER(group);
171 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
173 if (NULL != group->session) {
174 mali_mmu_activate_empty_page_directory(group->mmu);
175 group->session = NULL;
179 enum mali_group_state mali_group_activate(struct mali_group *group);
182 * Change state from ACTIVATION_PENDING to ACTIVE
183 * For virtual group, all childs need to be ACTIVE first
185 mali_bool mali_group_set_active(struct mali_group *group);
188 * @return MALI_TRUE means one or more domains can now be powered off,
189 * and caller should call either mali_pm_update_async() or
190 * mali_pm_update_sync() in order to do so.
192 mali_bool mali_group_deactivate(struct mali_group *group);
194 MALI_STATIC_INLINE enum mali_group_state mali_group_get_state(struct mali_group *group)
196 MALI_DEBUG_ASSERT_POINTER(group);
197 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
201 MALI_STATIC_INLINE mali_bool mali_group_power_is_on(struct mali_group *group)
203 MALI_DEBUG_ASSERT_POINTER(group);
204 return group->power_is_on;
207 void mali_group_power_up(struct mali_group *group);
208 void mali_group_power_down(struct mali_group *group);
210 MALI_STATIC_INLINE void mali_group_set_disable_request(
211 struct mali_group *group, mali_bool disable)
213 MALI_DEBUG_ASSERT_POINTER(group);
214 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
215 group->disable_requested = disable;
218 * When one of child group's disable_requeset is set TRUE, then
219 * the disable_request of parent group should also be set to TRUE.
220 * While, the disable_request of parent group should only be set to FALSE
221 * only when all of its child group's disable_request are set to FALSE.
223 if (NULL != group->parent_group && MALI_TRUE == disable) {
224 group->parent_group->disable_requested = disable;
228 MALI_STATIC_INLINE mali_bool mali_group_disable_requested(
229 struct mali_group *group)
231 MALI_DEBUG_ASSERT_POINTER(group);
232 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
233 return group->disable_requested;
236 /** @brief Virtual groups */
237 void mali_group_add_group(struct mali_group *parent, struct mali_group *child);
238 struct mali_group *mali_group_acquire_group(struct mali_group *parent);
239 void mali_group_remove_group(struct mali_group *parent, struct mali_group *child);
241 /** @brief Checks if the group is working.
243 MALI_STATIC_INLINE mali_bool mali_group_is_working(struct mali_group *group)
245 MALI_DEBUG_ASSERT_POINTER(group);
246 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
247 if (mali_group_is_in_virtual(group)) {
248 struct mali_group *tmp_group = mali_executor_get_virtual_group();
249 return tmp_group->is_working;
251 return group->is_working;
254 MALI_STATIC_INLINE struct mali_gp_job *mali_group_get_running_gp_job(struct mali_group *group)
256 MALI_DEBUG_ASSERT_POINTER(group);
257 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
258 return group->gp_running_job;
261 /** @brief Zap MMU TLB on all groups
263 * Zap TLB on group if \a session is active.
265 mali_bool mali_group_zap_session(struct mali_group *group,
266 struct mali_session_data *session);
268 /** @brief Get pointer to GP core object
270 MALI_STATIC_INLINE struct mali_gp_core *mali_group_get_gp_core(struct mali_group *group)
272 MALI_DEBUG_ASSERT_POINTER(group);
273 return group->gp_core;
276 /** @brief Get pointer to PP core object
278 MALI_STATIC_INLINE struct mali_pp_core *mali_group_get_pp_core(struct mali_group *group)
280 MALI_DEBUG_ASSERT_POINTER(group);
281 return group->pp_core;
284 /** @brief Start GP job
286 void mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job);
288 void mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job);
290 /** @brief Start virtual group Job on a virtual group
292 void mali_group_start_job_on_virtual(struct mali_group *group, struct mali_pp_job *job, u32 first_subjob, u32 last_subjob);
295 /** @brief Start a subjob from a particular on a specific PP group
297 void mali_group_start_job_on_group(struct mali_group *group, struct mali_pp_job *job, u32 subjob);
300 /** @brief remove all the unused groups in tmp_unused group list, so that the group is in consistent status.
302 void mali_group_non_dlbu_job_done_virtual(struct mali_group *group);
305 /** @brief Resume GP job that suspended waiting for more heap memory
307 void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr);
309 MALI_STATIC_INLINE enum mali_interrupt_result mali_group_get_interrupt_result_gp(struct mali_group *group)
311 MALI_DEBUG_ASSERT_POINTER(group);
312 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
313 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
314 return mali_gp_get_interrupt_result(group->gp_core);
317 MALI_STATIC_INLINE enum mali_interrupt_result mali_group_get_interrupt_result_pp(struct mali_group *group)
319 MALI_DEBUG_ASSERT_POINTER(group);
320 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
321 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
322 return mali_pp_get_interrupt_result(group->pp_core);
325 MALI_STATIC_INLINE enum mali_interrupt_result mali_group_get_interrupt_result_mmu(struct mali_group *group)
327 MALI_DEBUG_ASSERT_POINTER(group);
328 MALI_DEBUG_ASSERT_POINTER(group->mmu);
329 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
330 return mali_mmu_get_interrupt_result(group->mmu);
333 MALI_STATIC_INLINE mali_bool mali_group_gp_is_active(struct mali_group *group)
335 MALI_DEBUG_ASSERT_POINTER(group);
336 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
337 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
338 return mali_gp_is_active(group->gp_core);
341 MALI_STATIC_INLINE mali_bool mali_group_pp_is_active(struct mali_group *group)
343 MALI_DEBUG_ASSERT_POINTER(group);
344 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
345 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
346 return mali_pp_is_active(group->pp_core);
349 MALI_STATIC_INLINE mali_bool mali_group_has_timed_out(struct mali_group *group)
351 unsigned long time_cost;
352 struct mali_group *tmp_group = group;
354 MALI_DEBUG_ASSERT_POINTER(group);
355 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
357 /* if the group is in virtual need to use virtual_group's start time */
358 if (mali_group_is_in_virtual(group)) {
359 tmp_group = mali_executor_get_virtual_group();
362 time_cost = _mali_osk_time_tickcount() - tmp_group->start_time;
363 if (_mali_osk_time_mstoticks(mali_max_job_runtime) <= time_cost) {
365 * current tick is at or after timeout end time,
366 * so this is a valid timeout
371 * Not a valid timeout. A HW interrupt probably beat
372 * us to it, and the timer wasn't properly deleted
373 * (async deletion used due to atomic context).
379 MALI_STATIC_INLINE void mali_group_mask_all_interrupts_gp(struct mali_group *group)
381 MALI_DEBUG_ASSERT_POINTER(group);
382 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
383 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
384 return mali_gp_mask_all_interrupts(group->gp_core);
387 MALI_STATIC_INLINE void mali_group_mask_all_interrupts_pp(struct mali_group *group)
389 MALI_DEBUG_ASSERT_POINTER(group);
390 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
391 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
392 return mali_pp_mask_all_interrupts(group->pp_core);
395 MALI_STATIC_INLINE void mali_group_enable_interrupts_gp(
396 struct mali_group *group,
397 enum mali_interrupt_result exceptions)
399 MALI_DEBUG_ASSERT_POINTER(group);
400 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
401 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
402 mali_gp_enable_interrupts(group->gp_core, exceptions);
405 MALI_STATIC_INLINE void mali_group_schedule_bottom_half_gp(struct mali_group *group)
407 MALI_DEBUG_ASSERT_POINTER(group);
408 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
409 _mali_osk_wq_schedule_work(group->bottom_half_work_gp);
412 MALI_STATIC_INLINE void mali_group_schedule_bottom_half_pp(struct mali_group *group)
414 MALI_DEBUG_ASSERT_POINTER(group);
415 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
416 _mali_osk_wq_schedule_work(group->bottom_half_work_pp);
419 MALI_STATIC_INLINE void mali_group_schedule_bottom_half_mmu(struct mali_group *group)
421 MALI_DEBUG_ASSERT_POINTER(group);
422 MALI_DEBUG_ASSERT_POINTER(group->mmu);
423 _mali_osk_wq_schedule_work(group->bottom_half_work_mmu);
426 struct mali_pp_job *mali_group_complete_pp(struct mali_group *group, mali_bool success, u32 *sub_job);
428 struct mali_gp_job *mali_group_complete_gp(struct mali_group *group, mali_bool success);
430 #if defined(CONFIG_MALI400_PROFILING)
431 MALI_STATIC_INLINE void mali_group_oom(struct mali_group *group)
433 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND |
434 MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
439 struct mali_group *mali_group_get_glob_group(u32 index);
440 u32 mali_group_get_glob_num_groups(void);
442 u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size);
445 _mali_osk_errcode_t mali_group_upper_half_mmu(void *data);
446 _mali_osk_errcode_t mali_group_upper_half_gp(void *data);
447 _mali_osk_errcode_t mali_group_upper_half_pp(void *data);
449 MALI_STATIC_INLINE mali_bool mali_group_is_empty(struct mali_group *group)
451 MALI_DEBUG_ASSERT_POINTER(group);
452 MALI_DEBUG_ASSERT(mali_group_is_virtual(group));
453 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
454 return _mali_osk_list_empty(&group->group_list);
457 #endif /* __MALI_GROUP_H__ */