static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success) { _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s)); if (NULL != notobj) { _mali_uk_gp_job_finished_s *jobres = notobj->result_buffer; _mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */ jobres->user_job_ptr = mali_gp_job_get_user_id(job); if (MALI_TRUE == success) { jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS; } else { jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR; } jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job); jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job); jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job); mali_session_send_notification(mali_gp_job_get_session(job), notobj); } else { MALI_PRINT_ERROR(("Mali GP scheduler: Unable to allocate notification object\n")); } mali_gp_job_delete(job); }
struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache) { struct mali_cluster *cluster = NULL; if (mali_global_num_clusters >= MALI_MAX_NUMBER_OF_CLUSTERS) { MALI_PRINT_ERROR(("Mali cluster: Too many cluster objects created\n")); return NULL; } cluster = _mali_osk_malloc(sizeof(struct mali_cluster)); if (NULL != cluster) { _mali_osk_memset(cluster, 0, sizeof(struct mali_cluster)); cluster->l2 = l2_cache; /* This cluster now owns this L2 cache object */ cluster->last_invalidated_id = 0; mali_global_clusters[mali_global_num_clusters] = cluster; mali_global_num_clusters++; return cluster; } return NULL; }
_mali_osk_errcode_t _mali_ukk_open(void **context) { int i; _mali_osk_errcode_t err; 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); _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); 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; 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); /* return what the subsystem which failed session start returned */ MALI_ERROR(err); }
/** * Creates a sync fence tracker and a sync fence. Adds sync fence tracker to Timeline system and * returns sync fence. The sync fence will be signaled when the sync fence tracker is activated. * * @param timeline Timeline. * @param point Point on timeline. * @return Sync fence that will be signaled when tracker is activated. */ static struct sync_fence *mali_timeline_sync_fence_create_and_add_tracker(struct mali_timeline *timeline, mali_timeline_point point) { struct mali_timeline_sync_fence_tracker *sync_fence_tracker; struct sync_fence *sync_fence; struct mali_timeline_fence fence; MALI_DEBUG_ASSERT_POINTER(timeline); MALI_DEBUG_ASSERT(MALI_TIMELINE_NO_POINT != point); /* Allocate sync fence tracker. */ sync_fence_tracker = _mali_osk_calloc(1, sizeof(struct mali_timeline_sync_fence_tracker)); if (NULL == sync_fence_tracker) { MALI_PRINT_ERROR(("Mali Timeline: sync_fence_tracker allocation failed\n")); return NULL; } /* Create sync flag. */ MALI_DEBUG_ASSERT_POINTER(timeline->sync_tl); sync_fence_tracker->flag = mali_sync_flag_create(timeline->sync_tl, point); if (NULL == sync_fence_tracker->flag) { MALI_PRINT_ERROR(("Mali Timeline: sync_flag creation failed\n")); _mali_osk_free(sync_fence_tracker); return NULL; } /* Create sync fence from sync flag. */ sync_fence = mali_sync_flag_create_fence(sync_fence_tracker->flag); if (NULL == sync_fence) { MALI_PRINT_ERROR(("Mali Timeline: sync_fence creation failed\n")); mali_sync_flag_put(sync_fence_tracker->flag); _mali_osk_free(sync_fence_tracker); return NULL; } /* Setup fence for tracker. */ _mali_osk_memset(&fence, 0, sizeof(struct mali_timeline_fence)); fence.sync_fd = -1; fence.points[timeline->id] = point; /* Finally, add the tracker to Timeline system. */ mali_timeline_tracker_init(&sync_fence_tracker->tracker, MALI_TIMELINE_TRACKER_SYNC, &fence, sync_fence_tracker); point = mali_timeline_system_add_tracker(timeline->system, &sync_fence_tracker->tracker, MALI_TIMELINE_NONE); MALI_DEBUG_ASSERT(MALI_TIMELINE_NO_POINT == point); return sync_fence; }
static _mali_osk_errcode_t mali200_subsystem_startup(mali_kernel_subsystem_identifier id) { mali_core_subsystem * subsystem; MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_startup\n") ) ; mali_subsystem_mali200_id = id; /* All values get 0 as default */ _mali_osk_memset(&subsystem_mali200, 0, sizeof(subsystem_mali200)); subsystem = &subsystem_mali200; subsystem->start_job = &subsystem_mali200_start_job; subsystem->irq_handler_upper_half = &subsystem_mali200_irq_handler_upper_half; subsystem->irq_handler_bottom_half = &subsystem_mali200_irq_handler_bottom_half; subsystem->get_new_job_from_user = &subsystem_mali200_get_new_job_from_user; subsystem->return_job_to_user = &subsystem_mali200_return_job_to_user; subsystem->renderunit_delete = &subsystem_mali200_renderunit_delete; subsystem->reset_core = &subsystem_mali200_renderunit_reset_core; subsystem->stop_bus = &subsystem_mali200_renderunit_stop_bus; subsystem->probe_core_irq_trigger = &subsystem_mali200_renderunit_probe_core_irq_trigger; subsystem->probe_core_irq_acknowledge = &subsystem_mali200_renderunit_probe_core_irq_finished; /* Setting variables in the general core part of the subsystem.*/ subsystem->name = MALI_PP_SUBSYSTEM_NAME; subsystem->core_type = MALI_PP_CORE_TYPE; subsystem->id = id; /* Initiates the rest of the general core part of the subsystem */ MALI_CHECK_NO_ERROR(mali_core_subsystem_init( subsystem )); /* This will register the function for adding MALI200 cores to the subsystem */ #if defined(USING_MALI200) MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI200, mali200_renderunit_create)); #endif #if defined(USING_MALI400) MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI400PP, mali200_renderunit_create)); #endif MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_startup\n") ) ; MALI_SUCCESS; }
static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job) { if (MALI_FALSE == mali_pp_job_use_no_notification(job)) { _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s)); if (NULL != notobj) { u32 i; u32 sub_jobs = mali_pp_job_get_sub_job_count(job); mali_bool success = mali_pp_job_was_success(job); _mali_uk_pp_job_finished_s *jobres = notobj->result_buffer; _mali_osk_memset(jobres, 0, sizeof(_mali_uk_pp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */ jobres->user_job_ptr = mali_pp_job_get_user_id(job); if (MALI_TRUE == success) { jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS; } else { jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR; } for (i = 0; i < sub_jobs; i++) { jobres->perf_counter0[i] = mali_pp_job_get_perf_counter_value0(job, i); jobres->perf_counter1[i] = mali_pp_job_get_perf_counter_value1(job, i); } mali_session_send_notification(mali_pp_job_get_session(job), notobj); } else { MALI_PRINT_ERROR(("Mali PP scheduler: Unable to allocate notification object\n")); } } mali_pp_job_delete(job); }
struct mali_group *mali_group_create(struct mali_cluster *cluster, struct mali_mmu_core *mmu) { struct mali_group *group = NULL; if (mali_global_num_groups >= MALI_MAX_NUMBER_OF_GROUPS) { MALI_PRINT_ERROR(("Mali group: Too many group objects created\n")); return NULL; } group = _mali_osk_malloc(sizeof(struct mali_group)); if (NULL != group) { _mali_osk_memset(group, 0, sizeof(struct mali_group)); group->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_GROUP); if (NULL != group->lock) { group->cluster = cluster; group->mmu = mmu; /* This group object now owns the MMU object */ group->session = NULL; group->page_dir_ref_count = 0; group->power_is_on = MALI_TRUE; group->gp_state = MALI_GROUP_CORE_STATE_IDLE; group->pp_state = MALI_GROUP_CORE_STATE_IDLE; #if defined(USING_MALI200) group->pagedir_activation_failed = MALI_FALSE; #endif mali_global_groups[mali_global_num_groups] = group; mali_global_num_groups++; return group; } _mali_osk_free(group); } return NULL; }
static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success) { _mali_uk_gp_job_finished_s *jobres = job->finished_notification->result_buffer; _mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */ jobres->user_job_ptr = mali_gp_job_get_user_id(job); if (MALI_TRUE == success) { jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS; } else { jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR; } jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job); jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job); jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job); mali_session_send_notification(mali_gp_job_get_session(job), job->finished_notification); job->finished_notification = NULL; mali_gp_job_delete(job); }
static _mali_osk_errcode_t mali200_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue) { mali_core_session * session; MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_session_begin\n") ) ; MALI_CHECK_NON_NULL(session = _mali_osk_malloc( sizeof(mali_core_session) ), _MALI_OSK_ERR_NOMEM); _mali_osk_memset(session, 0, sizeof(*session) ); *slot = (mali_kernel_subsystem_session_slot)session; session->subsystem = &subsystem_mali200; session->notification_queue = queue; #if USING_MMU session->mmu_session = mali_session_data; #endif mali_core_session_begin(session); MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_session_begin\n") ) ; MALI_SUCCESS; }
static _mali_osk_errcode_t build_system_info(void) { unsigned int i; int err = _MALI_OSK_ERR_FAULT; _mali_system_info * new_info, * cleanup; _mali_core_info * current_core; _mali_mem_info * current_mem; u32 new_size = 0; /* create a new system info struct */ MALI_CHECK_NON_NULL(new_info = (_mali_system_info *)_mali_osk_malloc(sizeof(_mali_system_info)), _MALI_OSK_ERR_NOMEM); _mali_osk_memset(new_info, 0, sizeof(_mali_system_info)); /* if an error happens during any of the system_info_fill calls cleanup the new info structs */ cleanup = new_info; /* ask each subsystems to fill in their info */ for (i = 0; i < SUBSYSTEMS_COUNT; ++i) { if (NULL != subsystems[i]->system_info_fill) { err = subsystems[i]->system_info_fill(new_info); if (_MALI_OSK_ERR_OK != err) goto error_exit; } } /* building succeeded, calculate the size */ /* size needed of the system info struct itself */ new_size = sizeof(_mali_system_info); /* size needed for the cores */ for (current_core = new_info->core_info; NULL != current_core; current_core = current_core->next) { new_size += sizeof(_mali_core_info); } /* size needed for the memory banks */ for (current_mem = new_info->mem_info; NULL != current_mem; current_mem = current_mem->next) { new_size += sizeof(_mali_mem_info); } /* lock system info access so a user wont't get a corrupted version */ _mali_osk_lock_wait( system_info_lock, _MALI_OSK_LOCKMODE_RW ); /* cleanup the old one */ cleanup = system_info; /* set new info */ system_info = new_info; system_info_size = new_size; /* we're safe */ _mali_osk_lock_signal( system_info_lock, _MALI_OSK_LOCKMODE_RW ); /* ok result */ err = _MALI_OSK_ERR_OK; /* we share the cleanup routine with the error case */ error_exit: if (NULL == cleanup) MALI_ERROR((_mali_osk_errcode_t)err); /* no cleanup needed, return what err contains */ /* cleanup */ cleanup_system_info(cleanup); /* return whatever err is, we could end up here in both the error and success cases */ MALI_ERROR((_mali_osk_errcode_t)err); }
_mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource) { /* Create PMM state memory */ MALI_DEBUG_ASSERT( pmm_state == NULL ); pmm_state = (_mali_pmm_internal_state_t *) _mali_osk_malloc(sizeof(*pmm_state)); MALI_CHECK_NON_NULL( pmm_state, _MALI_OSK_ERR_NOMEM ); /* All values get 0 as default */ _mali_osk_memset(pmm_state, 0, sizeof(*pmm_state)); /* Set up the initial PMM state */ pmm_state->waiting = 0; pmm_state->status = MALI_PMM_STATUS_IDLE; pmm_state->state = MALI_PMM_STATE_UNAVAILABLE; /* Until a core registers */ /* Set up policy via compile time option for the moment */ #if MALI_PMM_ALWAYS_ON pmm_state->policy = MALI_PMM_POLICY_ALWAYS_ON; #else pmm_state->policy = MALI_PMM_POLICY_JOB_CONTROL; #endif #if MALI_PMM_TRACE _mali_pmm_trace_policy_change( MALI_PMM_POLICY_NONE, pmm_state->policy ); #endif /* Set up assumes all values are initialized to NULL or MALI_FALSE, so * we can exit halfway through set up and perform clean up */ #if !MALI_PMM_NO_PMU if( mali_platform_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup; pmm_state->pmu_initialized = MALI_TRUE; #endif pmm_state->queue = _mali_osk_notification_queue_init(); if( !pmm_state->queue ) goto pmm_fail_cleanup; pmm_state->iqueue = _mali_osk_notification_queue_init(); if( !pmm_state->iqueue ) goto pmm_fail_cleanup; /* We are creating an IRQ handler just for the worker thread it gives us */ pmm_state->irq = _mali_osk_irq_init( _MALI_OSK_IRQ_NUMBER_PMM, malipmm_irq_uhandler, malipmm_irq_bhandler, NULL, NULL, (void *)pmm_state, /* PMM state is passed to IRQ */ "PMM handler" ); if( !pmm_state->irq ) goto pmm_fail_cleanup; #ifdef CONFIG_SMP mali_pmm_lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0); if( !mali_pmm_lock ) goto pmm_fail_cleanup; #endif /* CONFIG_SMP */ pmm_state->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 75); if( !pmm_state->lock ) goto pmm_fail_cleanup; if( _mali_osk_atomic_init( &(pmm_state->messages_queued), 0 ) != _MALI_OSK_ERR_OK ) { goto pmm_fail_cleanup; } MALIPMM_DEBUG_PRINT( ("PMM: subsystem created, policy=%d\n", pmm_state->policy) ); MALI_SUCCESS; pmm_fail_cleanup: MALI_PRINT_ERROR( ("PMM: subsystem failed to be created\n") ); if( pmm_state ) { _mali_osk_resource_type_t t = PMU; if( pmm_state->lock ) _mali_osk_lock_term( pmm_state->lock ); if( pmm_state->irq ) _mali_osk_irq_term( pmm_state->irq ); if( pmm_state->queue ) _mali_osk_notification_queue_term( pmm_state->queue ); if( pmm_state->iqueue ) _mali_osk_notification_queue_term( pmm_state->iqueue ); if( pmm_state->pmu_initialized ) ( mali_platform_deinit(&t) ); _mali_osk_free(pmm_state); pmm_state = NULL; } MALI_ERROR( _MALI_OSK_ERR_FAULT ); }
_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource) { if( resource->type == PMU ) { if( (resource->base == 0) || (resource->description == NULL) ) { /* NOTE: We currently don't care about any other resource settings */ MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Missing PMU set up information\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } pmu_info = (platform_pmu_t *)_mali_osk_malloc(sizeof(*pmu_info)); MALI_CHECK_NON_NULL( pmu_info, _MALI_OSK_ERR_NOMEM ); /* All values get 0 as default */ _mali_osk_memset(pmu_info, 0, sizeof(*pmu_info)); pmu_info->reg_base_addr = resource->base; pmu_info->reg_size = (u32)PMU_REGISTER_ADDRESS_SPACE_SIZE; pmu_info->name = resource->description; pmu_info->irq_num = resource->irq; if( _MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name) ) { MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not request register region (0x%08X - 0x%08X) for %s\n", pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); goto cleanup; } else { MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: request_mem_region: (0x%08X - 0x%08X) for %s\n", pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); } pmu_info->reg_mapped = _mali_osk_mem_mapioregion( pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name ); if( 0 == pmu_info->reg_mapped ) { MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not ioremap registers for %s .\n", pmu_info->name)); _mali_osk_mem_unreqregion( pmu_info->reg_base_addr, pmu_info->reg_size ); goto cleanup; } else { MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) for %s\n", (u32) pmu_info->reg_mapped, ((u32)pmu_info->reg_mapped)+ pmu_info->reg_size - 1, pmu_info->name)); } MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: Mapping registers to %s\n", pmu_info->name)); #if PMU_TEST pmu_test(pmu_info, (MALI_PMM_CORE_GP)); pmu_test(pmu_info, (MALI_PMM_CORE_GP|MALI_PMM_CORE_L2|MALI_PMM_CORE_PP0)); #endif MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Initialized - %s\n", pmu_info->name) ); } else { /* Didn't expect a different resource */ MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } MALI_SUCCESS; cleanup: _mali_osk_free(pmu_info); pmu_info = NULL; MALI_ERROR(_MALI_OSK_ERR_NOMEM); }
_mali_osk_errcode_t mali_platform_init(_mali_osk_resource_t *resource) { unsigned long rate; int clk_div; int mali_used = 0; //get mali ahb clock h_ahb_mali = clk_get(NULL, "ahb_mali"); if(!h_ahb_mali){ MALI_PRINT(("try to get ahb mali clock failed!\n")); } //get mali clk h_mali_clk = clk_get(NULL, "mali"); if(!h_mali_clk){ MALI_PRINT(("try to get mali clock failed!\n")); } h_ve_pll = clk_get(NULL, "ve_pll"); if(!h_ve_pll){ MALI_PRINT(("try to get ve pll clock failed!\n")); } //set mali parent clock if(clk_set_parent(h_mali_clk, h_ve_pll)){ MALI_PRINT(("try to set mali clock source failed!\n")); } //set mali clock rate = clk_get_rate(h_ve_pll); if(!script_parser_fetch("mali_para", "mali_used", &mali_used, 1)) { if (mali_used == 1) { if (!script_parser_fetch("mali_para", "mali_clkdiv", &clk_div, 1)) { if (clk_div > 0) { pr_info("mali: use config clk_div %d\n", clk_div); mali_clk_div = clk_div; } } } } pr_info("mali: clk_div %d\n", mali_clk_div); rate /= mali_clk_div; if(clk_set_rate(h_mali_clk, rate)){ MALI_PRINT(("try to set mali clock failed!\n")); } if(clk_reset(h_mali_clk,0)){ MALI_PRINT(("try to reset release failed!\n")); } MALI_PRINT(("mali clock set completed, clock is %d Mhz\n", rate)); #if USING_MALI_PMM if( resource == NULL ) { /* Nothing to set up for the system */ } else if( resource->type == PMU ) { if( (resource->base == 0) || (resource->description == NULL) ) { /* NOTE: We currently don't care about any other resource settings */ MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Missing PMU set up information\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } MALI_DEBUG_ASSERT( pmu_info == NULL ); pmu_info = (platform_pmu_t *)_mali_osk_malloc(sizeof(*pmu_info)); MALI_CHECK_NON_NULL( pmu_info, _MALI_OSK_ERR_NOMEM ); /* All values get 0 as default */ _mali_osk_memset(pmu_info, 0, sizeof(*pmu_info)); pmu_info->reg_base_addr = resource->base; pmu_info->reg_size = (u32)PMU_REGISTER_ADDRESS_SPACE_SIZE; pmu_info->name = resource->description; pmu_info->irq_num = resource->irq; if( _MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name) ) { MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not request register region (0x%08X - 0x%08X) for %s\n", pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); goto cleanup; } else { MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: request_mem_region: (0x%08X - 0x%08X) for %s\n", pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name)); } pmu_info->reg_mapped = _mali_osk_mem_mapioregion( pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name ); if( 0 == pmu_info->reg_mapped ) { MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not ioremap registers for %s .\n", pmu_info->name)); _mali_osk_mem_unreqregion( pmu_info->reg_base_addr, pmu_info->reg_size ); goto cleanup; } else { MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) for %s\n", (u32) pmu_info->reg_mapped, ((u32)pmu_info->reg_mapped)+ pmu_info->reg_size - 1, pmu_info->name)); } MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: Mapping registers to %s\n", pmu_info->name)); #if PMU_TEST pmu_test(pmu_info, (MALI_PMM_CORE_GP)); pmu_test(pmu_info, (MALI_PMM_CORE_GP|MALI_PMM_CORE_L2|MALI_PMM_CORE_PP0)); #endif MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Initialized - %s\n", pmu_info->name) ); } else { /* Didn't expect a different resource */ MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } MALI_SUCCESS; cleanup: _mali_osk_free(pmu_info); pmu_info = NULL; MALI_ERROR(_MALI_OSK_ERR_NOMEM); #else /* Nothing to do when not using PMM - as mali already on */ MALI_SUCCESS; #endif }
_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); }