static _mali_osk_errcode_t mali200_core_version_legal( mali_core_renderunit *core ) { u32 mali_type; mali_type = core->core_version >> 16; #if defined(USING_MALI400) /* Mali300 and Mali400 is compatible, accept either core. */ if (MALI400_PP_PRODUCT_ID != mali_type && MALI300_PP_PRODUCT_ID != mali_type) #else if (MALI_PP_PRODUCT_ID != mali_type) #endif { MALI_PRINT_ERROR(("Error: reading this from " MALI_PP_SUBSYSTEM_NAME " version register: 0x%x\n", core->core_version)); MALI_ERROR(_MALI_OSK_ERR_FAULT); } MALI_DEBUG_PRINT(3, ("Mali PP: core_version_legal: Reads correct mali version: %d\n", mali_type) ) ; MALI_SUCCESS; }
static _mali_osk_errcode_t mali_platform_powerdown(void) { if (is_running) { #if CONFIG_HAS_WAKELOCK wake_unlock(&wakelock); #endif clk_disable(clk_sga); if (regulator) { int ret = regulator_disable(regulator); if (ret < 0) { MALI_DEBUG_PRINT(2, ("%s: Failed to disable regulator %s\n", __func__, "v-mali")); is_running = false; MALI_ERROR(_MALI_OSK_ERR_FAULT); } } is_running = false; } MALI_DEBUG_PRINT(4, ("mali_platform_powerdown is_running: %u\n", is_running)); MALI_SUCCESS; }
static _mali_osk_errcode_t writereg(u32 where, u32 what, const char *comment, struct dump_info *info) { if (NULL != info) { info->register_writes_size += sizeof(u32) * 2; /* two 32-bit words */ if (NULL != info->buffer) { /* check that we have enough space */ if (info->buffer_left < sizeof(u32) * 2) MALI_ERROR(_MALI_OSK_ERR_NOMEM); *info->buffer = where; info->buffer++; *info->buffer = what; info->buffer++; info->buffer_left -= sizeof(u32) * 2; } } MALI_SUCCESS; }
_mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u32 size ) { MALI_CHECK_GOTO( 0 == ( phys_base & (~_MALI_OSK_CPU_PAGE_MASK)), failure ); MALI_CHECK_GOTO( 0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)), failure ); if ( phys_base >= mem_validator.phys_base && (phys_base + size) >= mem_validator.phys_base && phys_base <= (mem_validator.phys_base + mem_validator.size) && (phys_base + size) <= (mem_validator.phys_base + mem_validator.size) ) { MALI_SUCCESS; } if (phys_base >= mem_validator.phys_base) MALI_PRINTF( ("1\n") ); if ((phys_base + size) >= mem_validator.phys_base) MALI_PRINTF( ("2\n") ); if (phys_base <= (mem_validator.phys_base + mem_validator.size)) MALI_PRINTF( ("3\n") ); if ((phys_base + size) <= (mem_validator.phys_base + mem_validator.size)) MALI_PRINTF( ("4\n") ); failure: MALI_PRINTF( ("*******************************************************************************\n") ); MALI_PRINTF( ("MALI PHYSICAL RANGE VALIDATION ERROR!\n") ); MALI_PRINTF( ("\n") ); MALI_PRINTF( ("We failed to validate a Mali-Physical range that the user-side wished to map in\n") ); MALI_PRINTF( ("\n") ); MALI_PRINTF( ("It is likely that the user-side wished to do Direct Rendering, but a suitable\n") ); MALI_PRINTF( ("address range validation mechanism has not been correctly setup\n") ); MALI_PRINTF( ("\n") ); MALI_PRINTF( ("The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_base, size) ); MALI_PRINTF( ("The range validator was: phys_base=0x%08X, size=0x%08X\n", mem_validator.phys_base, mem_validator.size) ); MALI_PRINTF( ("\n") ); MALI_PRINTF( ("Please refer to the ARM Mali Software Integration Guide for more information.\n") ); MALI_PRINTF( ("\n") ); MALI_PRINTF( ("*******************************************************************************\n") ); MALI_ERROR( _MALI_OSK_ERR_FAULT ); }
_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size) { const int first_pde = MALI_MMU_PDE_ENTRY(mali_address); const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1); _mali_osk_errcode_t err; mali_io_address pde_mapping; u32 pde_phys; int i; if (last_pde < first_pde) { MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } for(i = first_pde; i <= last_pde; i++) { if(0 == (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & MALI_MMU_FLAGS_PRESENT)) { /* Page table not present */ MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); MALI_DEBUG_ASSERT(NULL == pagedir->page_entries_mapped[i]); err = mali_mmu_get_table_page(&pde_phys, &pde_mapping); if(_MALI_OSK_ERR_OK != err) { MALI_PRINT_ERROR(("Failed to allocate page table page.\n")); return err; } pagedir->page_entries_mapped[i] = pde_mapping; /* Update PDE, mark as present */ _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), pde_phys | MALI_MMU_FLAGS_PRESENT); MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]); pagedir->page_entries_usage_count[i] = 1; } else { pagedir->page_entries_usage_count[i]++; } } _mali_osk_write_mem_barrier(); MALI_SUCCESS; }
_mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only ) { switch( core ) { case MALI_PMM_CORE_GP: MALI_CHECK_NO_ERROR(maligp_signal_power_up(queue_only)); break; #if defined USING_MALI400_L2_CACHE case MALI_PMM_CORE_L2: if( !queue_only ) { /* Enable L2 cache due to power up */ mali_kernel_l2_cache_do_enable(); /* Invalidate the cache on power up */ MALI_DEBUG_PRINT(5, ("L2 Cache: Invalidate all\n")); MALI_CHECK_NO_ERROR(mali_kernel_l2_cache_invalidate_all()); } break; #endif case MALI_PMM_CORE_PP0: MALI_CHECK_NO_ERROR(malipp_signal_power_up(0, queue_only)); break; case MALI_PMM_CORE_PP1: MALI_CHECK_NO_ERROR(malipp_signal_power_up(1, queue_only)); break; case MALI_PMM_CORE_PP2: MALI_CHECK_NO_ERROR(malipp_signal_power_up(2, queue_only)); break; case MALI_PMM_CORE_PP3: MALI_CHECK_NO_ERROR(malipp_signal_power_up(3, queue_only)); break; default: /* Unknown core */ MALI_DEBUG_PRINT_ERROR( ("Unknown core signalled with power up: %d\n", core) ); MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS ); } MALI_SUCCESS; }
_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type) { if (*type == PMU) { if( pmu_info ) { _mali_osk_mem_unmapioregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->reg_mapped); _mali_osk_mem_unreqregion(pmu_info->reg_base_addr, pmu_info->reg_size); _mali_osk_free(pmu_info); pmu_info = NULL; MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Terminated PMU\n") ); } } else { /* Didn't expect a different resource */ MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); } MALI_SUCCESS; }
_mali_osk_errcode_t mali_platform_init() { is_running = false; last_utilization = 0; if (!is_initialized) { mali_utilization_workqueue = create_singlethread_workqueue("mali_utilization_workqueue"); if (NULL == mali_utilization_workqueue) { MALI_DEBUG_PRINT(2, ("%s: Failed to setup workqueue %s\n", __func__, "mali_utilization_workqueue")); goto error; } INIT_WORK(&mali_utilization_work, mali_utilization_function); regulator = regulator_get(NULL, "v-mali"); if (IS_ERR(regulator)) { MALI_DEBUG_PRINT(2, ("%s: Failed to get regulator %s\n", __func__, "v-mali")); goto error; } clk_sga = clk_get_sys("mali", NULL); if (IS_ERR(clk_sga)) { regulator_put(regulator); MALI_DEBUG_PRINT(2, ("%s: Failed to get clock %s\n", __func__, "mali")); goto error; } #if CONFIG_HAS_WAKELOCK wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "mali_wakelock"); #endif is_initialized = true; } MALI_SUCCESS; error: MALI_DEBUG_PRINT(1, ("SGA initialization failed.\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); }
_mali_osk_errcode_t mali_platform_init(void) { mali_clk = clk_get_sys("mali", "pll_fixed"); if (mali_clk ) { if (!mali_init_flag) { clk_set_rate(mali_clk, 400000000); mali_clk->enable(mali_clk); malifix_init(); mali_meson_poweron(1); mali_init_flag = 1; } MALI_SUCCESS; } else panic("linux kernel should > 3.0\n"); #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 MALI_PRINT_ERROR(("Failed to lookup mali clock")); MALI_ERROR(_MALI_OSK_ERR_FAULT); #else MALI_SUCCESS; #endif /* CONFIG_ARCH_MESON6 */ }
_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *odescriptor) { _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; int new_descriptor; MALI_DEBUG_ASSERT_POINTER(map); MALI_DEBUG_ASSERT_POINTER(odescriptor); _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW); new_descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings); if (new_descriptor == map->current_nr_mappings) { /* no free descriptor, try to expand the table */ mali_descriptor_table * new_table, * old_table; if (map->current_nr_mappings >= map->max_nr_mappings_allowed) goto unlock_and_exit; map->current_nr_mappings += BITS_PER_LONG; new_table = descriptor_table_alloc(map->current_nr_mappings); if (NULL == new_table) goto unlock_and_exit; old_table = map->table; _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG); _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*)); map->table = new_table; descriptor_table_free(old_table); } /* we have found a valid descriptor, set the value and usage bit */ _mali_osk_set_nonatomic_bit(new_descriptor, map->table->usage); map->table->mappings[new_descriptor] = target; *odescriptor = new_descriptor; err = _MALI_OSK_ERR_OK; unlock_and_exit: _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW); MALI_ERROR(err); }
_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args ) { _mali_osk_errcode_t err; _mali_osk_notification_t * notification; _mali_osk_notification_queue_t *queue; /* check input */ MALI_DEBUG_ASSERT_POINTER(args); MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); queue = (_mali_osk_notification_queue_t *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_core_id); /* if the queue does not exist we're currently shutting down */ if (NULL == queue) { MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n")); args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS; MALI_SUCCESS; } /* receive a notification, might sleep */ err = _mali_osk_notification_queue_receive(queue, ¬ification); if (_MALI_OSK_ERR_OK != err) { MALI_ERROR(err); /* errcode returned, pass on to caller */ } /* copy the buffer to the user */ args->type = (_mali_uk_notification_type)notification->notification_type; _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size); /* finished with the notification */ _mali_osk_notification_delete( notification ); MALI_SUCCESS; /* all ok */ }
_mali_osk_errcode_t mali_platform_powerup(u32 cores) { #if USING_MALI_PMM u32 cores_pmu; u32 stat; u32 timeout; MALI_DEBUG_ASSERT_POINTER(pmu_info); MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */ MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power up (0x%x)\n", cores) ); /* Don't use interrupts - just poll status */ pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_INT_MASK, 0 ); cores_pmu = pmu_translate_cores_to_pmu(cores); pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_UP, cores_pmu ); timeout = 10; /* 10ms */ do { /* Get status of sleeping cores */ stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS ); stat &= cores_pmu; if( stat == 0 ) break; /* All cores we wanted are now awake */ _mali_osk_time_ubusydelay(1000); /* 1ms */ timeout--; } while( timeout > 0 ); if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT); MALI_SUCCESS; #else /* Nothing to do when not using PMM */ MALI_SUCCESS; #endif }
_mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args ) { _mali_core_info * current_core; _mali_mem_info * current_mem; _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; void * current_write_pos, ** current_patch_pos; u32 adjust_ptr_base; /* check input */ MALI_DEBUG_ASSERT_POINTER(args); MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); MALI_CHECK_NON_NULL(args->system_info, _MALI_OSK_ERR_INVALID_ARGS); /* lock the system info */ _mali_osk_lock_wait( system_info_lock, _MALI_OSK_LOCKMODE_RW ); /* first check size */ if (args->size < system_info_size) goto exit_when_locked; /* we build a copy of system_info in the user space buffer specified by the user and * patch up the pointers. The ukk_private members of _mali_uk_get_system_info_s may * indicate a different base address for patching the pointers (normally the * address of the provided system_info buffer would be used). This is helpful when * the system_info buffer needs to get copied to user space and the pointers need * to be in user space. */ if (0 == args->ukk_private) { adjust_ptr_base = (u32)args->system_info; } else { adjust_ptr_base = args->ukk_private; } /* copy each struct into the buffer, and update its pointers */ current_write_pos = (void *)args->system_info; /* first, the master struct */ _mali_osk_memcpy(current_write_pos, system_info, sizeof(_mali_system_info)); /* advance write pointer */ current_write_pos = (void *)((u32)current_write_pos + sizeof(_mali_system_info)); /* first we write the core info structs, patch starts at master's core_info pointer */ current_patch_pos = (void **)((u32)args->system_info + offsetof(_mali_system_info, core_info)); for (current_core = system_info->core_info; NULL != current_core; current_core = current_core->next) { /* patch the pointer pointing to this core */ *current_patch_pos = (void*)(adjust_ptr_base + ((u32)current_write_pos - (u32)args->system_info)); /* copy the core info */ _mali_osk_memcpy(current_write_pos, current_core, sizeof(_mali_core_info)); /* update patch pos */ current_patch_pos = (void **)((u32)current_write_pos + offsetof(_mali_core_info, next)); /* advance write pos in memory */ current_write_pos = (void *)((u32)current_write_pos + sizeof(_mali_core_info)); } /* patching of last patch pos is not needed, since we wrote NULL there in the first place */ /* then we write the mem info structs, patch starts at master's mem_info pointer */ current_patch_pos = (void **)((u32)args->system_info + offsetof(_mali_system_info, mem_info)); for (current_mem = system_info->mem_info; NULL != current_mem; current_mem = current_mem->next) { /* patch the pointer pointing to this core */ *current_patch_pos = (void*)(adjust_ptr_base + ((u32)current_write_pos - (u32)args->system_info)); /* copy the core info */ _mali_osk_memcpy(current_write_pos, current_mem, sizeof(_mali_mem_info)); /* update patch pos */ current_patch_pos = (void **)((u32)current_write_pos + offsetof(_mali_mem_info, next)); /* advance write pos in memory */ current_write_pos = (void *)((u32)current_write_pos + sizeof(_mali_mem_info)); } /* patching of last patch pos is not needed, since we wrote NULL there in the first place */ err = _MALI_OSK_ERR_OK; exit_when_locked: _mali_osk_lock_signal( system_info_lock, _MALI_OSK_LOCKMODE_RW ); MALI_ERROR(err); }
_mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_allocators, _mali_osk_list_t *tracking_list ) { memory_engine * engine = (memory_engine*)mem_engine; MALI_DEBUG_ASSERT_POINTER(engine); MALI_DEBUG_ASSERT_POINTER(descriptor); MALI_DEBUG_ASSERT_POINTER(physical_allocators); /* ASSERT that the list member has been initialized, even if it won't be * used for tracking. We need it to be initialized to see if we need to * delete it from a list in the release function. */ MALI_DEBUG_ASSERT( NULL != descriptor->list.next && NULL != descriptor->list.prev ); if (_MALI_OSK_ERR_OK == engine->mali_address->allocate(descriptor)) { _mali_osk_errcode_t res = _MALI_OSK_ERR_OK; if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) { res = engine->process_address->allocate(descriptor); } if ( _MALI_OSK_ERR_OK == res ) { /* address space setup OK, commit physical memory to the allocation */ mali_physical_memory_allocator * active_allocator = physical_allocators; struct mali_physical_memory_allocation * active_allocation_tracker = &descriptor->physical_allocation; u32 offset = 0; while ( NULL != active_allocator ) { switch (active_allocator->allocate(active_allocator->ctx, mem_engine, descriptor, &offset, active_allocation_tracker)) { case MALI_MEM_ALLOC_FINISHED: if ( NULL != tracking_list ) { /* Insert into the memory session list */ /* ASSERT that it is not already part of a list */ MALI_DEBUG_ASSERT( _mali_osk_list_empty( &descriptor->list ) ); _mali_osk_list_add( &descriptor->list, tracking_list ); } MALI_SUCCESS; /* all done */ case MALI_MEM_ALLOC_NONE: /* reuse current active_allocation_tracker */ MALI_DEBUG_PRINT( 4, ("Memory Engine Allocate: No allocation on %s, resorting to %s\n", ( active_allocator->name ) ? active_allocator->name : "UNNAMED", ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); active_allocator = active_allocator->next; break; case MALI_MEM_ALLOC_PARTIAL: if (NULL != active_allocator->next) { /* need a new allocation tracker */ active_allocation_tracker->next = _mali_osk_calloc(1, sizeof(mali_physical_memory_allocation)); if (NULL != active_allocation_tracker->next) { active_allocation_tracker = active_allocation_tracker->next; MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate: Partial allocation on %s, resorting to %s\n", ( active_allocator->name ) ? active_allocator->name : "UNNAMED", ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") ); active_allocator = active_allocator->next; break; } } /* FALL THROUGH */ case MALI_MEM_ALLOC_INTERNAL_FAILURE: active_allocator = NULL; /* end the while loop */ break; } } MALI_PRINT(("Memory allocate failed, could not allocate size %d kB.\n", descriptor->size/1024)); /* allocation failure, start cleanup */ /* loop over any potential partial allocations */ active_allocation_tracker = &descriptor->physical_allocation; while (NULL != active_allocation_tracker) { /* handle blank trackers which will show up during failure */ if (NULL != active_allocation_tracker->release) { active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle); } active_allocation_tracker = active_allocation_tracker->next; } /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */ for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; ) { void * buf = active_allocation_tracker; active_allocation_tracker = active_allocation_tracker->next; _mali_osk_free(buf); } /* release the address spaces */ if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE ) { engine->process_address->release(descriptor); } } engine->mali_address->release(descriptor); } MALI_ERROR(_MALI_OSK_ERR_FAULT); }
_mali_osk_errcode_t _mali_ukk_attach_ump_mem(_mali_uk_attach_ump_mem_s *args) { ump_dd_handle ump_mem; struct mali_session_data *session; mali_mem_allocation *descriptor; int md, ret; MALI_DEBUG_ASSERT_POINTER(args); MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); session = (struct mali_session_data *)args->ctx; MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS); /* check arguments */ /* NULL might be a valid Mali address */ if (!args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); /* size must be a multiple of the system page size */ if (args->size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); MALI_DEBUG_PRINT(3, ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n", args->secure_id, args->mali_address, args->size)); ump_mem = ump_dd_handle_create_from_secure_id((int)args->secure_id); if (UMP_DD_HANDLE_INVALID == ump_mem) MALI_ERROR(_MALI_OSK_ERR_FAULT); descriptor = mali_mem_descriptor_create(session, MALI_MEM_UMP); if (NULL == descriptor) { ump_dd_reference_release(ump_mem); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } descriptor->ump_mem.handle = ump_mem; descriptor->mali_mapping.addr = args->mali_address; descriptor->size = args->size; descriptor->mali_mapping.properties = MALI_MMU_FLAGS_DEFAULT; descriptor->flags |= MALI_MEM_FLAG_DONT_CPU_MAP; if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { descriptor->flags = MALI_MEM_FLAG_MALI_GUARD_PAGE; } _mali_osk_mutex_wait(session->memory_lock); ret = mali_ump_map(session, descriptor); if (0 != ret) { _mali_osk_mutex_signal(session->memory_lock); ump_dd_reference_release(ump_mem); mali_mem_descriptor_destroy(descriptor); MALI_ERROR(_MALI_OSK_ERR_NOMEM); } _mali_osk_mutex_signal(session->memory_lock); if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md)) { ump_dd_reference_release(ump_mem); mali_mem_descriptor_destroy(descriptor); MALI_ERROR(_MALI_OSK_ERR_FAULT); } args->cookie = md; MALI_DEBUG_PRINT(5,("Returning from UMP attach\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 ); }
/* Start this job on this core. Return MALI_TRUE if the job was started. */ static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali_core_renderunit * core) { mali200_job *job200; /* The local extended version of the general structs */ job200 = _MALI_OSK_CONTAINER_OF(job, mali200_job, embedded_core_job); if ( (0 == job200->user_input.frame_registers[0]) || (0 == job200->user_input.frame_registers[1]) ) { MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x WILL NOT START SINCE JOB HAS ILLEGAL ADDRESSES\n", (u32)job200->user_input.user_job_ptr)); MALI_ERROR(_MALI_OSK_ERR_FAULT); } MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x START_RENDER Tile_list: 0x%08x\n", (u32)job200->user_input.user_job_ptr, job200->user_input.frame_registers[0])); MALI_DEBUG_PRINT(6, ("Mali PP: RSW base addr: 0x%08x Vertex base addr: 0x%08x\n", job200->user_input.frame_registers[1], job200->user_input.frame_registers[2])); /* Frame registers. Copy from mem to physical registers */ mali_core_renderunit_register_write_array( core, MALI200_REG_ADDR_FRAME, &(job200->user_input.frame_registers[0]), MALI200_NUM_REGS_FRAME); /* Write Back unit 0. Copy from mem to physical registers only if the WB unit will be used. */ if (job200->user_input.wb0_registers[0]) { mali_core_renderunit_register_write_array( core, MALI200_REG_ADDR_WB0, &(job200->user_input.wb0_registers[0]), MALI200_NUM_REGS_WBx); } /* Write Back unit 1. Copy from mem to physical registers only if the WB unit will be used. */ if (job200->user_input.wb1_registers[0]) { mali_core_renderunit_register_write_array( core, MALI200_REG_ADDR_WB1, &(job200->user_input.wb1_registers[0]), MALI200_NUM_REGS_WBx); } /* Write Back unit 2. Copy from mem to physical registers only if the WB unit will be used. */ if (job200->user_input.wb2_registers[0]) { mali_core_renderunit_register_write_array( core, MALI200_REG_ADDR_WB2, &(job200->user_input.wb2_registers[0]), MALI200_NUM_REGS_WBx); } /* This selects which performance counters we are reading */ if ( 0 != job200->user_input.perf_counter_flag ) { if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) { mali_core_renderunit_register_write_relaxed( core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); mali_core_renderunit_register_write_relaxed( core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, job200->user_input.perf_counter_src0); } if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) { mali_core_renderunit_register_write_relaxed( core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE); mali_core_renderunit_register_write_relaxed( core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, job200->user_input.perf_counter_src1); } #if defined(USING_MALI400_L2_CACHE) if ( job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) ) { int force_reset = ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET ) ? 1 : 0; u32 src0 = 0; u32 src1 = 0; if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE ) { src0 = job200->user_input.perf_counter_l2_src0; } if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE ) { src1 = job200->user_input.perf_counter_l2_src1; } mali_kernel_l2_cache_set_perf_counters(src0, src1, force_reset); /* will activate and possibly reset counters */ /* Now, retrieve the current values, so we can substract them when the job has completed */ mali_kernel_l2_cache_get_perf_counters(&job200->perf_counter_l2_src0, &job200->perf_counter_l2_val0, &job200->perf_counter_l2_src1, &job200->perf_counter_l2_val1); } #endif } subsystem_flush_mapped_mem_cache(); #if MALI_STATE_TRACKING _mali_osk_atomic_inc(&job->session->jobs_started); #endif /* This is the command that starts the Core */ mali_core_renderunit_register_write( core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING); _mali_osk_write_mem_barrier(); #if MALI_TIMELINE_PROFILING_ENABLED _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job200->user_input.frame_builder_id, job200->user_input.flush_id, 0, 0, 0); _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), job200->pid, job200->tid, #if defined(USING_MALI400_L2_CACHE) (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24), job200->perf_counter_l2_val0, job200->perf_counter_l2_val1 #else 0, 0, 0 #endif ); #endif MALI_SUCCESS; }
_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_platform_init() { int ret; is_running = false; mali_last_utilization = 0; if (!is_initialized) { prcmu_write(PRCMU_PLLSOC0, PRCMU_PLLSOC0_INIT); prcmu_write(PRCMU_SGACLK, PRCMU_SGACLK_INIT); mali_boost_init(); mali_utilization_workqueue = create_singlethread_workqueue("mali_utilization_workqueue"); if (NULL == mali_utilization_workqueue) { MALI_DEBUG_PRINT(2, ("%s: Failed to setup workqueue %s\n", __func__, "mali_utilization_workqueue")); goto error; } INIT_WORK(&mali_utilization_work, mali_utilization_function); //TODO register a notifier block with prcmu opp update func to monitor ape opp INIT_DELAYED_WORK(&mali_boost_delayedwork, mali_boost_work); regulator = regulator_get(NULL, "v-mali"); if (IS_ERR(regulator)) { MALI_DEBUG_PRINT(2, ("%s: Failed to get regulator %s\n", __func__, "v-mali")); goto error; } clk_sga = clk_get_sys("mali", NULL); if (IS_ERR(clk_sga)) { regulator_put(regulator); MALI_DEBUG_PRINT(2, ("%s: Failed to get clock %s\n", __func__, "mali")); goto error; } #if CONFIG_HAS_WAKELOCK wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "mali_wakelock"); #endif mali_kobject = kobject_create_and_add("mali", kernel_kobj); if (!mali_kobject) { pr_err("[Mali] Failed to create kobject interface\n"); } ret = sysfs_create_group(mali_kobject, &mali_interface_group); if (ret) { kobject_put(mali_kobject); } prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, "mali", PRCMU_QOS_DEFAULT_VALUE); prcmu_qos_add_requirement(PRCMU_QOS_DDR_OPP, "mali", PRCMU_QOS_DEFAULT_VALUE); pr_info("[Mali] DB8500 GPU OC Initialized (%s)\n", MALI_UX500_VERSION); is_initialized = true; } MALI_SUCCESS; error: MALI_DEBUG_PRINT(1, ("SGA initialization failed.\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); }
/***************************************************************************** function name : mali_platform_init description : init mali by calling interFace of low software and dvfs input vars : void output vars : NA return value : _mali_osk_errcode_t calls : mali_clock_init mali_dvfs_status_init called : mali_driver_init history : 1.data : 04/03/2014 author : s00250033 modify : new *****************************************************************************/ _mali_osk_errcode_t mali_platform_init(struct platform_device *pdev) { #if MALI_PWRON_NO_DRV mali_platform_powerup_no_drv(); MALI_SUCCESS; #endif pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); pdev->dev.type = &mali_gpu_device_device_type; pdev->dev.platform_data = &mali_gpu_data; np = pdev->dev.of_node; switch(mali_get_gpu_type()) { case MALI_CORE_400_MP1: pdev->num_resources = ARRAY_SIZE(mali_gpu_resources_m400_mp1); pdev->resource = mali_gpu_resources_m400_mp1; MALI_DEBUG_PRINT(2,("get gpu type MALI_CORE_400_MP1\n")); break; case MALI_CORE_400_MP2: pdev->num_resources = ARRAY_SIZE(mali_gpu_resources_m400_mp2); pdev->resource = mali_gpu_resources_m400_mp2; MALI_DEBUG_PRINT(2,("get gpu type MALI_CORE_400_MP2\n")); break; case MALI_CORE_450_MP4: mali_gpu_class_is_mali450 = MALI_TRUE; pdev->num_resources = ARRAY_SIZE(mali_gpu_resources_m450_mp4); pdev->resource = mali_gpu_resources_m450_mp4; MALI_DEBUG_PRINT(2,("get gpu type MALI_CORE_450_MP4\n")); break; default: MALI_DEBUG_PRINT(1,("error get gpu type\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } /* open and get the clk and regulator without mali pmm */ init_mali_clock_regulator(pdev); #if MALI_DVFS_ENABLED pwrctrl_g3d_dfs_init(pdev); mali_dfs_target_profile(0); /* init the dvfs AND work queue */ mali_dvfs_status_init(MALI_DVFS_HOLD); #endif #ifdef CONFIG_PM_RUNTIME #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) pm_runtime_set_autosuspend_delay(&(pdev->dev), 1000); pm_runtime_use_autosuspend(&(pdev->dev)); #endif pm_runtime_enable(&pdev->dev); #endif MALI_SUCCESS; }
_mali_osk_errcode_t mali_platform_init(void) { unsigned long rate,rtmp,rtmp1; // int clk_div; // int mali_used = 0; struct clk *h_tmp; printk(KERN_INFO "Omegamoon>> %s\n", __func__); //get mali ahb clock h_pd_gpu = clk_get(NULL, "pd_gpu"); if(!h_pd_gpu){ MALI_PRINT(("try to get pd_gpu clock failed!\n")); MALI_ERROR(1); } //get mali clk h_gpu = clk_get(NULL, "gpu"); if(!h_gpu){ MALI_PRINT(("try to get gpu clock failed!\n")); MALI_ERROR(1); } rate = clk_get_rate(h_gpu) / 1000; //set mali parent clock if((h_tmp = clk_get_parent(h_gpu))) if((rtmp = clk_get_rate(h_tmp))){ MALI_PRINT(("get mali new parent clock:%d Hz\n", rtmp)); if((h_tmp = clk_get(NULL, "codec_pll"))) if((rtmp1 = clk_get_rate(h_tmp))){ MALI_PRINT(("get mali old parent clock:%d Hz\n", rtmp1)); rtmp1 = rtmp1 / 1000; rate = (rtmp/rtmp1)*rate; } } //set mali clock // = 49875000 // 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; // rate = (unsigned long)49875000; printk(KERN_INFO "Omegamoon >> Current GPU rate is %d\n", rate); if (rate <= 198000000) { printk(KERN_INFO "Omegamoon >> Forcibly set GPU frequency to 400MHz\n"); rate = (unsigned long)400000000; } if(clk_set_rate(h_gpu, rate)){ MALI_PRINT(("try to set gpu 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 Hz\n", rate)); /*enable mali axi/apb clock*/ if(mali_clk_flag == 0) { MALI_PRINT(("enable mali clock\n")); if(clk_enable(h_gpu)) MALI_PRINT(("try to enable mali clock failed!\n")); else mali_clk_flag = 1; // MALI_PRINT(("try to disable h_pd_gpu\n")); // clk_disable(h_pd_gpu); // clk_disable(h_gpu); } MALI_SUCCESS; }
_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); }
/* is called from mali_kernel_constructor in common code */ _mali_osk_errcode_t _mali_osk_init( void ) { if (0 != initialize_kernel_device()) MALI_ERROR(_MALI_OSK_ERR_FAULT); MALI_SUCCESS; }
_mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core ) { _mali_osk_errcode_t err; _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR; if( pmm == NULL ) { /* PMM state has not been created, this is because the PMU resource has not been * created yet. * This probably means that the PMU resource has not been specfied as the first * resource in the config file */ MALI_PRINT_ERROR( ("PMM: Cannot register core %s because the PMU resource has not been\n initialized. Please make sure the PMU resource is the first resource in the\n resource configuration.\n", pmm_trace_get_core_name(core)) ); MALI_ERROR(_MALI_OSK_ERR_FAULT); } MALI_PMM_LOCK(pmm); #if MALI_STATE_TRACKING pmm->mali_pmm_lock_acquired = 1; #endif /* MALI_STATE_TRACKING */ /* Check if the core is registered more than once in PMM */ MALI_DEBUG_ASSERT( (pmm->cores_registered & core) == 0 ); MALIPMM_DEBUG_PRINT( ("PMM: core registered: (0x%x) %s\n", core, pmm_trace_get_core_name(core)) ); #if !MALI_PMM_NO_PMU /* Make sure the core is powered up */ err = malipmm_powerup( core ); #else err = _MALI_OSK_ERR_OK; #endif if( _MALI_OSK_ERR_OK == err ) { #if MALI_PMM_TRACE mali_pmm_core_mask old_power = pmm->cores_powered; #endif /* Assume a registered core is now powered up and idle */ pmm->cores_registered |= core; pmm->cores_idle |= core; pmm->cores_powered |= core; pmm_update_system_state( pmm ); #if MALI_PMM_TRACE _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered ); #endif } else { MALI_PRINT_ERROR( ("PMM: Error(%d) powering up registered core: (0x%x) %s\n", err, core, pmm_trace_get_core_name(core)) ); } #if MALI_STATE_TRACKING pmm->mali_pmm_lock_acquired = 0; #endif /* MALI_STATE_TRACKING */ MALI_PMM_UNLOCK(pmm); return err; }
_mali_osk_errcode_t _mali_ukk_map_external_mem(_mali_uk_map_external_mem_s *args) { struct mali_session_data *session; mali_mem_allocation * descriptor; int md; _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(args); MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS); session = (struct mali_session_data *)args->ctx; MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS); /* check arguments */ /* NULL might be a valid Mali address */ if (! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); /* size must be a multiple of the system page size */ if (args->size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); MALI_DEBUG_PRINT(3, ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n", (void*)args->phys_addr, (void*)(args->phys_addr + args->size -1), (void*)args->mali_address) ); /* Validate the mali physical range */ if (_MALI_OSK_ERR_OK != mali_mem_validation_check(args->phys_addr, args->size)) { return _MALI_OSK_ERR_FAULT; } descriptor = mali_mem_descriptor_create(session, MALI_MEM_EXTERNAL); if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM); descriptor->mali_mapping.addr = args->mali_address; descriptor->size = args->size; if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { descriptor->flags = MALI_MEM_FLAG_MALI_GUARD_PAGE; } _mali_osk_mutex_wait(session->memory_lock); { u32 virt = descriptor->mali_mapping.addr; u32 phys = args->phys_addr; u32 size = args->size; err = mali_mem_mali_map_prepare(descriptor); if (_MALI_OSK_ERR_OK != err) { _mali_osk_mutex_signal(session->memory_lock); mali_mem_descriptor_destroy(descriptor); return _MALI_OSK_ERR_NOMEM; } mali_mmu_pagedir_update(session->page_directory, virt, phys, size, MALI_MMU_FLAGS_DEFAULT); if (descriptor->flags & MALI_MEM_FLAG_MALI_GUARD_PAGE) { mali_mmu_pagedir_update(session->page_directory, virt + size, phys, _MALI_OSK_MALI_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT); } } _mali_osk_mutex_signal(session->memory_lock); if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md)) { _mali_osk_mutex_wait(session->memory_lock); mali_mem_external_release(descriptor); _mali_osk_mutex_signal(session->memory_lock); mali_mem_descriptor_destroy(descriptor); MALI_ERROR(_MALI_OSK_ERR_FAULT); } args->cookie = md; MALI_SUCCESS; }
static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * resource) { mali_core_renderunit *core; _mali_osk_errcode_t err; MALI_DEBUG_PRINT(3, ("Mali PP: mali200_renderunit_create\n") ) ; /* Checking that the resource settings are correct */ #if defined(USING_MALI200) if(MALI200 != resource->type) { MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core.")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } #elif defined(USING_MALI400) if(MALI400PP != resource->type) { MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core.")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } #endif if ( 0 != resource->size ) { MALI_PRINT_ERROR(("Memory size set to " MALI_PP_SUBSYSTEM_NAME " core should be zero.")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } if ( NULL == resource->description ) { MALI_PRINT_ERROR(("A " MALI_PP_SUBSYSTEM_NAME " core needs a unique description field")); MALI_ERROR(_MALI_OSK_ERR_FAULT); } /* Create a new core object */ core = (mali_core_renderunit*) _mali_osk_malloc(sizeof(*core)); if ( NULL == core ) { MALI_ERROR(_MALI_OSK_ERR_NOMEM); } /* Variables set to be able to open and register the core */ core->subsystem = &subsystem_mali200 ; core->registers_base_addr = resource->base ; core->size = MALI200_REG_SIZEOF_REGISTER_BANK ; core->irq_nr = resource->irq ; core->description = resource->description; #if USING_MMU core->mmu_id = resource->mmu_id; core->mmu = NULL; #endif #if USING_MALI_PMM /* Set up core's PMM id */ switch( subsystem_mali200.number_of_cores ) { case 0: core->pmm_id = MALI_PMM_CORE_PP0; break; case 1: core->pmm_id = MALI_PMM_CORE_PP1; break; case 2: core->pmm_id = MALI_PMM_CORE_PP2; break; case 3: core->pmm_id = MALI_PMM_CORE_PP3; break; default: MALI_DEBUG_PRINT(1, ("Unknown supported core for PMM\n")); err = _MALI_OSK_ERR_FAULT; goto exit_on_error0; } #endif err = mali_core_renderunit_init( core ); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Failed to initialize renderunit\n")); goto exit_on_error0; } /* Map the new core object, setting: core->registers_mapped */ err = mali_core_renderunit_map_registers(core); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Failed to map register\n")); goto exit_on_error1; } /* Check that the register mapping of the core works. Return 0 if Mali PP core is present and accessible. */ if (mali_benchmark) { #if defined(USING_MALI200) core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 5 /* Fake Mali200-r0p5 */; #elif defined(USING_MALI400) core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 0x0101 /* Fake Mali400-r1p1 */; #else #error "No supported mali core defined" #endif } else { core->core_version = mali_core_renderunit_register_read( core, MALI200_REG_ADDR_MGMT_VERSION); } err = mali200_core_version_legal(core); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Invalid core\n")); goto exit_on_error2; } /* Reset the core. Put the core into a state where it can start to render. */ mali200_reset(core); /* Registering IRQ, init the work_queue_irq_handle */ /* Adding this core as an available renderunit in the subsystem. */ err = mali_core_subsystem_register_renderunit(&subsystem_mali200, core); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Failed to register with core\n")); goto exit_on_error2; } MALI_DEBUG_PRINT(6, ("Mali PP: mali200_renderunit_create\n") ) ; MALI_SUCCESS; exit_on_error2: mali_core_renderunit_unmap_registers(core); exit_on_error1: mali_core_renderunit_term(core); exit_on_error0: _mali_osk_free( core ) ; MALI_PRINT_ERROR(("Renderunit NOT created.")); MALI_ERROR(err); }