mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries) { mali_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(mali_descriptor_mapping)); init_entries = MALI_PAD_INT(init_entries); max_entries = MALI_PAD_INT(max_entries); if (NULL != map) { map->table = descriptor_table_alloc(init_entries); if (NULL != map->table) { #if !USING_MMU map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 20); #else map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 116); #endif if (NULL != map->lock) { _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */ map->max_nr_mappings_allowed = max_entries; map->current_nr_mappings = init_entries; return map; } descriptor_table_free(map->table); } _mali_osk_free(map); } return NULL; }
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_pm_initialize(void) { mali_pm_lock_execute_state_change = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_EXECUTE); if (NULL != mali_pm_lock_execute_state_change ) { mali_pm_lock_set_next_state = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ONELOCK| _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_LAST); if (NULL != mali_pm_lock_set_next_state) { mali_pm_lock_set_core_states = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_CORE_STATE); if (NULL != mali_pm_lock_set_core_states) { idle_timer = _mali_osk_timer_init(); if (NULL != idle_timer) { wq_irq = _mali_osk_irq_init(_MALI_OSK_IRQ_NUMBER_PMM, mali_pm_upper_half, mali_pm_bottom_half, NULL, NULL, (void *)NULL, "Mali PM deferred work"); if (NULL != wq_irq) { if (_MALI_OSK_ERR_OK == mali_platform_init()) { #if MALI_PMM_RUNTIME_JOB_CONTROL_ON _mali_osk_pm_dev_enable(); mali_pm_powerup(); #endif return _MALI_OSK_ERR_OK; } _mali_osk_irq_term(wq_irq); } _mali_osk_timer_del(idle_timer); _mali_osk_timer_term(idle_timer); } _mali_osk_lock_term(mali_pm_lock_set_core_states); } _mali_osk_lock_term(mali_pm_lock_set_next_state); } _mali_osk_lock_term(mali_pm_lock_execute_state_change); } return _MALI_OSK_ERR_FAULT; }
_mali_osk_errcode_t _mali_profiling_init(mali_bool auto_start) { profile_entries = NULL; profile_entry_count = 0; _mali_osk_atomic_init(&profile_insert_index, 0); _mali_osk_atomic_init(&profile_entries_written, 0); lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 ); if (NULL == lock) { return _MALI_OSK_ERR_FAULT; } prof_state = MALI_PROFILING_STATE_IDLE; if (MALI_TRUE == auto_start) { u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */ mali_profiling_default_enable = MALI_TRUE; /* save this so user space can query this on their startup */ if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit)) { return _MALI_OSK_ERR_FAULT; } } return _MALI_OSK_ERR_OK; }
mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries) { mali_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(mali_descriptor_mapping)); init_entries = MALI_PAD_INT(init_entries); max_entries = MALI_PAD_INT(max_entries); if (NULL != map) { map->table = descriptor_table_alloc(init_entries); if (NULL != map->table) { map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP); if (NULL != map->lock) { _mali_osk_set_nonatomic_bit(0, map->table->usage); map->max_nr_mappings_allowed = max_entries; map->current_nr_mappings = init_entries; return map; } descriptor_table_free(map->table); } _mali_osk_free(map); } return NULL; }
_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start) { profile_entries = NULL; profile_entry_count = 0; _mali_osk_atomic_init(&profile_insert_index, 0); _mali_osk_atomic_init(&profile_entries_written, 0); lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING); if (NULL == lock) { return _MALI_OSK_ERR_FAULT; } prof_state = MALI_PROFILING_STATE_IDLE; if (MALI_TRUE == auto_start) { u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */ mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE); if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit)) { return _MALI_OSK_ERR_FAULT; } } return _MALI_OSK_ERR_OK; }
static mali_bool init_mali_clock(void) { mali_bool ret = MALI_TRUE; if (mali_clock != 0) return ret; // already initialized mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0); if (mali_dvfs_lock == NULL) return _MALI_OSK_ERR_FAULT; if (mali_clk_set_rate(mali_gpu_clk, GPU_MHZ) == MALI_FALSE) { ret = MALI_FALSE; goto err_clock_get; } MALI_PRINT(("init_mali_clock mali_clock %p \n", mali_clock)); #ifdef CONFIG_REGULATOR #if USING_MALI_PMM g3d_regulator = regulator_get(&mali_gpu_device.dev, "vdd_g3d"); #else g3d_regulator = regulator_get(NULL, "vdd_g3d"); #endif if (IS_ERR(g3d_regulator)) { MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n")); ret = MALI_FALSE; goto err_regulator; } regulator_enable(g3d_regulator); MALI_DEBUG_PRINT(1, ("= regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount())); mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); #endif MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n")); MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__)); MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__)); mali_clk_put(MALI_FALSE); gpu_power_state = 0; bPoweroff = 1; return MALI_TRUE; #ifdef CONFIG_REGULATOR err_regulator: regulator_put(g3d_regulator); #endif err_clock_get: mali_clk_put(MALI_TRUE); return ret; }
_mali_osk_errcode_t mali_session_initialize(void) { _MALI_OSK_INIT_LIST_HEAD(&mali_sessions); mali_sessions_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_SESSIONS); if (NULL == mali_sessions_lock) return _MALI_OSK_ERR_NOMEM; return _MALI_OSK_ERR_OK; }
_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; }
/** This function is called when Mali GPU device is initialized */ int _mali_dev_platform_register(void) { int err=0; #if MALI_PMM_RUNTIME_JOB_CONTROL_ON /*set_mali_parent_power_domain((void *)&mali_gpu_device);*/ #endif /*err = platform_device_register(&mali_gpu_device);*/ lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0); if (!err) { err = platform_driver_register(&mali_plat_driver); if (err) { _mali_osk_lock_term(lock); platform_device_unregister(&mali_gpu_device); } } return err; }
void _mali_osk_pm_dev_enable(void) /* @@@@ todo: change to init of some kind.. or change the way or where atomics are initialized? */ { _mali_osk_atomic_init(&mali_pm_ref_count, 0); _mali_osk_atomic_init(&mali_suspend_called, 0); pm_timer = _mali_osk_timer_init(); _mali_osk_timer_setcallback(pm_timer, _mali_pm_callback, NULL); pm_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, 0); #if MALI_LICENSE_IS_GPL #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) mali_pm_wq = alloc_workqueue("mali_pm", WQ_UNBOUND, 0); #else mali_pm_wq = create_workqueue("mali_pm"); #endif if(NULL == mali_pm_wq) { MALI_PRINT_ERROR(("Unable to create Mali pm workqueue\n")); } #endif INIT_WORK( &mali_pm_wq_work_handle, mali_bottom_half_pm ); }
mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name) { mali_physical_memory_allocator * allocator; os_allocator * info; max_allocation = (max_allocation + _MALI_OSK_CPU_PAGE_SIZE-1) & ~(_MALI_OSK_CPU_PAGE_SIZE-1); MALI_DEBUG_PRINT(2, ("Mali OS memory allocator created with max allocation size of 0x%X bytes, cpu_usage_adjust 0x%08X\n", max_allocation, cpu_usage_adjust)); allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator)); if (NULL != allocator) { info = _mali_osk_malloc(sizeof(os_allocator)); if (NULL != info) { info->num_pages_max = max_allocation / _MALI_OSK_CPU_PAGE_SIZE; info->num_pages_allocated = 0; info->cpu_usage_adjust = cpu_usage_adjust; info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO); if (NULL != info->mutex) { allocator->allocate = os_allocator_allocate; allocator->allocate_page_table_block = os_allocator_allocate_page_table_block; allocator->destroy = os_allocator_destroy; allocator->stat = os_allocator_stat; allocator->ctx = info; allocator->name = name; return allocator; } _mali_osk_free(info); } _mali_osk_free(allocator); } return NULL; }
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; }
struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches) { struct mali_pmu_core* pmu; MALI_DEBUG_ASSERT(NULL == mali_global_pmu_core); MALI_DEBUG_PRINT(2, ("Mali PMU: Creating Mali PMU core\n")); pmu = (struct mali_pmu_core *)_mali_osk_malloc(sizeof(struct mali_pmu_core)); if (NULL != pmu) { pmu->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PMU); if (NULL != pmu->lock) { pmu->registered_cores_mask = mali_pmu_detect_mask(number_of_pp_cores, number_of_l2_caches); pmu->active_cores_mask = pmu->registered_cores_mask; if (_MALI_OSK_ERR_OK == mali_hw_core_create(&pmu->hw_core, resource, PMU_REGISTER_ADDRESS_SPACE_SIZE)) { _mali_osk_errcode_t err; struct _mali_osk_device_data data = { 0, }; err = _mali_osk_device_data_get(&data); if (_MALI_OSK_ERR_OK == err) { pmu->switch_delay = data.pmu_switch_delay; mali_global_pmu_core = pmu; return pmu; } mali_hw_core_delete(&pmu->hw_core); } _mali_osk_lock_term(pmu->lock); } _mali_osk_free(pmu); } return NULL; }
struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource) { struct mali_l2_cache_core *cache = NULL; _mali_osk_lock_flags_t lock_flags; #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_DEBUG_PRINT(2, ("Mali L2 cache: Creating Mali L2 cache: %s\n", resource->description)); if (mali_global_num_l2_cache_cores >= MALI_MAX_NUMBER_OF_L2_CACHE_CORES) { MALI_PRINT_ERROR(("Mali L2 cache: Too many L2 cache core objects created\n")); return NULL; } cache = _mali_osk_malloc(sizeof(struct mali_l2_cache_core)); if (NULL != cache) { cache->core_id = mali_global_num_l2_cache_cores; cache->counter_src0 = MALI_HW_CORE_NO_COUNTER; cache->counter_src1 = MALI_HW_CORE_NO_COUNTER; cache->pm_domain = NULL; cache->mali_l2_status = MALI_L2_NORMAL; if (_MALI_OSK_ERR_OK == mali_hw_core_create(&cache->hw_core, resource, MALI400_L2_CACHE_REGISTERS_SIZE)) { cache->command_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND); if (NULL != cache->command_lock) { cache->counter_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER); if (NULL != cache->counter_lock) { mali_l2_cache_reset(cache); cache->last_invalidated_id = 0; mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = cache; mali_global_num_l2_cache_cores++; return cache; } else { MALI_PRINT_ERROR(("Mali L2 cache: Failed to create counter lock for L2 cache core %s\n", cache->hw_core.description)); } _mali_osk_lock_term(cache->command_lock); } else { MALI_PRINT_ERROR(("Mali L2 cache: Failed to create command lock for L2 cache core %s\n", cache->hw_core.description)); } mali_hw_core_delete(&cache->hw_core); } _mali_osk_free(cache); } else { MALI_PRINT_ERROR(("Mali L2 cache: Failed to allocate memory for L2 cache core\n")); } return NULL; }
static mali_bool init_mali_clock(void) { int err = 0; mali_bool ret = MALI_TRUE; nPowermode = MALI_POWER_MODE_DEEP_SLEEP; if (mali_clock != 0) return ret; /* already initialized */ mali_freq_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0); if (mali_freq_lock == NULL) return _MALI_OSK_ERR_FAULT; if (!mali_clk_get()) { MALI_PRINT(("Error: Failed to get Mali clock\n")); goto err_clk; } #ifndef CONFIG_EXYNOS3_VPLL err = clk_set_parent(mali_mout0_clock, sclk_mpll_pre_div_clock); if (err) MALI_PRINT_ERROR(("mali_mout0_clock set parent to sclk_mpll_pre_div_clock failed\n")); err = clk_set_parent(mali_clock, mali_mout0_clock); if (err) MALI_PRINT_ERROR(("mali_clock set parent to mali_mout0_clock failed\n")); #else err = clk_set_rate(fout_vpll_clock, (unsigned int)mali_gpu_clk * GPU_MHZ); if (err > 0) MALI_PRINT_ERROR(("Failed to set fout_vpll clock: %d\n", err)); err = clk_set_parent(vpll_src_clock, ext_xtal_clock); if (err) MALI_PRINT_ERROR(("vpll_src_clock set parent to ext_xtal_clock failed\n")); err = clk_set_parent(sclk_vpll_clock, fout_vpll_clock); if (err) MALI_PRINT_ERROR(("sclk_vpll_clock set parent to fout_vpll_clock failed\n")); err = clk_set_parent(mali_mout1_clock, sclk_vpll_clock); if (err) MALI_PRINT_ERROR(("mali_mout1_clock set parent to sclk_vpll_clock failed\n")); err = clk_set_parent(mali_clock, mali_mout1_clock); if (err) MALI_PRINT_ERROR(("mali_clock set parent to mali_mout1_clock failed\n")); #endif if (!atomic_read(&clk_active)) { if (clk_enable(mali_clock) < 0) { MALI_PRINT(("Error: Failed to enable clock\n")); goto err_clk; } atomic_set(&clk_active, 1); } mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); mali_clk_put(MALI_FALSE); return MALI_TRUE; err_clk: mali_clk_put(MALI_TRUE); return ret; }
mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name) { mali_physical_memory_allocator * allocator; block_allocator * info; u32 usable_size; u32 num_blocks; usable_size = size & ~(MALI_BLOCK_SIZE - 1); MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size)); MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size)); num_blocks = usable_size / MALI_BLOCK_SIZE; MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks)); if (usable_size == 0) { MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size)); return NULL; } allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator)); if (NULL != allocator) { info = _mali_osk_malloc(sizeof(block_allocator)); if (NULL != info) { info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, 105); if (NULL != info->mutex) { info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks); if (NULL != info->all_blocks) { u32 i; info->first_free = NULL; info->num_blocks = num_blocks; info->base = base_address; info->cpu_usage_adjust = cpu_usage_adjust; for ( i = 0; i < num_blocks; i++) { info->all_blocks[i].next = info->first_free; info->first_free = &info->all_blocks[i]; } allocator->allocate = block_allocator_allocate; allocator->allocate_page_table_block = block_allocator_allocate_page_table_block; allocator->destroy = block_allocator_destroy; allocator->stat = block_allocator_stat; allocator->ctx = info; allocator->name = name; return allocator; } _mali_osk_lock_term(info->mutex); } _mali_osk_free(info); } _mali_osk_free(allocator); } return NULL; }
_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 ); }
static mali_bool init_mali_clock(void) { mali_bool ret = MALI_TRUE; nPowermode = MALI_POWER_MODE_DEEP_SLEEP; if (mali_clock != 0) return ret; /* already initialized */ mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0); if (mali_dvfs_lock == NULL) return _MALI_OSK_ERR_FAULT; if (!mali_clk_get()) { MALI_PRINT(("Error: Failed to get Mali clock\n")); goto err_clk; } clk_set_parent(vpll_src_clock, ext_xtal_clock); clk_set_parent(sclk_vpll_clock, fout_vpll_clock); clk_set_parent(mali_parent_clock, sclk_vpll_clock); clk_set_parent(mali_clock, mali_parent_clock); if (!atomic_read(&clk_active)) { if (clk_enable(mali_clock) < 0) { MALI_PRINT(("Error: Failed to enable clock\n")); goto err_clk; } atomic_set(&clk_active, 1); } mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ); MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock)); #ifdef CONFIG_REGULATOR g3d_regulator = regulator_get(NULL, "vdd_g3d"); if (IS_ERR(g3d_regulator)) { MALI_PRINT( ("MALI Error : failed to get vdd_g3d\n")); ret = MALI_FALSE; goto err_regulator; } mali_gpu_vol = get_match_volt(ID_G3D, mali_gpu_clk * GPU_ASV_VOLT); mali_runtime_resume.vol = get_match_volt(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT); regulator_enable(g3d_regulator); mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol); exynos_set_abb(ID_G3D, get_match_abb(ID_G3D, mali_runtime_resume.clk * GPU_ASV_VOLT)); #endif #if defined(CONFIG_MALI400_PROFILING) _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE| MALI_PROFILING_EVENT_CHANNEL_GPU| MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE, mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0); #endif mali_clk_put(MALI_FALSE); return MALI_TRUE; #ifdef CONFIG_REGULATOR err_regulator: regulator_put(g3d_regulator); #endif err_clk: mali_clk_put(MALI_TRUE); return ret; }
_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; }