struct mali_soft_job_system *mali_soft_job_system_create(struct mali_session_data *session) { u32 i; struct mali_soft_job_system *system; struct mali_soft_job *job; MALI_DEBUG_ASSERT_POINTER(session); system = (struct mali_soft_job_system *) _mali_osk_calloc(1, sizeof(struct mali_soft_job_system)); if (NULL == system) { return NULL; } system->session = session; system->lock = _mali_osk_spinlock_irq_init(_MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_SCHEDULER); if (NULL == system->lock) { mali_soft_job_system_destroy(system); return NULL; } system->lock_owner = 0; _MALI_OSK_INIT_LIST_HEAD(&(system->jobs_free)); _MALI_OSK_INIT_LIST_HEAD(&(system->jobs_used)); for (i = 0; i < MALI_MAX_NUM_SOFT_JOBS; ++i) { job = &(system->jobs[i]); _mali_osk_list_add(&(job->system_list), &(system->jobs_free)); job->system = system; job->state = MALI_SOFT_JOB_STATE_FREE; job->id = i; } return system; }
_mali_osk_errcode_t mali_scheduler_initialize(void) { _mali_osk_atomic_init(&mali_job_id_autonumber, 0); _mali_osk_atomic_init(&mali_job_cache_order_autonumber, 0); _MALI_OSK_INIT_LIST_HEAD(&job_queue_gp.normal_pri); _MALI_OSK_INIT_LIST_HEAD(&job_queue_gp.high_pri); job_queue_gp.depth = 0; _MALI_OSK_INIT_LIST_HEAD(&job_queue_pp.normal_pri); _MALI_OSK_INIT_LIST_HEAD(&job_queue_pp.high_pri); job_queue_pp.depth = 0; mali_scheduler_lock_obj = _mali_osk_spinlock_irq_init( _MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_SCHEDULER); if (NULL == mali_scheduler_lock_obj) { mali_scheduler_terminate(); } #if defined(MALI_SCHEDULER_USE_DEFERRED_PP_JOB_DELETE) scheduler_wq_pp_job_delete = _mali_osk_wq_create_work( mali_scheduler_do_pp_job_delete, NULL); if (NULL == scheduler_wq_pp_job_delete) { mali_scheduler_terminate(); return _MALI_OSK_ERR_FAULT; } scheduler_pp_job_delete_lock = _mali_osk_spinlock_irq_init( _MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED); if (NULL == scheduler_pp_job_delete_lock) { mali_scheduler_terminate(); return _MALI_OSK_ERR_FAULT; } #endif /* defined(MALI_SCHEDULER_USE_DEFERRED_PP_JOB_DELETE) */ #if defined(MALI_SCHEDULER_USE_DEFERRED_PP_JOB_QUEUE) scheduler_wq_pp_job_queue = _mali_osk_wq_create_work( mali_scheduler_do_pp_job_queue, NULL); if (NULL == scheduler_wq_pp_job_queue) { mali_scheduler_terminate(); return _MALI_OSK_ERR_FAULT; } scheduler_pp_job_queue_lock = _mali_osk_spinlock_irq_init( _MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED); if (NULL == scheduler_pp_job_queue_lock) { mali_scheduler_terminate(); return _MALI_OSK_ERR_FAULT; } #endif /* defined(MALI_SCHEDULER_USE_DEFERRED_PP_JOB_QUEUE) */ return _MALI_OSK_ERR_OK; }
struct mali_soft_job_system *mali_soft_job_system_create(struct mali_session_data *session) { struct mali_soft_job_system *system; MALI_DEBUG_ASSERT_POINTER(session); system = (struct mali_soft_job_system *) _mali_osk_calloc(1, sizeof(struct mali_soft_job_system)); if (NULL == system) { return NULL; } system->session = session; system->lock = _mali_osk_spinlock_irq_init(_MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_SCHEDULER); if (NULL == system->lock) { mali_soft_job_system_destroy(system); return NULL; } system->lock_owner = 0; system->last_job_id = 0; _MALI_OSK_INIT_LIST_HEAD(&(system->jobs_used)); return system; }
_mali_osk_errcode_t mali_session_initialize(void) { _MALI_OSK_INIT_LIST_HEAD(&mali_sessions); mali_sessions_lock = _mali_osk_spinlock_irq_init(_MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_SESSIONS); if (NULL == mali_sessions_lock) return _MALI_OSK_ERR_NOMEM; return _MALI_OSK_ERR_OK; }
static _mali_osk_errcode_t initialize_subsystems(void) { int i, j; _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; /* default error code */ MALI_CHECK_NON_NULL(system_info_lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0 ), _MALI_OSK_ERR_FAULT); #ifdef MALI_SESSION_MEMORY_USAGE MALI_CHECK_NON_NULL(session_data_lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0 ), _MALI_OSK_ERR_FAULT); _MALI_OSK_INIT_LIST_HEAD(&session_data_head); #endif for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i) { if (NULL != subsystems[i]->startup) { /* the subsystem has a startup function defined */ err = subsystems[i]->startup(i); /* the subsystem identifier is the offset in our subsystems array */ if (_MALI_OSK_ERR_OK != err) goto cleanup; } } for (j = 0; j < (int)SUBSYSTEMS_COUNT; ++j) { if (NULL != subsystems[j]->load_complete) { /* the subsystem has a load_complete function defined */ err = subsystems[j]->load_complete(j); if (_MALI_OSK_ERR_OK != err) goto cleanup; } } /* All systems loaded and resources registered */ /* Build system info */ if (_MALI_OSK_ERR_OK != build_system_info()) goto cleanup; MALI_SUCCESS; /* all ok */ cleanup: /* i is index of subsystem which failed to start, all indices before that has to be shut down */ for (i = i - 1; i >= 0; --i) { /* the subsystem identifier is the offset in our subsystems array */ /* Call possible shutdown notficiation functions */ if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i); } #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_lock_term( session_data_lock ); #endif _mali_osk_lock_term( system_info_lock ); MALI_ERROR(err); /* err is what the module which failed its startup returned, or the default */ }
_mali_osk_errcode_t mali_pp_scheduler_initialize(void) { u32 i; _MALI_OSK_INIT_LIST_HEAD(&job_queue); pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER); if (NULL == pp_scheduler_lock) { return _MALI_OSK_ERR_NOMEM; } pp_scheduler_working_wait_queue = _mali_osk_wait_queue_init(); if (NULL == pp_scheduler_working_wait_queue) { _mali_osk_lock_term(pp_scheduler_lock); return _MALI_OSK_ERR_NOMEM; } /* Find all the available PP cores */ for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++) { u32 group_id = 0; struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i); struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id); while (NULL != group) { struct mali_pp_core *pp_core = mali_group_get_pp_core(group); if (NULL != pp_core) { if (0 == pp_version) { /* Retrieve PP version from first avaiable PP core */ pp_version = mali_pp_core_get_version(pp_core); } slots[num_slots].group = group; slots[num_slots].state = MALI_PP_SLOT_STATE_IDLE; slots[num_slots].session = NULL; num_slots++; num_slots_idle++; } group_id++; group = mali_cluster_get_group(curr_cluster, group_id); } } return _MALI_OSK_ERR_OK; }
_mali_osk_errcode_t mali_gp_scheduler_initialize(void) { u32 i; _MALI_OSK_INIT_LIST_HEAD(&job_queue); gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER); gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init(); if (NULL == gp_scheduler_lock) { return _MALI_OSK_ERR_NOMEM; } if (NULL == gp_scheduler_working_wait_queue) { _mali_osk_lock_term(gp_scheduler_lock); return _MALI_OSK_ERR_NOMEM; } /* Find all the available GP cores */ for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++) { u32 group_id = 0; struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i); struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id); while (NULL != group) { struct mali_gp_core *gp_core = mali_group_get_gp_core(group); if (NULL != gp_core) { if (0 == gp_version) { /* Retrieve GP version */ gp_version = mali_gp_core_get_version(gp_core); } slot.group = group; slot.state = MALI_GP_SLOT_STATE_IDLE; break; /* There are only one GP, no point in looking for more */ } group_id++; group = mali_cluster_get_group(curr_cluster, group_id); } } return _MALI_OSK_ERR_OK; }
_mali_osk_errcode_t _mali_ukk_open(void **context) { int i; _mali_osk_errcode_t err; #ifdef MALI_SESSION_MEMORY_USAGE struct mali_session_data_list * session_data_list; #endif struct mali_session_data * session_data; /* allocated struct to track this session */ session_data = (struct mali_session_data *)_mali_osk_malloc(sizeof(struct mali_session_data)); MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM); #ifdef MALI_SESSION_MEMORY_USAGE session_data_list = (struct mali_session_data_list *)_mali_osk_malloc(sizeof(struct mali_session_data_list)); if (session_data_list == NULL) { _mali_osk_free(session_data); return _MALI_OSK_ERR_NOMEM; } _MALI_OSK_INIT_LIST_HEAD(&session_data_list->list_head); session_data_list->pid = _mali_osk_get_pid(); session_data_list->session_data = session_data; session_data->list = session_data_list; #endif _mali_osk_memset(session_data->subsystem_data, 0, sizeof(session_data->subsystem_data)); /* create a response queue for this session */ session_data->ioctl_queue = _mali_osk_notification_queue_init(); if (NULL == session_data->ioctl_queue) { _mali_osk_free(session_data); #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_free(session_data_list); #endif MALI_ERROR(_MALI_OSK_ERR_NOMEM); } MALI_DEBUG_PRINT(3, ("Session starting\n")); /* call session_begin on all subsystems */ for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i) { if (NULL != subsystems[i]->session_begin) { /* subsystem has a session_begin */ err = subsystems[i]->session_begin(session_data, &session_data->subsystem_data[i], session_data->ioctl_queue); MALI_CHECK_GOTO(err == _MALI_OSK_ERR_OK, cleanup); } } *context = (void*)session_data; #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_lock_wait( session_data_lock, _MALI_OSK_LOCKMODE_RW ); _mali_osk_list_addtail(&session_data_list->list_head, &session_data_head); _mali_osk_lock_signal( session_data_lock, _MALI_OSK_LOCKMODE_RW ); #endif MALI_DEBUG_PRINT(3, ("Session started\n")); MALI_SUCCESS; cleanup: MALI_DEBUG_PRINT(2, ("Session startup failed\n")); /* i is index of subsystem which failed session begin, all indices before that has to be ended */ /* end subsystem sessions in the reverse order they where started in */ for (i = i - 1; i >= 0; --i) { if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]); } _mali_osk_notification_queue_term(session_data->ioctl_queue); _mali_osk_free(session_data); #ifdef MALI_SESSION_MEMORY_USAGE _mali_osk_free(session_data_list); #endif /* return what the subsystem which failed session start returned */ MALI_ERROR(err); }
_mali_osk_errcode_t mali_pp_scheduler_initialize(void) { struct mali_group *group; struct mali_pp_core *pp_core; _mali_osk_lock_flags_t lock_flags; u32 num_groups; u32 i; #if defined(MALI_UPPER_HALF_SCHEDULING) lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE; #else lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE; #endif _MALI_OSK_INIT_LIST_HEAD(&job_queue); _MALI_OSK_INIT_LIST_HEAD(&group_list_working); _MALI_OSK_INIT_LIST_HEAD(&group_list_idle); _MALI_OSK_INIT_LIST_HEAD(&virtual_job_queue); pp_scheduler_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER); if (NULL == pp_scheduler_lock) { return _MALI_OSK_ERR_NOMEM; } pp_scheduler_working_wait_queue = _mali_osk_wait_queue_init(); if (NULL == pp_scheduler_working_wait_queue) { _mali_osk_lock_term(pp_scheduler_lock); return _MALI_OSK_ERR_NOMEM; } pp_scheduler_wq_schedule = _mali_osk_wq_create_work(mali_pp_scheduler_do_schedule, NULL); if (NULL == pp_scheduler_wq_schedule) { _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue); _mali_osk_lock_term(pp_scheduler_lock); return _MALI_OSK_ERR_NOMEM; } #if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE) pp_scheduler_wq_job_delete = _mali_osk_wq_create_work(mali_pp_scheduler_do_job_delete, NULL); if (NULL == pp_scheduler_wq_job_delete) { _mali_osk_wq_delete_work(pp_scheduler_wq_schedule); _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue); _mali_osk_lock_term(pp_scheduler_lock); return _MALI_OSK_ERR_NOMEM; } pp_scheduler_job_delete_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED); if (NULL == pp_scheduler_job_delete_lock) { _mali_osk_wq_delete_work(pp_scheduler_wq_job_delete); _mali_osk_wq_delete_work(pp_scheduler_wq_schedule); _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue); _mali_osk_lock_term(pp_scheduler_lock); return _MALI_OSK_ERR_NOMEM; } #endif num_groups = mali_group_get_glob_num_groups(); /* Do we have a virtual group? */ for (i = 0; i < num_groups; i++) { group = mali_group_get_glob_group(i); if (mali_group_is_virtual(group)) { MALI_DEBUG_PRINT(3, ("Found virtual group %p\n", group)); virtual_group = group; break; } } /* Find all the available PP cores */ for (i = 0; i < num_groups; i++) { group = mali_group_get_glob_group(i); pp_core = mali_group_get_pp_core(group); if (NULL != pp_core && !mali_group_is_virtual(group)) { if (0 == pp_version) { /* Retrieve PP version from the first available PP core */ pp_version = mali_pp_core_get_version(pp_core); } if (NULL != virtual_group) { /* Add all physical PP cores to the virtual group */ mali_group_lock(virtual_group); group->state = MALI_GROUP_STATE_JOINING_VIRTUAL; mali_group_add_group(virtual_group, group); mali_group_unlock(virtual_group); } else { _mali_osk_list_add(&group->pp_scheduler_list, &group_list_idle); } num_cores++; } } return _MALI_OSK_ERR_OK; }