2 * Copyright (C) 2011-2015 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.
10 #include "mali_kernel_common.h"
11 #include "mali_group.h"
13 #include "mali_l2_cache.h"
17 #include "mali_dlbu.h"
18 #include "mali_broadcast.h"
19 #include "mali_scheduler.h"
20 #include "mali_osk_profiling.h"
21 #include "mali_pm_domain.h"
23 #include "mali_executor.h"
25 #if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
26 #include <linux/sched.h>
27 #include <trace/events/gpu.h>
30 #define MALI_MAX_NUM_DOMAIN_REFS (MALI_MAX_NUMBER_OF_GROUPS * 2)
32 #if defined(CONFIG_MALI400_PROFILING)
33 static void mali_group_report_l2_cache_counters_per_core(struct mali_group *group, u32 core_num);
34 #endif /* #if defined(CONFIG_MALI400_PROFILING) */
36 static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS] = { NULL, };
37 static u32 mali_global_num_groups = 0;
39 /* SW timer for job execution */
40 int mali_max_job_runtime = MALI_MAX_JOB_RUNTIME_DEFAULT;
42 /* local helper functions */
43 static void mali_group_bottom_half_mmu(void *data);
44 static void mali_group_bottom_half_gp(void *data);
45 static void mali_group_bottom_half_pp(void *data);
46 static void mali_group_timeout(void *data);
47 static void mali_group_reset_pp(struct mali_group *group);
48 static void mali_group_reset_mmu(struct mali_group *group);
50 static void mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session);
51 static void mali_group_recovery_reset(struct mali_group *group);
53 struct mali_group *mali_group_create(struct mali_l2_cache_core *core,
54 struct mali_dlbu_core *dlbu,
55 struct mali_bcast_unit *bcast,
58 struct mali_group *group = NULL;
60 if (mali_global_num_groups >= MALI_MAX_NUMBER_OF_GROUPS) {
61 MALI_PRINT_ERROR(("Mali group: Too many group objects created\n"));
65 group = _mali_osk_calloc(1, sizeof(struct mali_group));
67 group->timeout_timer = _mali_osk_timer_init();
68 if (NULL != group->timeout_timer) {
69 _mali_osk_timer_setcallback(group->timeout_timer, mali_group_timeout, (void *)group);
71 group->l2_cache_core[0] = core;
72 _mali_osk_list_init(&group->group_list);
73 _mali_osk_list_init(&group->executor_list);
74 _mali_osk_list_init(&group->pm_domain_list);
75 group->bcast_core = bcast;
76 group->dlbu_core = dlbu;
78 /* register this object as a part of the correct power domain */
79 if ((NULL != core) || (NULL != dlbu) || (NULL != bcast))
80 group->pm_domain = mali_pm_register_group(domain_index, group);
82 mali_global_groups[mali_global_num_groups] = group;
83 mali_global_num_groups++;
87 _mali_osk_free(group);
93 void mali_group_delete(struct mali_group *group)
97 MALI_DEBUG_PRINT(4, ("Deleting group %s\n",
98 mali_group_core_description(group)));
100 MALI_DEBUG_ASSERT(NULL == group->parent_group);
101 MALI_DEBUG_ASSERT((MALI_GROUP_STATE_INACTIVE == group->state) || ((MALI_GROUP_STATE_ACTIVATION_PENDING == group->state)));
103 /* Delete the resources that this group owns */
104 if (NULL != group->gp_core) {
105 mali_gp_delete(group->gp_core);
108 if (NULL != group->pp_core) {
109 mali_pp_delete(group->pp_core);
112 if (NULL != group->mmu) {
113 mali_mmu_delete(group->mmu);
116 if (mali_group_is_virtual(group)) {
117 /* Remove all groups from virtual group */
118 struct mali_group *child;
119 struct mali_group *temp;
121 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list) {
122 child->parent_group = NULL;
123 mali_group_delete(child);
126 mali_dlbu_delete(group->dlbu_core);
128 if (NULL != group->bcast_core) {
129 mali_bcast_unit_delete(group->bcast_core);
133 for (i = 0; i < mali_global_num_groups; i++) {
134 if (mali_global_groups[i] == group) {
135 mali_global_groups[i] = NULL;
136 mali_global_num_groups--;
138 if (i != mali_global_num_groups) {
139 /* We removed a group from the middle of the array -- move the last
140 * group to the current position to close the gap */
141 mali_global_groups[i] = mali_global_groups[mali_global_num_groups];
142 mali_global_groups[mali_global_num_groups] = NULL;
149 if (NULL != group->timeout_timer) {
150 _mali_osk_timer_del(group->timeout_timer);
151 _mali_osk_timer_term(group->timeout_timer);
154 if (NULL != group->bottom_half_work_mmu) {
155 _mali_osk_wq_delete_work(group->bottom_half_work_mmu);
158 if (NULL != group->bottom_half_work_gp) {
159 _mali_osk_wq_delete_work(group->bottom_half_work_gp);
162 if (NULL != group->bottom_half_work_pp) {
163 _mali_osk_wq_delete_work(group->bottom_half_work_pp);
166 _mali_osk_free(group);
169 _mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group, struct mali_mmu_core *mmu_core)
171 /* This group object now owns the MMU core object */
172 group->mmu = mmu_core;
173 group->bottom_half_work_mmu = _mali_osk_wq_create_work(mali_group_bottom_half_mmu, group);
174 if (NULL == group->bottom_half_work_mmu) {
175 return _MALI_OSK_ERR_FAULT;
177 return _MALI_OSK_ERR_OK;
180 void mali_group_remove_mmu_core(struct mali_group *group)
182 /* This group object no longer owns the MMU core object */
184 if (NULL != group->bottom_half_work_mmu) {
185 _mali_osk_wq_delete_work(group->bottom_half_work_mmu);
189 _mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core *gp_core)
191 /* This group object now owns the GP core object */
192 group->gp_core = gp_core;
193 group->bottom_half_work_gp = _mali_osk_wq_create_work(mali_group_bottom_half_gp, group);
194 if (NULL == group->bottom_half_work_gp) {
195 return _MALI_OSK_ERR_FAULT;
198 return _MALI_OSK_ERR_OK;
201 void mali_group_remove_gp_core(struct mali_group *group)
203 /* This group object no longer owns the GP core object */
204 group->gp_core = NULL;
205 if (NULL != group->bottom_half_work_gp) {
206 _mali_osk_wq_delete_work(group->bottom_half_work_gp);
210 _mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core *pp_core)
212 /* This group object now owns the PP core object */
213 group->pp_core = pp_core;
214 group->bottom_half_work_pp = _mali_osk_wq_create_work(mali_group_bottom_half_pp, group);
215 if (NULL == group->bottom_half_work_pp) {
216 return _MALI_OSK_ERR_FAULT;
218 return _MALI_OSK_ERR_OK;
221 void mali_group_remove_pp_core(struct mali_group *group)
223 /* This group object no longer owns the PP core object */
224 group->pp_core = NULL;
225 if (NULL != group->bottom_half_work_pp) {
226 _mali_osk_wq_delete_work(group->bottom_half_work_pp);
230 enum mali_group_state mali_group_activate(struct mali_group *group)
232 MALI_DEBUG_ASSERT_POINTER(group);
233 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
235 MALI_DEBUG_PRINT(4, ("Group: Activating group %s\n",
236 mali_group_core_description(group)));
238 if (MALI_GROUP_STATE_INACTIVE == group->state) {
239 /* Group is inactive, get PM refs in order to power up */
242 * We'll take a maximum of 2 power domain references pr group,
243 * one for the group itself, and one for it's L2 cache.
245 struct mali_pm_domain *domains[MALI_MAX_NUM_DOMAIN_REFS];
246 struct mali_group *groups[MALI_MAX_NUM_DOMAIN_REFS];
248 mali_bool all_groups_on;
250 /* Deal with child groups first */
251 if (mali_group_is_virtual(group)) {
253 * The virtual group might have 0, 1 or 2 L2s in
254 * its l2_cache_core array, but we ignore these and
255 * let the child groups take the needed L2 cache ref
256 * on behalf of the virtual group.
257 * In other words; The L2 refs are taken in pair with
258 * the physical group which the L2 is attached to.
260 struct mali_group *child;
261 struct mali_group *temp;
264 * Child group is inactive, get PM
265 * refs in order to power up.
267 _MALI_OSK_LIST_FOREACHENTRY(child, temp,
269 struct mali_group, group_list) {
270 MALI_DEBUG_ASSERT(MALI_GROUP_STATE_INACTIVE
273 child->state = MALI_GROUP_STATE_ACTIVATION_PENDING;
275 MALI_DEBUG_ASSERT_POINTER(
277 domains[num_domains] = child->pm_domain;
278 groups[num_domains] = child;
282 * Take L2 domain ref for child group.
284 MALI_DEBUG_ASSERT(MALI_MAX_NUM_DOMAIN_REFS
286 domains[num_domains] = mali_l2_cache_get_pm_domain(
287 child->l2_cache_core[0]);
288 groups[num_domains] = NULL;
289 MALI_DEBUG_ASSERT(NULL ==
290 child->l2_cache_core[1]);
294 /* Take L2 domain ref for physical groups. */
295 MALI_DEBUG_ASSERT(MALI_MAX_NUM_DOMAIN_REFS >
298 domains[num_domains] = mali_l2_cache_get_pm_domain(
299 group->l2_cache_core[0]);
300 groups[num_domains] = NULL;
301 MALI_DEBUG_ASSERT(NULL == group->l2_cache_core[1]);
305 /* Do the group itself last (it's dependencies first) */
307 group->state = MALI_GROUP_STATE_ACTIVATION_PENDING;
309 MALI_DEBUG_ASSERT_POINTER(group->pm_domain);
310 domains[num_domains] = group->pm_domain;
311 groups[num_domains] = group;
314 all_groups_on = mali_pm_get_domain_refs(domains, groups,
318 * Complete activation for group, include
319 * virtual group or physical group.
321 if (MALI_TRUE == all_groups_on) {
323 mali_group_set_active(group);
325 } else if (MALI_GROUP_STATE_ACTIVE == group->state) {
327 MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on);
330 * Activation already pending, group->power_is_on could
331 * be both true or false. We need to wait for power up
332 * notification anyway.
334 MALI_DEBUG_ASSERT(MALI_GROUP_STATE_ACTIVATION_PENDING
338 MALI_DEBUG_PRINT(4, ("Group: group %s activation result: %s\n",
339 mali_group_core_description(group),
340 MALI_GROUP_STATE_ACTIVE == group->state ?
341 "ACTIVE" : "PENDING"));
346 mali_bool mali_group_set_active(struct mali_group *group)
348 MALI_DEBUG_ASSERT_POINTER(group);
349 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
350 MALI_DEBUG_ASSERT(MALI_GROUP_STATE_ACTIVATION_PENDING == group->state);
351 MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on);
353 MALI_DEBUG_PRINT(4, ("Group: Activation completed for %s\n",
354 mali_group_core_description(group)));
356 if (mali_group_is_virtual(group)) {
357 struct mali_group *child;
358 struct mali_group *temp;
360 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list,
361 struct mali_group, group_list) {
362 if (MALI_TRUE != child->power_is_on) {
366 child->state = MALI_GROUP_STATE_ACTIVE;
369 mali_group_reset(group);
372 /* Go to ACTIVE state */
373 group->state = MALI_GROUP_STATE_ACTIVE;
378 mali_bool mali_group_deactivate(struct mali_group *group)
380 struct mali_pm_domain *domains[MALI_MAX_NUM_DOMAIN_REFS];
382 mali_bool power_down = MALI_FALSE;
384 MALI_DEBUG_ASSERT_POINTER(group);
385 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
386 MALI_DEBUG_ASSERT(MALI_GROUP_STATE_INACTIVE != group->state);
388 MALI_DEBUG_PRINT(3, ("Group: Deactivating group %s\n",
389 mali_group_core_description(group)));
391 group->state = MALI_GROUP_STATE_INACTIVE;
393 MALI_DEBUG_ASSERT_POINTER(group->pm_domain);
394 domains[num_domains] = group->pm_domain;
397 if (mali_group_is_virtual(group)) {
398 /* Release refs for all child groups */
399 struct mali_group *child;
400 struct mali_group *temp;
402 _MALI_OSK_LIST_FOREACHENTRY(child, temp,
404 struct mali_group, group_list) {
405 child->state = MALI_GROUP_STATE_INACTIVE;
407 MALI_DEBUG_ASSERT_POINTER(child->pm_domain);
408 domains[num_domains] = child->pm_domain;
411 /* Release L2 cache domain for child groups */
412 MALI_DEBUG_ASSERT(MALI_MAX_NUM_DOMAIN_REFS >
414 domains[num_domains] = mali_l2_cache_get_pm_domain(
415 child->l2_cache_core[0]);
416 MALI_DEBUG_ASSERT(NULL == child->l2_cache_core[1]);
421 * Must do mali_group_power_down() steps right here for
422 * virtual group, because virtual group itself is likely to
423 * stay powered on, however child groups are now very likely
424 * to be powered off (and thus lose their state).
427 mali_group_clear_session(group);
429 * Disable the broadcast unit (clear it's mask).
430 * This is needed in case the GPU isn't actually
431 * powered down at this point and groups are
432 * removed from an inactive virtual group.
433 * If not, then the broadcast unit will intercept
436 mali_bcast_disable(group->bcast_core);
438 /* Release L2 cache domain for physical groups */
439 MALI_DEBUG_ASSERT(MALI_MAX_NUM_DOMAIN_REFS >
441 domains[num_domains] = mali_l2_cache_get_pm_domain(
442 group->l2_cache_core[0]);
443 MALI_DEBUG_ASSERT(NULL == group->l2_cache_core[1]);
447 power_down = mali_pm_put_domain_refs(domains, num_domains);
452 void mali_group_power_up(struct mali_group *group)
454 MALI_DEBUG_ASSERT_POINTER(group);
455 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
457 MALI_DEBUG_PRINT(3, ("Group: Power up for %s\n",
458 mali_group_core_description(group)));
460 group->power_is_on = MALI_TRUE;
462 if (MALI_FALSE == mali_group_is_virtual(group)
463 && MALI_FALSE == mali_group_is_in_virtual(group)) {
464 mali_group_reset(group);
468 * When we just acquire only one physical group form virt group,
469 * we should remove the bcast&dlbu mask from virt group and
470 * reset bcast and dlbu core, although part of pp cores in virt
471 * group maybe not be powered on.
473 if (MALI_TRUE == mali_group_is_virtual(group)) {
474 mali_bcast_reset(group->bcast_core);
475 mali_dlbu_update_mask(group->dlbu_core);
479 void mali_group_power_down(struct mali_group *group)
481 MALI_DEBUG_ASSERT_POINTER(group);
482 MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on);
483 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
485 MALI_DEBUG_PRINT(3, ("Group: Power down for %s\n",
486 mali_group_core_description(group)));
488 group->power_is_on = MALI_FALSE;
490 if (mali_group_is_virtual(group)) {
492 * What we do for physical jobs in this function should
493 * already have been done in mali_group_deactivate()
496 MALI_DEBUG_ASSERT(NULL == group->session);
498 mali_group_clear_session(group);
502 MALI_DEBUG_CODE(static void mali_group_print_virtual(struct mali_group *vgroup)
505 struct mali_group *group;
506 struct mali_group *temp;
508 MALI_DEBUG_PRINT(4, ("Virtual group %s (%p)\n",
509 mali_group_core_description(vgroup),
511 MALI_DEBUG_PRINT(4, ("l2_cache_core[0] = %p, ref = %d\n", vgroup->l2_cache_core[0], vgroup->l2_cache_core_ref_count[0]));
512 MALI_DEBUG_PRINT(4, ("l2_cache_core[1] = %p, ref = %d\n", vgroup->l2_cache_core[1], vgroup->l2_cache_core_ref_count[1]));
515 _MALI_OSK_LIST_FOREACHENTRY(group, temp, &vgroup->group_list, struct mali_group, group_list) {
516 MALI_DEBUG_PRINT(4, ("[%d] %s (%p), l2_cache_core[0] = %p\n",
517 i, mali_group_core_description(group),
518 group, group->l2_cache_core[0]));
523 static void mali_group_dump_core_status(struct mali_group *group)
527 MALI_DEBUG_ASSERT_POINTER(group);
528 MALI_DEBUG_ASSERT(NULL != group->gp_core || (NULL != group->pp_core && !mali_group_is_virtual(group)));
530 if (NULL != group->gp_core) {
531 MALI_PRINT(("Dump Group %s\n", group->gp_core->hw_core.description));
533 for (i = 0; i < 0xA8; i += 0x10) {
534 MALI_PRINT(("0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, mali_hw_core_register_read(&group->gp_core->hw_core, i),
535 mali_hw_core_register_read(&group->gp_core->hw_core, i + 4),
536 mali_hw_core_register_read(&group->gp_core->hw_core, i + 8),
537 mali_hw_core_register_read(&group->gp_core->hw_core, i + 12)));
542 MALI_PRINT(("Dump Group %s\n", group->pp_core->hw_core.description));
544 for (i = 0; i < 0x5c; i += 0x10) {
545 MALI_PRINT(("0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, mali_hw_core_register_read(&group->pp_core->hw_core, i),
546 mali_hw_core_register_read(&group->pp_core->hw_core, i + 4),
547 mali_hw_core_register_read(&group->pp_core->hw_core, i + 8),
548 mali_hw_core_register_read(&group->pp_core->hw_core, i + 12)));
551 /* Ignore some minor registers */
552 for (i = 0x1000; i < 0x1068; i += 0x10) {
553 MALI_PRINT(("0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, mali_hw_core_register_read(&group->pp_core->hw_core, i),
554 mali_hw_core_register_read(&group->pp_core->hw_core, i + 4),
555 mali_hw_core_register_read(&group->pp_core->hw_core, i + 8),
556 mali_hw_core_register_read(&group->pp_core->hw_core, i + 12)));
560 MALI_PRINT(("Dump Group MMU\n"));
561 for (i = 0; i < 0x24; i += 0x10) {
562 MALI_PRINT(("0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i, mali_hw_core_register_read(&group->mmu->hw_core, i),
563 mali_hw_core_register_read(&group->mmu->hw_core, i + 4),
564 mali_hw_core_register_read(&group->mmu->hw_core, i + 8),
565 mali_hw_core_register_read(&group->mmu->hw_core, i + 12)));
573 void mali_group_dump_status(struct mali_group *group)
575 MALI_DEBUG_ASSERT_POINTER(group);
577 if (mali_group_is_virtual(group)) {
578 struct mali_group *group_c;
579 struct mali_group *temp;
580 _MALI_OSK_LIST_FOREACHENTRY(group_c, temp, &group->group_list, struct mali_group, group_list) {
581 mali_group_dump_core_status(group_c);
584 mali_group_dump_core_status(group);
589 * @brief Add child group to virtual group parent
591 void mali_group_add_group(struct mali_group *parent, struct mali_group *child)
596 MALI_DEBUG_PRINT(3, ("Adding group %s to virtual group %s\n",
597 mali_group_core_description(child),
598 mali_group_core_description(parent)));
600 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
601 MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
602 MALI_DEBUG_ASSERT(!mali_group_is_virtual(child));
603 MALI_DEBUG_ASSERT(NULL == child->parent_group);
605 _mali_osk_list_addtail(&child->group_list, &parent->group_list);
607 child->parent_group = parent;
609 MALI_DEBUG_ASSERT_POINTER(child->l2_cache_core[0]);
611 MALI_DEBUG_PRINT(4, ("parent->l2_cache_core: [0] = %p, [1] = %p\n", parent->l2_cache_core[0], parent->l2_cache_core[1]));
612 MALI_DEBUG_PRINT(4, ("child->l2_cache_core: [0] = %p, [1] = %p\n", child->l2_cache_core[0], child->l2_cache_core[1]));
614 /* Keep track of the L2 cache cores of child groups */
616 for (i = 0; i < 2; i++) {
617 if (parent->l2_cache_core[i] == child->l2_cache_core[0]) {
618 MALI_DEBUG_ASSERT(parent->l2_cache_core_ref_count[i] > 0);
619 parent->l2_cache_core_ref_count[i]++;
625 /* First time we see this L2 cache, add it to our list */
626 i = (NULL == parent->l2_cache_core[0]) ? 0 : 1;
628 MALI_DEBUG_PRINT(4, ("First time we see l2_cache %p. Adding to [%d] = %p\n", child->l2_cache_core[0], i, parent->l2_cache_core[i]));
630 MALI_DEBUG_ASSERT(NULL == parent->l2_cache_core[i]);
632 parent->l2_cache_core[i] = child->l2_cache_core[0];
633 parent->l2_cache_core_ref_count[i]++;
636 /* Update Broadcast Unit and DLBU */
637 mali_bcast_add_group(parent->bcast_core, child);
638 mali_dlbu_add_group(parent->dlbu_core, child);
640 if (MALI_TRUE == parent->power_is_on) {
641 mali_bcast_reset(parent->bcast_core);
642 mali_dlbu_update_mask(parent->dlbu_core);
645 if (MALI_TRUE == child->power_is_on) {
646 if (NULL == parent->session) {
647 if (NULL != child->session) {
649 * Parent has no session, so clear
650 * child session as well.
652 mali_mmu_activate_empty_page_directory(child->mmu);
655 if (parent->session == child->session) {
656 /* We already have same session as parent,
657 * so a simple zap should be enough.
659 mali_mmu_zap_tlb(child->mmu);
662 * Parent has a different session, so we must
663 * switch to that sessions page table
665 mali_mmu_activate_page_directory(child->mmu, mali_session_get_page_directory(parent->session));
668 /* It is the parent which keeps the session from now on */
669 child->session = NULL;
672 /* should have been cleared when child was powered down */
673 MALI_DEBUG_ASSERT(NULL == child->session);
676 /* Start job on child when parent is active */
677 if (NULL != parent->pp_running_job) {
678 struct mali_pp_job *job = parent->pp_running_job;
680 MALI_DEBUG_PRINT(3, ("Group %x joining running job %d on virtual group %x\n",
681 child, mali_pp_job_get_id(job), parent));
683 /* Only allowed to add active child to an active parent */
684 MALI_DEBUG_ASSERT(MALI_GROUP_STATE_ACTIVE == parent->state);
685 MALI_DEBUG_ASSERT(MALI_GROUP_STATE_ACTIVE == child->state);
687 mali_pp_job_start(child->pp_core, job, mali_pp_core_get_id(child->pp_core), MALI_TRUE);
689 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
690 MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core)) |
691 MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
692 mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
694 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
695 MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core)) |
696 MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
697 mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
698 #if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
699 if (child->pp_core) {
700 trace_gpu_sched_switch(
701 mali_pp_core_description(child->pp_core),
702 sched_clock(), mali_pp_job_get_tid(job),
703 0, mali_pp_job_get_id(job));
707 #if defined(CONFIG_MALI400_PROFILING)
708 trace_mali_core_active(mali_pp_job_get_pid(job), 1 /* active */, 0 /* PP */, mali_pp_core_get_id(child->pp_core),
709 mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job));
713 MALI_DEBUG_CODE(mali_group_print_virtual(parent);)
717 * @brief Remove child group from virtual group parent
719 void mali_group_remove_group(struct mali_group *parent, struct mali_group *child)
723 MALI_DEBUG_PRINT(3, ("Removing group %s from virtual group %s\n",
724 mali_group_core_description(child),
725 mali_group_core_description(parent)));
727 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
728 MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
729 MALI_DEBUG_ASSERT(!mali_group_is_virtual(child));
730 MALI_DEBUG_ASSERT(parent == child->parent_group);
732 /* Update Broadcast Unit and DLBU */
733 mali_bcast_remove_group(parent->bcast_core, child);
734 mali_dlbu_remove_group(parent->dlbu_core, child);
736 if (MALI_TRUE == parent->power_is_on) {
737 mali_bcast_reset(parent->bcast_core);
738 mali_dlbu_update_mask(parent->dlbu_core);
741 child->session = parent->session;
742 child->parent_group = NULL;
744 _mali_osk_list_delinit(&child->group_list);
745 if (_mali_osk_list_empty(&parent->group_list)) {
746 parent->session = NULL;
749 /* Keep track of the L2 cache cores of child groups */
750 i = (child->l2_cache_core[0] == parent->l2_cache_core[0]) ? 0 : 1;
752 MALI_DEBUG_ASSERT(child->l2_cache_core[0] == parent->l2_cache_core[i]);
754 parent->l2_cache_core_ref_count[i]--;
755 if (parent->l2_cache_core_ref_count[i] == 0) {
756 parent->l2_cache_core[i] = NULL;
759 MALI_DEBUG_CODE(mali_group_print_virtual(parent));
762 struct mali_group *mali_group_acquire_group(struct mali_group *parent)
764 struct mali_group *child = NULL;
766 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
767 MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
769 if (!_mali_osk_list_empty(&parent->group_list)) {
770 child = _MALI_OSK_LIST_ENTRY(parent->group_list.prev, struct mali_group, group_list);
771 mali_group_remove_group(parent, child);
775 if (MALI_GROUP_STATE_ACTIVE != parent->state
776 && MALI_TRUE == child->power_is_on) {
777 mali_group_reset(child);
784 void mali_group_reset(struct mali_group *group)
786 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
787 MALI_DEBUG_ASSERT(NULL == group->gp_running_job);
788 MALI_DEBUG_ASSERT(NULL == group->pp_running_job);
789 MALI_DEBUG_ASSERT(NULL == group->session);
791 MALI_DEBUG_PRINT(3, ("Group: reset of %s\n",
792 mali_group_core_description(group)));
794 if (NULL != group->dlbu_core) {
795 mali_dlbu_reset(group->dlbu_core);
798 if (NULL != group->bcast_core) {
799 mali_bcast_reset(group->bcast_core);
802 MALI_DEBUG_ASSERT(NULL != group->mmu);
803 mali_group_reset_mmu(group);
805 if (NULL != group->gp_core) {
806 MALI_DEBUG_ASSERT(NULL == group->pp_core);
807 mali_gp_reset(group->gp_core);
809 MALI_DEBUG_ASSERT(NULL != group->pp_core);
810 mali_group_reset_pp(group);
814 void mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job)
816 struct mali_session_data *session;
818 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
820 MALI_DEBUG_PRINT(3, ("Group: Starting GP job 0x%08X on group %s\n",
822 mali_group_core_description(group)));
824 session = mali_gp_job_get_session(job);
826 MALI_DEBUG_ASSERT_POINTER(group->l2_cache_core[0]);
827 mali_l2_cache_invalidate_conditional(group->l2_cache_core[0], mali_gp_job_get_cache_order(job));
829 mali_group_activate_page_directory(group, session);
831 mali_gp_job_start(group->gp_core, job);
833 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
834 MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) |
835 MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
836 mali_gp_job_get_frame_builder_id(job), mali_gp_job_get_flush_id(job), 0, 0, 0);
837 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
838 MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
839 mali_gp_job_get_pid(job), mali_gp_job_get_tid(job), 0, 0, 0);
841 #if defined(CONFIG_MALI400_PROFILING)
842 trace_mali_core_active(mali_gp_job_get_pid(job), 1 /* active */, 1 /* GP */, 0 /* core */,
843 mali_gp_job_get_frame_builder_id(job), mali_gp_job_get_flush_id(job));
846 #if defined(CONFIG_MALI400_PROFILING)
847 if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
848 (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0]))) {
849 mali_group_report_l2_cache_counters_per_core(group, 0);
851 #endif /* #if defined(CONFIG_MALI400_PROFILING) */
853 #if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
854 if (group->gp_core) {
855 trace_gpu_sched_switch(mali_gp_core_description(group->gp_core),
856 sched_clock(), mali_gp_job_get_tid(job),
857 0, mali_gp_job_get_id(job));
861 group->gp_running_job = job;
862 group->is_working = MALI_TRUE;
864 /* Setup SW timer and record start time */
865 group->start_time = _mali_osk_time_tickcount();
866 _mali_osk_timer_mod(group->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
868 MALI_DEBUG_PRINT(4, ("Group: Started GP job 0x%08X on group %s at %u\n",
870 mali_group_core_description(group),
874 /* Used to set all the registers except frame renderer list address and fragment shader stack address
875 * It means the caller must set these two registers properly before calling this function
877 void mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job)
879 struct mali_session_data *session;
881 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
883 MALI_DEBUG_PRINT(3, ("Group: Starting PP job 0x%08X part %u/%u on group %s\n",
885 mali_pp_job_get_sub_job_count(job),
886 mali_group_core_description(group)));
888 session = mali_pp_job_get_session(job);
890 if (NULL != group->l2_cache_core[0]) {
891 mali_l2_cache_invalidate_conditional(group->l2_cache_core[0], mali_pp_job_get_cache_order(job));
894 if (NULL != group->l2_cache_core[1]) {
895 mali_l2_cache_invalidate_conditional(group->l2_cache_core[1], mali_pp_job_get_cache_order(job));
898 mali_group_activate_page_directory(group, session);
900 if (mali_group_is_virtual(group)) {
901 struct mali_group *child;
902 struct mali_group *temp;
905 MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job));
907 /* Configure DLBU for the job */
908 mali_dlbu_config_job(group->dlbu_core, job);
910 /* Write stack address for each child group */
911 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list) {
912 mali_pp_write_addr_stack(child->pp_core, job);
916 mali_pp_job_start(group->pp_core, job, sub_job, MALI_FALSE);
918 mali_pp_job_start(group->pp_core, job, sub_job, MALI_FALSE);
921 /* if the group is virtual, loop through physical groups which belong to this group
922 * and call profiling events for its cores as virtual */
923 if (MALI_TRUE == mali_group_is_virtual(group)) {
924 struct mali_group *child;
925 struct mali_group *temp;
927 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list) {
928 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
929 MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core)) |
930 MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
931 mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
933 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
934 MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core)) |
935 MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
936 mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
938 #if defined(CONFIG_MALI400_PROFILING)
939 trace_mali_core_active(mali_pp_job_get_pid(job), 1 /* active */, 0 /* PP */, mali_pp_core_get_id(child->pp_core),
940 mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job));
944 #if defined(CONFIG_MALI400_PROFILING)
945 if (0 != group->l2_cache_core_ref_count[0]) {
946 if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
947 (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0]))) {
948 mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
951 if (0 != group->l2_cache_core_ref_count[1]) {
952 if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[1])) &&
953 (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[1]))) {
954 mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[1]));
957 #endif /* #if defined(CONFIG_MALI400_PROFILING) */
959 } else { /* group is physical - call profiling events for physical cores */
960 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
961 MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core)) |
962 MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
963 mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
965 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
966 MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core)) |
967 MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL,
968 mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
970 #if defined(CONFIG_MALI400_PROFILING)
971 trace_mali_core_active(mali_pp_job_get_pid(job), 1 /* active */, 0 /* PP */, mali_pp_core_get_id(group->pp_core),
972 mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job));
975 #if defined(CONFIG_MALI400_PROFILING)
976 if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
977 (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0]))) {
978 mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
980 #endif /* #if defined(CONFIG_MALI400_PROFILING) */
983 #if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
984 if (group->pp_core) {
985 trace_gpu_sched_switch(mali_pp_core_description(group->pp_core),
986 sched_clock(), mali_pp_job_get_tid(job),
987 0, mali_pp_job_get_id(job));
991 group->pp_running_job = job;
992 group->pp_running_sub_job = sub_job;
993 group->is_working = MALI_TRUE;
995 /* Setup SW timer and record start time */
996 group->start_time = _mali_osk_time_tickcount();
997 _mali_osk_timer_mod(group->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
999 MALI_DEBUG_PRINT(4, ("Group: Started PP job 0x%08X part %u/%u on group %s at %u\n",
1001 mali_pp_job_get_sub_job_count(job),
1002 mali_group_core_description(group),
1003 group->start_time));
1007 void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr)
1009 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1011 MALI_DEBUG_ASSERT_POINTER(group->l2_cache_core[0]);
1012 mali_l2_cache_invalidate(group->l2_cache_core[0]);
1014 mali_mmu_zap_tlb_without_stall(group->mmu);
1016 mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr);
1018 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME |
1019 MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
1022 #if defined(CONFIG_MALI400_PROFILING)
1023 trace_mali_core_active(mali_gp_job_get_pid(group->gp_running_job), 1 /* active */, 1 /* GP */, 0 /* core */,
1024 mali_gp_job_get_frame_builder_id(group->gp_running_job), mali_gp_job_get_flush_id(group->gp_running_job));
1028 static void mali_group_reset_mmu(struct mali_group *group)
1030 struct mali_group *child;
1031 struct mali_group *temp;
1032 _mali_osk_errcode_t err;
1034 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1036 if (!mali_group_is_virtual(group)) {
1037 /* This is a physical group or an idle virtual group -- simply wait for
1038 * the reset to complete. */
1039 err = mali_mmu_reset(group->mmu);
1040 MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
1041 } else { /* virtual group */
1042 /* Loop through all members of this virtual group and wait
1043 * until they are done resetting.
1045 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list) {
1046 err = mali_mmu_reset(child->mmu);
1047 MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
1052 static void mali_group_reset_pp(struct mali_group *group)
1054 struct mali_group *child;
1055 struct mali_group *temp;
1057 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1059 mali_pp_reset_async(group->pp_core);
1061 if (!mali_group_is_virtual(group) || NULL == group->pp_running_job) {
1062 /* This is a physical group or an idle virtual group -- simply wait for
1063 * the reset to complete. */
1064 mali_pp_reset_wait(group->pp_core);
1066 /* Loop through all members of this virtual group and wait until they
1067 * are done resetting.
1069 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list) {
1070 mali_pp_reset_wait(child->pp_core);
1075 struct mali_pp_job *mali_group_complete_pp(struct mali_group *group, mali_bool success, u32 *sub_job)
1077 struct mali_pp_job *pp_job_to_return;
1079 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1080 MALI_DEBUG_ASSERT_POINTER(group);
1081 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
1082 MALI_DEBUG_ASSERT_POINTER(group->pp_running_job);
1083 MALI_DEBUG_ASSERT_POINTER(sub_job);
1084 MALI_DEBUG_ASSERT(MALI_TRUE == group->is_working);
1086 /* Stop/clear the timeout timer. */
1087 _mali_osk_timer_del_async(group->timeout_timer);
1089 if (NULL != group->pp_running_job) {
1091 /* Deal with HW counters and profiling */
1093 if (MALI_TRUE == mali_group_is_virtual(group)) {
1094 struct mali_group *child;
1095 struct mali_group *temp;
1097 /* update performance counters from each physical pp core within this virtual group */
1098 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list) {
1099 mali_pp_update_performance_counters(group->pp_core, child->pp_core, group->pp_running_job, mali_pp_core_get_id(child->pp_core));
1102 #if defined(CONFIG_MALI400_PROFILING)
1103 /* send profiling data per physical core */
1104 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list) {
1105 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1106 MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core)) |
1107 MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
1108 mali_pp_job_get_perf_counter_value0(group->pp_running_job, mali_pp_core_get_id(child->pp_core)),
1109 mali_pp_job_get_perf_counter_value1(group->pp_running_job, mali_pp_core_get_id(child->pp_core)),
1110 mali_pp_job_get_perf_counter_src0(group->pp_running_job, group->pp_running_sub_job) | (mali_pp_job_get_perf_counter_src1(group->pp_running_job, group->pp_running_sub_job) << 8),
1113 trace_mali_core_active(mali_pp_job_get_pid(group->pp_running_job),
1114 0 /* active */, 0 /* PP */, mali_pp_core_get_id(child->pp_core),
1115 mali_pp_job_get_frame_builder_id(group->pp_running_job),
1116 mali_pp_job_get_flush_id(group->pp_running_job));
1118 if (0 != group->l2_cache_core_ref_count[0]) {
1119 if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
1120 (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0]))) {
1121 mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
1124 if (0 != group->l2_cache_core_ref_count[1]) {
1125 if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[1])) &&
1126 (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[1]))) {
1127 mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[1]));
1133 /* update performance counters for a physical group's pp core */
1134 mali_pp_update_performance_counters(group->pp_core, group->pp_core, group->pp_running_job, group->pp_running_sub_job);
1136 #if defined(CONFIG_MALI400_PROFILING)
1137 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1138 MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core)) |
1139 MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL,
1140 mali_pp_job_get_perf_counter_value0(group->pp_running_job, group->pp_running_sub_job),
1141 mali_pp_job_get_perf_counter_value1(group->pp_running_job, group->pp_running_sub_job),
1142 mali_pp_job_get_perf_counter_src0(group->pp_running_job, group->pp_running_sub_job) | (mali_pp_job_get_perf_counter_src1(group->pp_running_job, group->pp_running_sub_job) << 8),
1145 trace_mali_core_active(mali_pp_job_get_pid(group->pp_running_job),
1146 0 /* active */, 0 /* PP */, mali_pp_core_get_id(group->pp_core),
1147 mali_pp_job_get_frame_builder_id(group->pp_running_job),
1148 mali_pp_job_get_flush_id(group->pp_running_job));
1150 if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
1151 (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0]))) {
1152 mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
1157 #if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
1158 if (group->gp_core) {
1159 trace_gpu_sched_switch(
1160 mali_gp_core_description(group->gp_core),
1161 sched_clock(), 0, 0, 0);
1168 /* Only do soft reset for successful jobs, a full recovery
1169 * reset will be done for failed jobs. */
1170 mali_pp_reset_async(group->pp_core);
1173 pp_job_to_return = group->pp_running_job;
1174 group->pp_running_job = NULL;
1175 group->is_working = MALI_FALSE;
1176 *sub_job = group->pp_running_sub_job;
1179 MALI_DEBUG_PRINT(2, ("Mali group: Executing recovery reset due to job failure\n"));
1180 mali_group_recovery_reset(group);
1181 } else if (_MALI_OSK_ERR_OK != mali_pp_reset_wait(group->pp_core)) {
1182 MALI_PRINT_ERROR(("Mali group: Executing recovery reset due to reset failure\n"));
1183 mali_group_recovery_reset(group);
1186 return pp_job_to_return;
1189 struct mali_gp_job *mali_group_complete_gp(struct mali_group *group, mali_bool success)
1191 struct mali_gp_job *gp_job_to_return;
1193 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1194 MALI_DEBUG_ASSERT_POINTER(group);
1195 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
1196 MALI_DEBUG_ASSERT_POINTER(group->gp_running_job);
1197 MALI_DEBUG_ASSERT(MALI_TRUE == group->is_working);
1199 /* Stop/clear the timeout timer. */
1200 _mali_osk_timer_del_async(group->timeout_timer);
1202 if (NULL != group->gp_running_job) {
1203 mali_gp_update_performance_counters(group->gp_core, group->gp_running_job);
1205 #if defined(CONFIG_MALI400_PROFILING)
1206 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
1207 mali_gp_job_get_perf_counter_value0(group->gp_running_job),
1208 mali_gp_job_get_perf_counter_value1(group->gp_running_job),
1209 mali_gp_job_get_perf_counter_src0(group->gp_running_job) | (mali_gp_job_get_perf_counter_src1(group->gp_running_job) << 8),
1212 if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
1213 (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
1214 mali_group_report_l2_cache_counters_per_core(group, 0);
1217 #if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
1218 if (group->pp_core) {
1219 trace_gpu_sched_switch(
1220 mali_pp_core_description(group->pp_core),
1221 sched_clock(), 0, 0, 0);
1225 #if defined(CONFIG_MALI400_PROFILING)
1226 trace_mali_core_active(mali_gp_job_get_pid(group->gp_running_job), 0 /* active */, 1 /* GP */, 0 /* core */,
1227 mali_gp_job_get_frame_builder_id(group->gp_running_job), mali_gp_job_get_flush_id(group->gp_running_job));
1230 mali_gp_job_set_current_heap_addr(group->gp_running_job,
1231 mali_gp_read_plbu_alloc_start_addr(group->gp_core));
1235 /* Only do soft reset for successful jobs, a full recovery
1236 * reset will be done for failed jobs. */
1237 mali_gp_reset_async(group->gp_core);
1240 gp_job_to_return = group->gp_running_job;
1241 group->gp_running_job = NULL;
1242 group->is_working = MALI_FALSE;
1245 MALI_DEBUG_PRINT(2, ("Mali group: Executing recovery reset due to job failure\n"));
1246 mali_group_recovery_reset(group);
1247 } else if (_MALI_OSK_ERR_OK != mali_gp_reset_wait(group->gp_core)) {
1248 MALI_PRINT_ERROR(("Mali group: Executing recovery reset due to reset failure\n"));
1249 mali_group_recovery_reset(group);
1252 return gp_job_to_return;
1255 struct mali_group *mali_group_get_glob_group(u32 index)
1257 if (mali_global_num_groups > index) {
1258 return mali_global_groups[index];
1264 u32 mali_group_get_glob_num_groups(void)
1266 return mali_global_num_groups;
1269 static void mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session)
1271 MALI_DEBUG_PRINT(5, ("Mali group: Activating page directory 0x%08X from session 0x%08X on group %s\n",
1272 mali_session_get_page_directory(session), session,
1273 mali_group_core_description(group)));
1275 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1277 if (group->session != session) {
1278 /* Different session than last time, so we need to do some work */
1279 MALI_DEBUG_PRINT(5, ("Mali group: Activate session: %08x previous: %08x on group %s\n",
1280 session, group->session,
1281 mali_group_core_description(group)));
1282 mali_mmu_activate_page_directory(group->mmu, mali_session_get_page_directory(session));
1283 group->session = session;
1285 /* Same session as last time, so no work required */
1286 MALI_DEBUG_PRINT(4, ("Mali group: Activate existing session 0x%08X on group %s\n",
1287 session->page_directory,
1288 mali_group_core_description(group)));
1289 mali_mmu_zap_tlb_without_stall(group->mmu);
1293 static void mali_group_recovery_reset(struct mali_group *group)
1295 _mali_osk_errcode_t err;
1297 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1299 /* Stop cores, bus stop */
1300 if (NULL != group->pp_core) {
1301 mali_pp_stop_bus(group->pp_core);
1303 mali_gp_stop_bus(group->gp_core);
1306 /* Flush MMU and clear page fault (if any) */
1307 mali_mmu_activate_fault_flush_page_directory(group->mmu);
1308 mali_mmu_page_fault_done(group->mmu);
1310 /* Wait for cores to stop bus, then do a hard reset on them */
1311 if (NULL != group->pp_core) {
1312 if (mali_group_is_virtual(group)) {
1313 struct mali_group *child, *temp;
1315 /* Disable the broadcast unit while we do reset directly on the member cores. */
1316 mali_bcast_disable(group->bcast_core);
1318 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list) {
1319 mali_pp_stop_bus_wait(child->pp_core);
1320 mali_pp_hard_reset(child->pp_core);
1323 mali_bcast_enable(group->bcast_core);
1325 mali_pp_stop_bus_wait(group->pp_core);
1326 mali_pp_hard_reset(group->pp_core);
1329 mali_gp_stop_bus_wait(group->gp_core);
1330 mali_gp_hard_reset(group->gp_core);
1334 err = mali_mmu_reset(group->mmu);
1335 MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
1338 group->session = NULL;
1341 #if MALI_STATE_TRACKING
1342 u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size)
1346 struct mali_group *child;
1347 struct mali_group *temp;
1349 if (mali_group_is_virtual(group)) {
1350 n += _mali_osk_snprintf(buf + n, size - n,
1351 "Virtual PP Group: %p\n", group);
1352 } else if (mali_group_is_in_virtual(group)) {
1353 n += _mali_osk_snprintf(buf + n, size - n,
1354 "Child PP Group: %p\n", group);
1355 } else if (NULL != group->pp_core) {
1356 n += _mali_osk_snprintf(buf + n, size - n,
1357 "Physical PP Group: %p\n", group);
1359 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
1360 n += _mali_osk_snprintf(buf + n, size - n,
1361 "GP Group: %p\n", group);
1364 switch (group->state) {
1365 case MALI_GROUP_STATE_INACTIVE:
1366 n += _mali_osk_snprintf(buf + n, size - n,
1367 "\tstate: INACTIVE\n");
1369 case MALI_GROUP_STATE_ACTIVATION_PENDING:
1370 n += _mali_osk_snprintf(buf + n, size - n,
1371 "\tstate: ACTIVATION_PENDING\n");
1373 case MALI_GROUP_STATE_ACTIVE:
1374 n += _mali_osk_snprintf(buf + n, size - n,
1375 "\tstate: MALI_GROUP_STATE_ACTIVE\n");
1378 n += _mali_osk_snprintf(buf + n, size - n,
1379 "\tstate: UNKNOWN (%d)\n", group->state);
1380 MALI_DEBUG_ASSERT(0);
1384 n += _mali_osk_snprintf(buf + n, size - n,
1386 group->power_is_on ? "On" : "Off");
1388 n += mali_pm_dump_state_domain(group->pm_domain, buf + n, size - n);
1390 for (i = 0; i < 2; i++) {
1391 if (NULL != group->l2_cache_core[i]) {
1392 struct mali_pm_domain *domain;
1393 domain = mali_l2_cache_get_pm_domain(
1394 group->l2_cache_core[i]);
1395 n += mali_pm_dump_state_domain(domain,
1400 if (group->gp_core) {
1401 n += mali_gp_dump_state(group->gp_core, buf + n, size - n);
1402 n += _mali_osk_snprintf(buf + n, size - n,
1403 "\tGP running job: %p\n", group->gp_running_job);
1406 if (group->pp_core) {
1407 n += mali_pp_dump_state(group->pp_core, buf + n, size - n);
1408 n += _mali_osk_snprintf(buf + n, size - n,
1409 "\tPP running job: %p, subjob %d \n",
1410 group->pp_running_job,
1411 group->pp_running_sub_job);
1414 _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list,
1415 struct mali_group, group_list) {
1416 n += mali_group_dump_state(child, buf + n, size - n);
1423 _mali_osk_errcode_t mali_group_upper_half_mmu(void *data)
1425 struct mali_group *group = (struct mali_group *)data;
1426 _mali_osk_errcode_t ret;
1428 MALI_DEBUG_ASSERT_POINTER(group);
1429 MALI_DEBUG_ASSERT_POINTER(group->mmu);
1431 #if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
1432 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1433 mali_executor_lock();
1434 if (!mali_group_is_working(group)) {
1435 /* Not working, so nothing to do */
1436 mali_executor_unlock();
1437 return _MALI_OSK_ERR_FAULT;
1440 if (NULL != group->gp_core) {
1441 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
1442 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1443 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1444 0, 0, /* No pid and tid for interrupt handler */
1445 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP_MMU(0),
1446 mali_mmu_get_rawstat(group->mmu), 0);
1448 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
1449 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
1450 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1451 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1452 0, 0, /* No pid and tid for interrupt handler */
1453 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP_MMU(
1454 mali_pp_core_get_id(group->pp_core)),
1455 mali_mmu_get_rawstat(group->mmu), 0);
1457 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1458 mali_executor_unlock();
1462 ret = mali_executor_interrupt_mmu(group, MALI_TRUE);
1464 #if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
1465 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1466 mali_executor_lock();
1467 if (!mali_group_is_working(group) && (!mali_group_power_is_on(group))) {
1468 /* group complete and on job shedule on it, it already power off */
1469 if (NULL != group->gp_core) {
1470 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1471 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1472 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1473 0, 0, /* No pid and tid for interrupt handler */
1474 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP_MMU(0),
1477 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1478 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1479 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1480 0, 0, /* No pid and tid for interrupt handler */
1481 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP_MMU(
1482 mali_pp_core_get_id(group->pp_core)),
1486 mali_executor_unlock();
1491 if (NULL != group->gp_core) {
1492 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1493 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1494 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1495 0, 0, /* No pid and tid for interrupt handler */
1496 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP_MMU(0),
1497 mali_mmu_get_rawstat(group->mmu), 0);
1499 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1500 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1501 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1502 0, 0, /* No pid and tid for interrupt handler */
1503 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP_MMU(
1504 mali_pp_core_get_id(group->pp_core)),
1505 mali_mmu_get_rawstat(group->mmu), 0);
1507 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1508 mali_executor_unlock();
1515 static void mali_group_bottom_half_mmu(void *data)
1517 struct mali_group *group = (struct mali_group *)data;
1519 MALI_DEBUG_ASSERT_POINTER(group);
1520 MALI_DEBUG_ASSERT_POINTER(group->mmu);
1522 if (NULL != group->gp_core) {
1523 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
1524 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1525 MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
1526 0, _mali_osk_get_tid(), /* pid and tid */
1527 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP_MMU(0),
1528 mali_mmu_get_rawstat(group->mmu), 0);
1530 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
1531 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
1532 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1533 MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
1534 0, _mali_osk_get_tid(), /* pid and tid */
1535 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP_MMU(
1536 mali_pp_core_get_id(group->pp_core)),
1537 mali_mmu_get_rawstat(group->mmu), 0);
1540 mali_executor_interrupt_mmu(group, MALI_FALSE);
1542 if (NULL != group->gp_core) {
1543 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1544 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1545 MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
1546 0, _mali_osk_get_tid(), /* pid and tid */
1547 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP_MMU(0),
1548 mali_mmu_get_rawstat(group->mmu), 0);
1550 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1551 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1552 MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
1553 0, _mali_osk_get_tid(), /* pid and tid */
1554 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP_MMU(
1555 mali_pp_core_get_id(group->pp_core)),
1556 mali_mmu_get_rawstat(group->mmu), 0);
1560 _mali_osk_errcode_t mali_group_upper_half_gp(void *data)
1562 struct mali_group *group = (struct mali_group *)data;
1563 _mali_osk_errcode_t ret;
1565 MALI_DEBUG_ASSERT_POINTER(group);
1566 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
1567 MALI_DEBUG_ASSERT_POINTER(group->mmu);
1569 #if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
1570 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1571 mali_executor_lock();
1572 if (!mali_group_is_working(group)) {
1573 /* Not working, so nothing to do */
1574 mali_executor_unlock();
1575 return _MALI_OSK_ERR_FAULT;
1578 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
1579 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1580 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1581 0, 0, /* No pid and tid for interrupt handler */
1582 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0),
1583 mali_gp_get_rawstat(group->gp_core), 0);
1585 MALI_DEBUG_PRINT(4, ("Group: Interrupt 0x%08X from %s\n",
1586 mali_gp_get_rawstat(group->gp_core),
1587 mali_group_core_description(group)));
1588 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1589 mali_executor_unlock();
1592 ret = mali_executor_interrupt_gp(group, MALI_TRUE);
1594 #if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
1595 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1596 mali_executor_lock();
1597 if (!mali_group_is_working(group) && (!mali_group_power_is_on(group))) {
1598 /* group complete and on job shedule on it, it already power off */
1599 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1600 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1601 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1602 0, 0, /* No pid and tid for interrupt handler */
1603 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0),
1605 mali_executor_unlock();
1609 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1610 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1611 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1612 0, 0, /* No pid and tid for interrupt handler */
1613 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0),
1614 mali_gp_get_rawstat(group->gp_core), 0);
1615 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1616 mali_executor_unlock();
1622 static void mali_group_bottom_half_gp(void *data)
1624 struct mali_group *group = (struct mali_group *)data;
1626 MALI_DEBUG_ASSERT_POINTER(group);
1627 MALI_DEBUG_ASSERT_POINTER(group->gp_core);
1628 MALI_DEBUG_ASSERT_POINTER(group->mmu);
1630 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
1631 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1632 MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
1633 0, _mali_osk_get_tid(), /* pid and tid */
1634 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0),
1635 mali_gp_get_rawstat(group->gp_core), 0);
1637 mali_executor_interrupt_gp(group, MALI_FALSE);
1639 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1640 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1641 MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
1642 0, _mali_osk_get_tid(), /* pid and tid */
1643 MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0),
1644 mali_gp_get_rawstat(group->gp_core), 0);
1647 _mali_osk_errcode_t mali_group_upper_half_pp(void *data)
1649 struct mali_group *group = (struct mali_group *)data;
1650 _mali_osk_errcode_t ret;
1652 MALI_DEBUG_ASSERT_POINTER(group);
1653 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
1654 MALI_DEBUG_ASSERT_POINTER(group->mmu);
1656 #if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
1657 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1658 mali_executor_lock();
1659 if (!mali_group_is_working(group)) {
1660 /* Not working, so nothing to do */
1661 mali_executor_unlock();
1662 return _MALI_OSK_ERR_FAULT;
1666 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
1667 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1668 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1669 0, 0, /* No pid and tid for interrupt handler */
1670 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(
1671 mali_pp_core_get_id(group->pp_core)),
1672 mali_pp_get_rawstat(group->pp_core), 0);
1674 MALI_DEBUG_PRINT(4, ("Group: Interrupt 0x%08X from %s\n",
1675 mali_pp_get_rawstat(group->pp_core),
1676 mali_group_core_description(group)));
1677 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1678 mali_executor_unlock();
1682 ret = mali_executor_interrupt_pp(group, MALI_TRUE);
1684 #if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
1685 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1686 mali_executor_lock();
1687 if (!mali_group_is_working(group) && (!mali_group_power_is_on(group))) {
1688 /* group complete and on job shedule on it, it already power off */
1689 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1690 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1691 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1692 0, 0, /* No pid and tid for interrupt handler */
1693 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(
1694 mali_pp_core_get_id(group->pp_core)),
1696 mali_executor_unlock();
1700 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1701 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1702 MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
1703 0, 0, /* No pid and tid for interrupt handler */
1704 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(
1705 mali_pp_core_get_id(group->pp_core)),
1706 mali_pp_get_rawstat(group->pp_core), 0);
1707 #if defined(CONFIG_MALI_SHARED_INTERRUPTS)
1708 mali_executor_unlock();
1714 static void mali_group_bottom_half_pp(void *data)
1716 struct mali_group *group = (struct mali_group *)data;
1718 MALI_DEBUG_ASSERT_POINTER(group);
1719 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
1720 MALI_DEBUG_ASSERT_POINTER(group->mmu);
1722 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
1723 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1724 MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
1725 0, _mali_osk_get_tid(), /* pid and tid */
1726 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(
1727 mali_pp_core_get_id(group->pp_core)),
1728 mali_pp_get_rawstat(group->pp_core), 0);
1730 mali_executor_interrupt_pp(group, MALI_FALSE);
1732 _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
1733 MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
1734 MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
1735 0, _mali_osk_get_tid(), /* pid and tid */
1736 MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(
1737 mali_pp_core_get_id(group->pp_core)),
1738 mali_pp_get_rawstat(group->pp_core), 0);
1741 static void mali_group_timeout(void *data)
1743 struct mali_group *group = (struct mali_group *)data;
1744 MALI_DEBUG_ASSERT_POINTER(group);
1746 MALI_DEBUG_PRINT(2, ("Group: timeout handler for %s at %u\n",
1747 mali_group_core_description(group),
1748 _mali_osk_time_tickcount()));
1750 if (NULL != group->gp_core) {
1751 mali_group_schedule_bottom_half_gp(group);
1753 MALI_DEBUG_ASSERT_POINTER(group->pp_core);
1754 mali_group_schedule_bottom_half_pp(group);
1758 mali_bool mali_group_zap_session(struct mali_group *group,
1759 struct mali_session_data *session)
1761 MALI_DEBUG_ASSERT_POINTER(group);
1762 MALI_DEBUG_ASSERT_POINTER(session);
1763 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1765 if (group->session != session) {
1766 /* not running from this session */
1767 return MALI_TRUE; /* success */
1770 if (group->is_working) {
1771 /* The Zap also does the stall and disable_stall */
1772 mali_bool zap_success = mali_mmu_zap_tlb(group->mmu);
1775 /* Just remove the session instead of zapping */
1776 mali_group_clear_session(group);
1777 return MALI_TRUE; /* success */
1781 #if defined(CONFIG_MALI400_PROFILING)
1782 static void mali_group_report_l2_cache_counters_per_core(struct mali_group *group, u32 core_num)
1788 u32 profiling_channel = 0;
1790 MALI_DEBUG_ASSERT_EXECUTOR_LOCK_HELD();
1794 profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
1795 MALI_PROFILING_EVENT_CHANNEL_GPU |
1796 MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS;
1799 profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
1800 MALI_PROFILING_EVENT_CHANNEL_GPU |
1801 MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L21_COUNTERS;
1804 profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
1805 MALI_PROFILING_EVENT_CHANNEL_GPU |
1806 MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L22_COUNTERS;
1809 profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
1810 MALI_PROFILING_EVENT_CHANNEL_GPU |
1811 MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS;
1815 if (0 == core_num) {
1816 mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
1818 if (1 == core_num) {
1819 if (1 == mali_l2_cache_get_id(group->l2_cache_core[0])) {
1820 mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
1821 } else if (1 == mali_l2_cache_get_id(group->l2_cache_core[1])) {
1822 mali_l2_cache_core_get_counter_values(group->l2_cache_core[1], &source0, &value0, &source1, &value1);
1825 if (2 == core_num) {
1826 if (2 == mali_l2_cache_get_id(group->l2_cache_core[0])) {
1827 mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
1828 } else if (2 == mali_l2_cache_get_id(group->l2_cache_core[1])) {
1829 mali_l2_cache_core_get_counter_values(group->l2_cache_core[1], &source0, &value0, &source1, &value1);
1833 _mali_osk_profiling_add_event(profiling_channel, source1 << 8 | source0, value0, value1, 0, 0);
1835 #endif /* #if defined(CONFIG_MALI400_PROFILING) */