void mali_gp_abort_job(struct mali_gp_core *core) { MALI_DEBUG_ASSERT_POINTER(core); MALI_ASSERT_GROUP_LOCKED(core->group); if (_MALI_OSK_ERR_FAULT != mali_gp_reset(core)) { _mali_osk_timer_del(core->timeout_timer); } }
struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t *resource, struct mali_group *group) { struct mali_gp_core *core = NULL; MALI_DEBUG_ASSERT(NULL == mali_global_gp_core); MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description)); core = _mali_osk_malloc(sizeof(struct mali_gp_core)); if (NULL != core) { if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE)) { _mali_osk_errcode_t ret; ret = mali_gp_reset(core); if (_MALI_OSK_ERR_OK == ret) { ret = mali_group_add_gp_core(group, core); if (_MALI_OSK_ERR_OK == ret) { /* Setup IRQ handlers (which will do IRQ probing if needed) */ core->irq = _mali_osk_irq_init(resource->irq, mali_group_upper_half_gp, group, mali_gp_irq_probe_trigger, mali_gp_irq_probe_ack, core, resource->description); if (NULL != core->irq) { MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core)); mali_global_gp_core = core; return core; } else { MALI_PRINT_ERROR(("Mali GP: Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description)); } mali_group_remove_gp_core(group); } else { MALI_PRINT_ERROR(("Mali GP: Failed to add core %s to group\n", core->hw_core.description)); } } mali_hw_core_delete(&core->hw_core); } _mali_osk_free(core); } else { MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n")); } return NULL; }
/* Called from mali_cluster_reset() when the system is re-turned on */ void mali_group_reset(struct mali_group *group) { mali_group_lock(group); group->session = NULL; if (NULL != group->mmu) { mali_mmu_reset(group->mmu); } if (NULL != group->gp_core) { mali_gp_reset(group->gp_core); } if (NULL != group->pp_core) { mali_pp_reset(group->pp_core); } mali_group_unlock(group); }
struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group) { struct mali_gp_core* core = NULL; MALI_DEBUG_ASSERT(NULL == mali_global_gp_core); MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description)); core = _mali_osk_malloc(sizeof(struct mali_gp_core)); if (NULL != core) { core->group = group; core->running_job = NULL; core->counter_src0 = MALI_HW_CORE_NO_COUNTER; core->counter_src1 = MALI_HW_CORE_NO_COUNTER; core->counter_src0_used = MALI_HW_CORE_NO_COUNTER; core->counter_src1_used = MALI_HW_CORE_NO_COUNTER; if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE)) { _mali_osk_errcode_t ret; mali_group_lock(group); ret = mali_gp_reset(core); mali_group_unlock(group); if (_MALI_OSK_ERR_OK == ret) { core->irq = _mali_osk_irq_init(resource->irq, mali_gp_upper_half, mali_gp_bottom_half, mali_gp_irq_probe_trigger, mali_gp_irq_probe_ack, core, "mali_gp_irq_handlers"); if (NULL != core->irq) { core->timeout_timer = _mali_osk_timer_init(); if(NULL != core->timeout_timer) { _mali_osk_timer_setcallback(core->timeout_timer, mali_gp_timeout, (void *)core); MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core)); mali_global_gp_core = core; return core; } else { MALI_PRINT_ERROR(("Failed to setup timeout timer for GP core %s\n", core->hw_core.description)); _mali_osk_irq_term(core->irq); } } else { MALI_PRINT_ERROR(("Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description)); } } mali_hw_core_delete(&core->hw_core); } _mali_osk_free(core); } else { MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n")); } return NULL; }
/* Group lock need to be taken before calling mali_group_complete_jobs. Will release the lock here. */ static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success) { mali_bool need_group_reset = MALI_FALSE; mali_bool gp_success = success; mali_bool pp_success = success; MALI_ASSERT_GROUP_LOCKED(group); if (complete_gp && !complete_pp) { MALI_DEBUG_ASSERT_POINTER(group->gp_core); if (_MALI_OSK_ERR_OK == mali_gp_reset(group->gp_core)) { struct mali_gp_job *gp_job_to_return = group->gp_running_job; group->gp_state = MALI_GROUP_CORE_STATE_IDLE; group->gp_running_job = NULL; MALI_DEBUG_ASSERT_POINTER(gp_job_to_return); mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return)); if(mali_group_other_reschedule_needed(group)) { mali_group_unlock(group); mali_pp_scheduler_do_schedule(); } else { mali_group_unlock(group); } mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success); mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ return; } else { need_group_reset = MALI_TRUE; MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n")); pp_success = MALI_FALSE; /* This might kill PP as well, so this should fail */ } } if (complete_pp && !complete_gp) { MALI_DEBUG_ASSERT_POINTER(group->pp_core); if (_MALI_OSK_ERR_OK == mali_pp_reset(group->pp_core)) { struct mali_pp_job *pp_job_to_return = group->pp_running_job; u32 pp_sub_job_to_return = group->pp_running_sub_job; group->pp_state = MALI_GROUP_CORE_STATE_IDLE; group->pp_running_job = NULL; MALI_DEBUG_ASSERT_POINTER(pp_job_to_return); mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return)); if(mali_group_other_reschedule_needed(group)) { mali_group_unlock(group); mali_gp_scheduler_do_schedule(); } else { mali_group_unlock(group); } mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success); mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ return; } else { need_group_reset = MALI_TRUE; MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n")); gp_success = MALI_FALSE; /* This might kill GP as well, so this should fail */ } } else if (complete_gp && complete_pp) { need_group_reset = MALI_TRUE; } if (MALI_TRUE == need_group_reset) { struct mali_gp_job *gp_job_to_return = group->gp_running_job; struct mali_pp_job *pp_job_to_return = group->pp_running_job; u32 pp_sub_job_to_return = group->pp_running_sub_job; mali_bool schedule_other = MALI_FALSE; MALI_DEBUG_PRINT(3, ("Mali group: Resetting entire group\n")); group->gp_state = MALI_GROUP_CORE_STATE_IDLE; group->gp_running_job = NULL; if (NULL != gp_job_to_return) { mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return)); } group->pp_state = MALI_GROUP_CORE_STATE_IDLE; group->pp_running_job = NULL; if (NULL != pp_job_to_return) { mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return)); } /* The reset has to be done after mali_group_deactivate_page_directory() */ mali_group_recovery_reset(group); if (mali_group_other_reschedule_needed(group) && (NULL == gp_job_to_return || NULL == pp_job_to_return)) { schedule_other = MALI_TRUE; } mali_group_unlock(group); if (NULL != gp_job_to_return) { mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success); mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ } else if (schedule_other) { mali_pp_scheduler_do_schedule(); } if (NULL != pp_job_to_return) { mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success); mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */ } else if (schedule_other) { mali_gp_scheduler_do_schedule(); } return; } mali_group_unlock(group); }