void mali_regulator_set_voltage(int min_uV, int max_uV) { int voltage; #if !MALI_DVFS_ENABLED min_uV = mali_gpu_vol; max_uV = mali_gpu_vol; #endif /* #if MALI_VOLTAGE_LOCK if (mali_vol_lock_flag == MALI_FALSE) { if (min_uV < MALI_BOTTOMLOCK_VOL || max_uV < MALI_BOTTOMLOCK_VOL) { min_uV = MALI_BOTTOMLOCK_VOL; max_uV = MALI_BOTTOMLOCK_VOL; } } else if (_mali_osk_atomic_read(&voltage_lock_status) > 0 ) { if (min_uV < mali_lock_vol || max_uV < mali_lock_vol) { #if MALI_DVFS_ENABLED int mali_vol_get; mali_vol_get = mali_vol_get_from_table(mali_lock_vol); if (mali_vol_get) { min_uV = mali_vol_get; max_uV = mali_vol_get; } #else min_uV = mali_lock_vol; max_uV = mali_lock_vol; #endif } } #endif */ _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); if( IS_ERR_OR_NULL(g3d_regulator) ) { MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n")); return; } MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV)); #if MALI_TIMELINE_PROFILING_ENABLED _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS, min_uV, max_uV, 1, 0, 0); #endif regulator_set_voltage(g3d_regulator,min_uV,max_uV); voltage = regulator_get_voltage(g3d_regulator); #if MALI_TIMELINE_PROFILING_ENABLED _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS, voltage, 0, 2, 0, 0); #endif mali_gpu_vol = voltage; MALI_DEBUG_PRINT(1, ("= regulator_get_voltage: %d \n",mali_gpu_vol)); _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); }
static void mali_dvfs_work_handler(struct work_struct *w) { int change_clk = 0; int change_step = 0; bMaliDvfsRun=1; /* dvfs table change when clock was changed */ if (step0_clk != mali_dvfs[0].clock) { MALI_PRINT(("::: step0_clk change to %d Mhz\n", step0_clk)); change_clk = step0_clk; change_step = 0; step0_clk = change_dvfs_tableset(change_clk, change_step); } #if (MALI_DVFS_STEPS > 1) if (step1_clk != mali_dvfs[1].clock) { MALI_PRINT(("::: step1_clk change to %d Mhz\n", step1_clk)); change_clk = step1_clk; change_step = 1; step1_clk = change_dvfs_tableset(change_clk, change_step); } if (step0_up != mali_dvfs_threshold[0].upthreshold) { MALI_PRINT(("::: step0_up change to %d %\n", step0_up)); mali_dvfs_threshold[0].upthreshold = step0_up; } if (step1_down != mali_dvfs_threshold[1].downthreshold) { MALI_PRINT((":::step1_down change to %d %\n", step1_down)); mali_dvfs_threshold[1].downthreshold = step1_down; } #if (MALI_DVFS_STEPS > 2) if (step2_clk != mali_dvfs[2].clock) { MALI_PRINT(("::: step2_clk change to %d Mhz\n", step2_clk)); change_clk = step2_clk; change_step = 2; step2_clk = change_dvfs_tableset(change_clk, change_step); } if (step1_up != mali_dvfs_threshold[1].upthreshold) { MALI_PRINT((":::step1_up change to %d %\n", step1_up)); mali_dvfs_threshold[1].upthreshold = step1_up; } if (step2_down != mali_dvfs_threshold[2].downthreshold) { MALI_PRINT((":::step2_down change to %d %\n", step2_down)); mali_dvfs_threshold[2].downthreshold = step2_down; } #if (MALI_DVFS_STEPS > 3) if (step3_clk != mali_dvfs[3].clock) { MALI_PRINT(("::: step3_clk change to %d Mhz\n", step3_clk)); change_clk = step3_clk; change_step = 3; step3_clk = change_dvfs_tableset(change_clk, change_step); } if (step2_up != mali_dvfs_threshold[2].upthreshold) { MALI_PRINT((":::step2_up change to %d %\n", step2_up)); mali_dvfs_threshold[2].upthreshold = step2_up; } if (step3_down != mali_dvfs_threshold[3].downthreshold) { MALI_PRINT((":::step3_down change to %d %\n", step3_down)); mali_dvfs_threshold[3].downthreshold = step3_down; } #if (MALI_DVFS_STEPS > 4) if (step4_clk != mali_dvfs[4].clock) { MALI_PRINT(("::: step4_clk change to %d Mhz\n", step4_clk)); change_clk = step4_clk; change_step = 4; step4_clk = change_dvfs_tableset(change_clk, change_step); } if (step3_up != mali_dvfs_threshold[3].upthreshold) { MALI_PRINT((":::step3_up change to %d %\n", step3_up)); mali_dvfs_threshold[3].upthreshold = step3_up; } if (step4_down != mali_dvfs_threshold[4].downthreshold) { MALI_PRINT((":::step4_down change to %d %\n", step4_down)); mali_dvfs_threshold[4].downthreshold = step4_down; } #endif #endif #endif #endif #ifdef DEBUG mali_dvfs[0].vol = step0_vol; mali_dvfs[1].vol = step1_vol; mali_dvfs[2].vol = step2_vol; mali_dvfs[3].vol = step3_vol; mali_dvfs[4].vol = step4_vol; #endif MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n")); if (!mali_dvfs_status(mali_dvfs_utilization)) MALI_DEBUG_PRINT(1,( "error on mali dvfs status in mali_dvfs_work_handler")); bMaliDvfsRun=0; }
_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_STATIC_INLINE void mali_gp_scheduler_unlock(void) { MALI_DEBUG_PRINT(5, ("Mali GP scheduler: Releasing GP scheduler lock\n")); _mali_osk_lock_signal(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW); }
int mali_platform_device_register(void) { int err = -1; #if defined(CONFIG_ARCH_REALVIEW) u32 m400_gp_version; #endif MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n")); /* Detect present Mali GPU and connect the correct resources to the device */ #if defined(CONFIG_ARCH_VEXPRESS) if (mali_read_phys(0xFC020000) == 0x00010100) { MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n")); err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m450_mp8, sizeof(mali_gpu_resources_m450_mp8) / sizeof(mali_gpu_resources_m450_mp8[0])); } #elif defined(CONFIG_ARCH_REALVIEW) m400_gp_version = mali_read_phys(0xC000006C); if (m400_gp_version == 0x00000000 && (mali_read_phys(0xC000206c) & 0xFFFF0000) == 0x0A070000) { MALI_DEBUG_PRINT(4, ("Registering Mali-200 device\n")); err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m200, sizeof(mali_gpu_resources_m200) / sizeof(mali_gpu_resources_m200[0])); mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ } else if ((m400_gp_version & 0xFFFF0000) == 0x0C070000) { MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n")); err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m300, sizeof(mali_gpu_resources_m300) / sizeof(mali_gpu_resources_m300[0])); mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ } else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000) { u32 fpga_fw_version = mali_read_phys(0xC0010000); if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F) { /* Mali-400 MP1 r1p0 or r1p1 */ MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n")); err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m400_mp1, sizeof(mali_gpu_resources_m400_mp1) / sizeof(mali_gpu_resources_m400_mp1[0])); mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ } else if (fpga_fw_version == 0x130C000F) { /* Mali-400 MP2 r1p1 */ MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n")); err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources_m400_mp2, sizeof(mali_gpu_resources_m400_mp2) / sizeof(mali_gpu_resources_m400_mp2[0])); mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ } } #endif if (0 == err) { err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data)); if (0 == err) { /* Register the platform device */ err = platform_device_register(&mali_gpu_device); if (0 == err) { #ifdef CONFIG_PM_RUNTIME #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000); pm_runtime_use_autosuspend(&(mali_gpu_device.dev)); #endif pm_runtime_enable(&(mali_gpu_device.dev)); #endif return 0; } } platform_device_unregister(&mali_gpu_device); } return err; }
void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual) { u32 relative_address; u32 start_index; u32 nr_of_regs; u32 *frame_registers = mali_pp_job_get_frame_registers(job); u32 *wb0_registers = mali_pp_job_get_wb0_registers(job); u32 *wb1_registers = mali_pp_job_get_wb1_registers(job); u32 *wb2_registers = mali_pp_job_get_wb2_registers(job); u32 counter_src0 = mali_pp_job_get_perf_counter_src0(job, sub_job); u32 counter_src1 = mali_pp_job_get_perf_counter_src1(job, sub_job); MALI_DEBUG_ASSERT_POINTER(core); /* Write frame registers */ /* * There are two frame registers which are different for each sub job: * 1. The Renderer List Address Register (MALI200_REG_ADDR_FRAME) * 2. The FS Stack Address Register (MALI200_REG_ADDR_STACK) */ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_FRAME / sizeof(u32)]); /* For virtual jobs, the stack address shouldn't be broadcast but written individually */ if (!mali_pp_job_is_virtual(job) || restart_virtual) { mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK / sizeof(u32)]); } /* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */ relative_address = MALI200_REG_ADDR_RSW; start_index = MALI200_REG_ADDR_RSW / sizeof(u32); nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32); mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, relative_address, &frame_registers[start_index], nr_of_regs, &mali_frame_registers_reset_values[start_index]); /* MALI200_REG_ADDR_STACK_SIZE */ relative_address = MALI200_REG_ADDR_STACK_SIZE; start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32); mali_hw_core_register_write_relaxed_conditional(&core->hw_core, relative_address, frame_registers[start_index], mali_frame_registers_reset_values[start_index]); /* Skip 2 reserved registers */ /* Write remaining registers */ relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X; start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32); nr_of_regs = MALI_PP_MALI400_NUM_FRAME_REGISTERS - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32); mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, relative_address, &frame_registers[start_index], nr_of_regs, &mali_frame_registers_reset_values[start_index]); /* Write WBx registers */ if (wb0_registers[0]) { /* M200_WB0_REG_SOURCE_SELECT register */ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values); } if (wb1_registers[0]) { /* M200_WB1_REG_SOURCE_SELECT register */ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values); } if (wb2_registers[0]) { /* M200_WB2_REG_SOURCE_SELECT register */ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values); } if (MALI_HW_CORE_NO_COUNTER != counter_src0) { mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, counter_src0); mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value); } if (MALI_HW_CORE_NO_COUNTER != counter_src1) { mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, counter_src1); mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value); } #ifdef CONFIG_MALI400_HEATMAPS_ENABLED if(job->uargs.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_HEATMAP_ENABLE) { mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERFMON_CONTR, ((job->uargs.tilesx & 0x3FF) << 16) | 1); mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERFMON_BASE, job->uargs.heatmap_mem & 0xFFFFFFF8); } #endif /* CONFIG_MALI400_HEATMAPS_ENABLED */ MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description)); /* Adding barrier to make sure all rester writes are finished */ _mali_osk_write_mem_barrier(); /* This is the command that starts the core. */ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING); /* Adding barrier to make sure previous rester writes is finished */ _mali_osk_write_mem_barrier(); }
void mali_pp_print_state(struct mali_pp_core *core) { MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) )); }
static int mali_ump_map(struct mali_session_data *session, mali_mem_allocation *descriptor) { ump_dd_handle ump_mem; u32 nr_blocks; u32 i; ump_dd_physical_block *ump_blocks; struct mali_page_directory *pagedir; u32 offset = 0; u32 prop; _mali_osk_errcode_t err; MALI_DEBUG_ASSERT_POINTER(session); MALI_DEBUG_ASSERT_POINTER(descriptor); MALI_DEBUG_ASSERT(MALI_MEM_UMP == descriptor->type); ump_mem = descriptor->ump_mem.handle; MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem); nr_blocks = ump_dd_phys_block_count_get(ump_mem); if (nr_blocks == 0) { MALI_DEBUG_PRINT(1, ("No block count\n")); return -EINVAL; } ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks) * nr_blocks); if (NULL == ump_blocks) { return -ENOMEM; } if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks)) { _mali_osk_free(ump_blocks); return -EFAULT; } pagedir = session->page_directory; prop = descriptor->mali_mapping.properties; err = mali_mem_mali_map_prepare(descriptor); if (_MALI_OSK_ERR_OK != err) { MALI_DEBUG_PRINT(1, ("Mapping of UMP memory failed\n")); _mali_osk_free(ump_blocks); return -ENOMEM; } for (i = 0; i < nr_blocks; ++i) { u32 virt = descriptor->mali_mapping.addr + offset; MALI_DEBUG_PRINT(7, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size)); mali_mmu_pagedir_update(pagedir, virt, ump_blocks[i].addr, ump_blocks[i].size, prop); offset += ump_blocks[i].size; } if (descriptor->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) { u32 virt = descriptor->mali_mapping.addr + offset; /* Map in an extra virtual guard page at the end of the VMA */ MALI_DEBUG_PRINT(6, ("Mapping in extra guard page\n")); mali_mmu_pagedir_update(pagedir, virt, ump_blocks[0].addr, _MALI_OSK_MALI_PAGE_SIZE, prop); offset += _MALI_OSK_MALI_PAGE_SIZE; } _mali_osk_free(ump_blocks); return 0; }
void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) ) { MALI_DEBUG_ASSERT_POINTER( queue ); MALI_DEBUG_PRINT(6, ("Adding to wait queue %p\n", queue)); wait_event(queue->wait_queue, condition()); }
void mali_mmu_print_state(struct mali_mmu_core *mmu) { MALI_DEBUG_PRINT(2, ("MMU: State of %s is 0x%08x\n", mmu->hw_core.description, mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS))); }
_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_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx); session = (struct mali_session_data *)(uintptr_t)args->ctx; /* 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; }
struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource) { struct mali_l2_cache_core *cache = NULL; 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; 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(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND); if (NULL != cache->command_lock) { cache->counter_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER); if (NULL != cache->counter_lock) { if (_MALI_OSK_ERR_OK == mali_l2_cache_reset(cache)) { 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 reset L2 cache core %s\n", cache->hw_core.description)); } _mali_osk_lock_term(cache->counter_lock); } 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) { mali_bool ret = MALI_TRUE; gpu_power_state = 0; 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); return MALI_TRUE; #ifdef CONFIG_REGULATOR err_regulator: regulator_put(g3d_regulator); #endif err_clock_get: mali_clk_put(MALI_TRUE); return ret; }
mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz) { unsigned long rate = 0; mali_bool bis_vpll = MALI_TRUE; #ifndef CONFIG_VPLL_USE_FOR_TVENC bis_vpll = MALI_TRUE; #endif #if !MALI_DVFS_ENABLED clk = mali_gpu_clk; #endif _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); if (mali_clk_get(bis_vpll) == MALI_FALSE) return MALI_FALSE; rate = (unsigned long)clk * (unsigned long)mhz; MALI_DEBUG_PRINT(3,("= clk_set_rate : %d , %d \n",clk, mhz )); if (bis_vpll) { clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ); 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); } else { clk_set_parent(mali_parent_clock, mpll_clock); clk_set_parent(mali_clock, mali_parent_clock); } if (clk_enable(mali_clock) < 0) return MALI_FALSE; #if MALI_TIMELINE_PROFILING_ENABLED _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ, rate, 0, 0, 0, 0); #endif clk_set_rate(mali_clock, rate); rate = clk_get_rate(mali_clock); #if MALI_TIMELINE_PROFILING_ENABLED _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_EVENT_CHANNEL_SOFTWARE | MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ, rate, 1, 0, 0, 0); #endif if (bis_vpll) mali_gpu_clk = (int)(rate / mhz); else mali_gpu_clk = (int)((rate + 500000) / mhz); GPU_MHZ = mhz; MALI_DEBUG_PRINT(3,("= clk_get_rate: %d \n",mali_gpu_clk)); mali_clk_put(MALI_FALSE); _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); return MALI_TRUE; }
static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) #endif { int err; struct mali_session_data *session_data; #ifndef HAVE_UNLOCKED_IOCTL /* inode not used */ (void)inode; #endif MALI_DEBUG_PRINT(7, ("Ioctl received 0x%08X 0x%08lX\n", cmd, arg)); session_data = (struct mali_session_data *)filp->private_data; if (NULL == session_data) { MALI_DEBUG_PRINT(7, ("filp->private_data was NULL\n")); return -ENOTTY; } if (NULL == (void *)arg) { MALI_DEBUG_PRINT(7, ("arg was NULL\n")); return -ENOTTY; } switch(cmd) { case MALI_IOC_WAIT_FOR_NOTIFICATION: err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg); break; case MALI_IOC_GET_API_VERSION: err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg); break; case MALI_IOC_POST_NOTIFICATION: err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg); break; case MALI_IOC_GET_USER_SETTINGS: err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg); break; #if MALI_TIMELINE_PROFILING_ENABLED case MALI_IOC_PROFILING_START: err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg); break; case MALI_IOC_PROFILING_ADD_EVENT: err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg); break; case MALI_IOC_PROFILING_STOP: err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg); break; case MALI_IOC_PROFILING_GET_EVENT: err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg); break; case MALI_IOC_PROFILING_CLEAR: err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg); break; case MALI_IOC_PROFILING_GET_CONFIG: /* Deprecated: still compatible with get_user_settings */ err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg); break; case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: err = profiling_report_sw_counters_wrapper(session_data, (_mali_uk_sw_counters_report_s __user *)arg); break; #else case MALI_IOC_PROFILING_START: /* FALL-THROUGH */ case MALI_IOC_PROFILING_ADD_EVENT: /* FALL-THROUGH */ case MALI_IOC_PROFILING_STOP: /* FALL-THROUGH */ case MALI_IOC_PROFILING_GET_EVENT: /* FALL-THROUGH */ case MALI_IOC_PROFILING_CLEAR: /* FALL-THROUGH */ case MALI_IOC_PROFILING_GET_CONFIG: /* FALL-THROUGH */ case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: /* FALL-THROUGH */ MALI_DEBUG_PRINT(2, ("Profiling not supported\n")); err = -ENOTTY; break; #endif case MALI_IOC_MEM_INIT: err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg); break; case MALI_IOC_MEM_TERM: err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg); break; case MALI_IOC_MEM_MAP_EXT: err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg); break; case MALI_IOC_MEM_UNMAP_EXT: err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg); break; case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE: err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg); break; case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE: err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg); break; #if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 case MALI_IOC_MEM_ATTACH_UMP: err = mem_attach_ump_wrapper(session_data, (_mali_uk_attach_ump_mem_s __user *)arg); break; case MALI_IOC_MEM_RELEASE_UMP: err = mem_release_ump_wrapper(session_data, (_mali_uk_release_ump_mem_s __user *)arg); break; #else case MALI_IOC_MEM_ATTACH_UMP: case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */ MALI_DEBUG_PRINT(2, ("UMP not supported\n")); err = -ENOTTY; break; #endif #ifdef CONFIG_DMA_SHARED_BUFFER case MALI_IOC_MEM_ATTACH_DMA_BUF: err = mali_attach_dma_buf(session_data, (_mali_uk_attach_dma_buf_s __user *)arg); break; case MALI_IOC_MEM_RELEASE_DMA_BUF: err = mali_release_dma_buf(session_data, (_mali_uk_release_dma_buf_s __user *)arg); break; case MALI_IOC_MEM_DMA_BUF_GET_SIZE: err = mali_dma_buf_get_size(session_data, (_mali_uk_dma_buf_get_size_s __user *)arg); break; #else case MALI_IOC_MEM_DMA_BUF_GET_SIZE: /* FALL-THROUGH */ MALI_DEBUG_PRINT(2, ("DMA-BUF not supported\n")); err = -ENOTTY; break; #endif case MALI_IOC_PP_START_JOB: err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg); break; case MALI_IOC_PP_NUMBER_OF_CORES_GET: err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg); break; case MALI_IOC_PP_CORE_VERSION_GET: err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg); break; case MALI_IOC_PP_DISABLE_WB: err = pp_disable_wb_wrapper(session_data, (_mali_uk_pp_disable_wb_s __user *)arg); break; case MALI_IOC_GP2_START_JOB: err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg); break; case MALI_IOC_GP2_NUMBER_OF_CORES_GET: err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg); break; case MALI_IOC_GP2_CORE_VERSION_GET: err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg); break; case MALI_IOC_GP2_SUSPEND_RESPONSE: err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg); break; case MALI_IOC_VSYNC_EVENT_REPORT: err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg); break; case MALI_IOC_MEM_GET_BIG_BLOCK: /* Fallthrough */ case MALI_IOC_MEM_FREE_BIG_BLOCK: MALI_PRINT_ERROR(("Non-MMU mode is no longer supported.\n")); err = -ENOTTY; break; default: MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg)); err = -ENOTTY; }; return err; }
int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name) { int err = 0; struct device * mdev; device->mali_class = class_create(THIS_MODULE, mali_dev_name); if (IS_ERR(device->mali_class)) { err = PTR_ERR(device->mali_class); goto init_class_err; } mdev = device_create(device->mali_class, NULL, dev, NULL, mali_dev_name); if (IS_ERR(mdev)) { err = PTR_ERR(mdev); goto init_mdev_err; } mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL); if(ERR_PTR(-ENODEV) == mali_debugfs_dir) { /* Debugfs not supported. */ mali_debugfs_dir = NULL; } else { if(NULL != mali_debugfs_dir) { /* Debugfs directory created successfully; create files now */ struct dentry *mali_power_dir; struct dentry *mali_gp_dir; struct dentry *mali_pp_dir; struct dentry *mali_l2_dir; #if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED struct dentry *mali_profiling_dir; #endif mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir); if (mali_power_dir != NULL) { debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_events_fops); } mali_gp_dir = debugfs_create_dir("gp", mali_debugfs_dir); if (mali_gp_dir != NULL) { struct dentry *mali_gp_all_dir; u32 ci; struct mali_cluster *cluster; mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir); if (mali_gp_all_dir != NULL) { debugfs_create_file("counter_src0", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops); debugfs_create_file("counter_src1", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops); } ci = 0; cluster = mali_cluster_get_global_cluster(ci); while (NULL != cluster) { u32 gi = 0; struct mali_group *group = mali_cluster_get_group(cluster, gi); while (NULL != group) { struct mali_gp_core *gp_core = mali_group_get_gp_core(group); if (NULL != gp_core) { struct dentry *mali_gp_gpx_dir; mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir); if (NULL != mali_gp_gpx_dir) { debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops); debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops); } break; /* no need to look for any other GP cores */ } /* try next group */ gi++; group = mali_cluster_get_group(cluster, gi); } /* try next cluster */ ci++; cluster = mali_cluster_get_global_cluster(ci); } } mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir); if (mali_pp_dir != NULL) { struct dentry *mali_pp_all_dir; u32 ci; struct mali_cluster *cluster; mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir); if (mali_pp_all_dir != NULL) { debugfs_create_file("counter_src0", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops); debugfs_create_file("counter_src1", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops); } ci = 0; cluster = mali_cluster_get_global_cluster(ci); while (NULL != cluster) { u32 gi = 0; struct mali_group *group = mali_cluster_get_group(cluster, gi); while (NULL != group) { struct mali_pp_core *pp_core = mali_group_get_pp_core(group); if (NULL != pp_core) { char buf[16]; struct dentry *mali_pp_ppx_dir; _mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core)); mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir); if (NULL != mali_pp_ppx_dir) { debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops); debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops); } } /* try next group */ gi++; group = mali_cluster_get_group(cluster, gi); } /* try next cluster */ ci++; cluster = mali_cluster_get_global_cluster(ci); } } mali_l2_dir = debugfs_create_dir("l2", mali_debugfs_dir); if (mali_l2_dir != NULL) { struct dentry *mali_l2_all_dir; u32 l2_id; struct mali_l2_cache_core *l2_cache; mali_l2_all_dir = debugfs_create_dir("all", mali_l2_dir); if (mali_l2_all_dir != NULL) { debugfs_create_file("counter_src0", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops); debugfs_create_file("counter_src1", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops); } l2_id = 0; l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); while (NULL != l2_cache) { char buf[16]; struct dentry *mali_l2_l2x_dir; _mali_osk_snprintf(buf, sizeof(buf), "l2%u", l2_id); mali_l2_l2x_dir = debugfs_create_dir(buf, mali_l2_dir); if (NULL != mali_l2_l2x_dir) { debugfs_create_file("counter_src0", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src0_fops); debugfs_create_file("counter_src1", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src1_fops); } /* try next L2 */ l2_id++; l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id); } } debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops); #if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir); if (mali_profiling_dir != NULL) { struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir); if (mali_profiling_proc_dir != NULL) { struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir); if (mali_profiling_proc_default_dir != NULL) { debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, (void*)_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, &user_settings_fops); } } debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops); debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops); } #endif #if MALI_STATE_TRACKING debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops); #endif if (mali_sysfs_user_settings_register()) { /* Failed to create the debugfs entries for the user settings DB. */ MALI_DEBUG_PRINT(2, ("Failed to create user setting debugfs files. Ignoring...\n")); } } } /* Success! */ return 0; /* Error handling */ init_mdev_err: class_destroy(device->mali_class); init_class_err: return err; }
struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual, u32 bcast_id) { struct mali_pp_core* core = NULL; MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description)); MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base)); if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES) { MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n")); return NULL; } core = _mali_osk_malloc(sizeof(struct mali_pp_core)); if (NULL != core) { core->core_id = mali_global_num_pp_cores; core->bcast_id = bcast_id; if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK)) { _mali_osk_errcode_t ret; if (!is_virtual) { ret = mali_pp_reset(core); } else { ret = _MALI_OSK_ERR_OK; } if (_MALI_OSK_ERR_OK == ret) { ret = mali_group_add_pp_core(group, core); if (_MALI_OSK_ERR_OK == ret) { /* Setup IRQ handlers (which will do IRQ probing if needed) */ MALI_DEBUG_ASSERT(!is_virtual || -1 != resource->irq); core->irq = _mali_osk_irq_init(resource->irq, mali_group_upper_half_pp, group, mali_pp_irq_probe_trigger, mali_pp_irq_probe_ack, core, resource->description); if (NULL != core->irq) { mali_global_pp_cores[mali_global_num_pp_cores] = core; mali_global_num_pp_cores++; return core; } else { MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description)); } mali_group_remove_pp_core(group); } else { MALI_PRINT_ERROR(("Mali PP: Failed to add core %s to group\n", core->hw_core.description)); } } mali_hw_core_delete(&core->hw_core); } _mali_osk_free(core); } else { MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n")); } return NULL; }
static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info) { block_allocator * info; u32 left; block_info * last_allocated = NULL; mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE; block_allocator_allocation *ret_allocation; MALI_DEBUG_ASSERT_POINTER(ctx); MALI_DEBUG_ASSERT_POINTER(descriptor); MALI_DEBUG_ASSERT_POINTER(offset); MALI_DEBUG_ASSERT_POINTER(alloc_info); info = (block_allocator*)ctx; left = descriptor->size - *offset; MALI_DEBUG_ASSERT(0 != left); if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE; ret_allocation = _mali_osk_malloc( sizeof(block_allocator_allocation) ); if ( NULL == ret_allocation ) { /* Failure; try another allocator by returning MALI_MEM_ALLOC_NONE */ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); return result; } ret_allocation->start_offset = *offset; ret_allocation->mapping_length = 0; while ((left > 0) && (info->first_free)) { block_info * block; u32 phys_addr; u32 padding; u32 current_mapping_size; block = info->first_free; info->first_free = info->first_free->next; block->next = last_allocated; last_allocated = block; phys_addr = get_phys(info, block); padding = *offset & (MALI_BLOCK_SIZE-1); if (MALI_BLOCK_SIZE - padding < left) { current_mapping_size = MALI_BLOCK_SIZE - padding; } else { current_mapping_size = left; } if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, phys_addr + padding, info->cpu_usage_adjust, current_mapping_size)) { MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n")); result = MALI_MEM_ALLOC_INTERNAL_FAILURE; mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->start_offset, ret_allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0); /* release all memory back to the pool */ while (last_allocated) { /* This relinks every block we've just allocated back into the free-list */ block = last_allocated->next; last_allocated->next = info->first_free; info->first_free = last_allocated; last_allocated = block; } break; } *offset += current_mapping_size; left -= current_mapping_size; ret_allocation->mapping_length += current_mapping_size; } _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW); if (last_allocated) { if (left) result = MALI_MEM_ALLOC_PARTIAL; else result = MALI_MEM_ALLOC_FINISHED; /* Record all the information about this allocation */ ret_allocation->last_allocated = last_allocated; ret_allocation->engine = engine; ret_allocation->descriptor = descriptor; alloc_info->ctx = info; alloc_info->handle = ret_allocation; alloc_info->release = block_allocator_release; } else { /* Free the allocation information - nothing to be passed back */ _mali_osk_free( ret_allocation ); } return result; }
static void mali_pp_print_registers(struct mali_pp_core *core) { MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC))); MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE))); }
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, _MALI_OSK_LOCK_ORDER_MEM_INFO); 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; }
void mali_pm_runtime_suspend(void) { MALI_DEBUG_PRINT(2, ("Mali PM: Runtime suspend\n")); mali_group_power_off(); mali_power_on = MALI_FALSE; }
/* Register the platform device */ err = platform_device_register(&mali_gpu_device); if (0 == err) { #ifdef CONFIG_PM_RUNTIME #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000); pm_runtime_use_autosuspend(&(mali_gpu_device.dev)); #endif pm_runtime_enable(&(mali_gpu_device.dev)); #endif MALI_DEBUG_ASSERT(0 < num_pp_cores); mali_core_scaling_init(num_pp_cores); return 0; } return err; } void mali_platform_device_unregister(void) { MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n")); mali_core_scaling_term(); platform_device_unregister(&mali_gpu_device); platform_device_put(&mali_gpu_device); #if defined(CONFIG_ARCH_REALVIEW) mali_write_phys(0xC0010020, 0x9); /* Restore default (legacy) memory mapping */ #endif } static void mali_platform_device_release(struct device *device) { MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n")); } #else /* CONFIG_MALI_DT */ int mali_platform_device_init(struct platform_device *device) { int num_pp_cores; int err = -1; #if defined(CONFIG_ARCH_REALVIEW) u32 m400_gp_version; #endif /* Detect present Mali GPU and connect the correct resources to the device */ #if defined(CONFIG_ARCH_VEXPRESS) #if defined(CONFIG_ARM64) if (mali_read_phys(0x6F000000) == 0x40601450) { MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP6 device\n")); num_pp_cores = 6; } #else if (mali_read_phys(0xFC000000) == 0x00000450) { MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP8 device\n")); num_pp_cores = 8; } else if (mali_read_phys(0xFC000000) == 0x40400450) { MALI_DEBUG_PRINT(4, ("Registering Mali-450 MP4 device\n")); num_pp_cores = 4; } #endif #elif defined(CONFIG_ARCH_REALVIEW) m400_gp_version = mali_read_phys(0xC000006C); if ((m400_gp_version & 0xFFFF0000) == 0x0C070000) { MALI_DEBUG_PRINT(4, ("Registering Mali-300 device\n")); num_pp_cores = 1; mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ } else if ((m400_gp_version & 0xFFFF0000) == 0x0B070000) { u32 fpga_fw_version = mali_read_phys(0xC0010000); if (fpga_fw_version == 0x130C008F || fpga_fw_version == 0x110C008F) { /* Mali-400 MP1 r1p0 or r1p1 */ MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP1 device\n")); num_pp_cores = 1; mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ } else if (fpga_fw_version == 0x130C000F) { /* Mali-400 MP2 r1p1 */ MALI_DEBUG_PRINT(4, ("Registering Mali-400 MP2 device\n")); num_pp_cores = 2; mali_write_phys(0xC0010020, 0xA); /* Enable direct memory mapping for FPGA */ } } #endif err = platform_device_add_data(device, &mali_gpu_data, sizeof(mali_gpu_data)); if (0 == err) { #ifdef CONFIG_PM_RUNTIME #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) pm_runtime_set_autosuspend_delay(&(device->dev), 1000); pm_runtime_use_autosuspend(&(device->dev)); #endif pm_runtime_enable(&(device->dev)); #endif MALI_DEBUG_ASSERT(0 < num_pp_cores); mali_core_scaling_init(num_pp_cores); } return err; }
static void mali_platform_device_release(struct device *device) { MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n")); }
_mali_osk_errcode_t mali_mmu_pagedir_unmap(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); u32 left = size; int i; #ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 mali_bool pd_changed = MALI_FALSE; u32 pages_to_invalidate[3]; /* hard-coded to 3: max two pages from the PT level plus max one page from PD level */ u32 num_pages_inv = 0; #endif /* For all page directory entries in range. */ for (i = first_pde; i <= last_pde; i++) { u32 size_in_pde, offset; MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[i]); MALI_DEBUG_ASSERT(0 != pagedir->page_entries_usage_count[i]); /* Offset into page table, 0 if mali_address is 4MiB aligned */ offset = (mali_address & (MALI_MMU_VIRTUAL_PAGE_SIZE - 1)); if (left < MALI_MMU_VIRTUAL_PAGE_SIZE - offset) { size_in_pde = left; } else { size_in_pde = MALI_MMU_VIRTUAL_PAGE_SIZE - offset; } pagedir->page_entries_usage_count[i]--; /* If entire page table is unused, free it */ if (0 == pagedir->page_entries_usage_count[i]) { u32 page_address; MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n")); /* last reference removed, no need to zero out each PTE */ page_address = MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32))); pagedir->page_entries_mapped[i] = NULL; _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), 0); mali_mmu_release_table_page(page_address); #ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 pd_changed = MALI_TRUE; #endif } else { #ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i); num_pages_inv++; MALI_DEBUG_ASSERT(num_pages_inv<3); #endif /* If part of the page table is still in use, zero the relevant PTEs */ mali_mmu_zero_pte(pagedir->page_entries_mapped[i], mali_address, size_in_pde); } left -= size_in_pde; mali_address += size_in_pde; } _mali_osk_write_mem_barrier(); #ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2 /* L2 pages invalidation */ if (MALI_TRUE == pd_changed) { pages_to_invalidate[num_pages_inv] = pagedir->page_directory; num_pages_inv++; MALI_DEBUG_ASSERT(num_pages_inv<3); } if (_MALI_PRODUCT_ID_MALI200 != mali_kernel_core_get_product_id()) { mali_cluster_invalidate_pages(pages_to_invalidate, num_pages_inv); } #endif MALI_SUCCESS; }
/** @note munmap handler is done by vma close handler */ int mali_mmap(struct file *filp, struct vm_area_struct *vma) { struct mali_session_data *session; mali_mem_allocation *descriptor = NULL; u32 size = vma->vm_end - vma->vm_start; u32 mali_addr = vma->vm_pgoff << PAGE_SHIFT; session = (struct mali_session_data *)filp->private_data; if (NULL == session) { MALI_PRINT_ERROR(("mmap called without any session data available\n")); return -EFAULT; } MALI_DEBUG_PRINT(4, ("MMap() handler: start=0x%08X, phys=0x%08X, size=0x%08X vma->flags 0x%08x\n", (unsigned int)vma->vm_start, (unsigned int)(vma->vm_pgoff << PAGE_SHIFT), (unsigned int)(vma->vm_end - vma->vm_start), vma->vm_flags)); /* Set some bits which indicate that, the memory is IO memory, meaning * that no paging is to be performed and the memory should not be * included in crash dumps. And that the memory is reserved, meaning * that it's present and can never be paged out (see also previous * entry) */ vma->vm_flags |= VM_IO; vma->vm_flags |= VM_DONTCOPY; vma->vm_flags |= VM_PFNMAP; #if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) vma->vm_flags |= VM_RESERVED; #else vma->vm_flags |= VM_DONTDUMP; vma->vm_flags |= VM_DONTEXPAND; #endif vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */ /// since in ALPS project, especially low-memory segment, /// it would be hard to allocate a 256KB(2^6 * 4K) physical continuous memory due to memory fragmentation /// even 32KB conti. phy. might be hard to allocate. And it might cause ANR or KE /// avoid using block allocate(256KB) directly /// descriptor = mali_mem_block_alloc(mali_addr, size, vma, session); if (NULL == descriptor) { descriptor = mali_mem_os_alloc(mali_addr, size, vma, session); if (NULL == descriptor) { MALI_DEBUG_PRINT(3, ("MMAP failed\n")); return -ENOMEM; } } MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic); vma->vm_private_data = (void*)descriptor; /* Put on descriptor map */ if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &descriptor->id)) { _mali_osk_mutex_wait(session->memory_lock); mali_mem_os_release(descriptor); _mali_osk_mutex_signal(session->memory_lock); return -EFAULT; } return 0; }
static void mali_meson_poweron(int first_poweron) { unsigned long flags; u32 p, p_aligned; dma_addr_t p_phy; int i; unsigned int_mask; if(!first_poweron) { if ((last_power_mode != -1) && (last_power_mode != MALI_POWER_MODE_DEEP_SLEEP)) { MALI_DEBUG_PRINT(3, ("Maybe your system not deep sleep now.......\n")); //printk("Maybe your system not deep sleep now.......\n"); return; } } MALI_DEBUG_PRINT(2, ("mali_meson_poweron: Mali APB bus accessing\n")); if (READ_MALI_REG(MALI_PP_PP_VERSION) != MALI_PP_PP_VERSION_MAGIC) { MALI_DEBUG_PRINT(3, ("mali_meson_poweron: Mali APB bus access failed\n")); //printk("mali_meson_poweron: Mali APB bus access failed."); return; } MALI_DEBUG_PRINT(2, ("..........accessing done.\n")); if (READ_MALI_REG(MALI_MMU_DTE_ADDR) != 0) { MALI_DEBUG_PRINT(3, ("mali_meson_poweron: Mali is not really powered off\n")); //printk("mali_meson_poweron: Mali is not really powered off."); return; } p = (u32)kcalloc(4096 * 4, 1, GFP_KERNEL); if (!p) { printk("mali_meson_poweron: NOMEM in meson_poweron\n"); return; } p_aligned = __ALIGN_MASK(p, 4096); /* DTE */ *(u32 *)(p_aligned) = (virt_to_phys((void *)p_aligned) + OFFSET_MMU_PTE) | MMU_FLAG_DTE_PRESENT; /* PTE */ for (i=0; i<1024; i++) { *(u32 *)(p_aligned + OFFSET_MMU_PTE + i*4) = (virt_to_phys((void *)p_aligned) + OFFSET_MMU_VIRTUAL_ZERO + 4096 * i) | MMU_FLAG_PTE_PAGE_PRESENT | MMU_FLAG_PTE_RD_PERMISSION; } /* command & data */ memcpy((void *)(p_aligned + OFFSET_MMU_VIRTUAL_ZERO), poweron_data, 4096); p_phy = dma_map_single(NULL, (void *)p_aligned, 4096 * 3, DMA_TO_DEVICE); /* Set up Mali GP MMU */ WRITE_MALI_REG(MALI_MMU_DTE_ADDR, p_phy); WRITE_MALI_REG(MALI_MMU_CMD, 0); if ((READ_MALI_REG(MALI_MMU_STATUS) & 1) != 1) printk("mali_meson_poweron: MMU enabling failed.\n"); /* Set up Mali command registers */ WRITE_MALI_REG(MALI_APB_GP_VSCL_START, 0); WRITE_MALI_REG(MALI_APB_GP_VSCL_END, 0x38); spin_lock_irqsave(&lock, flags); int_mask = READ_MALI_REG(MALI_APB_GP_INT_MASK); WRITE_MALI_REG(MALI_APB_GP_INT_CLEAR, 0x707bff); WRITE_MALI_REG(MALI_APB_GP_INT_MASK, 0); /* Start GP */ WRITE_MALI_REG(MALI_APB_GP_CMD, 1); for (i = 0; i<100; i++) udelay(500); /* check Mali GP interrupt */ if (READ_MALI_REG(MALI_APB_GP_INT_RAWSTAT) & 0x707bff) printk("mali_meson_poweron: Interrupt received.\n"); else printk("mali_meson_poweron: No interrupt received.\n"); /* force reset GP */ WRITE_MALI_REG(MALI_APB_GP_CMD, 1 << 5); /* stop MMU paging and reset */ WRITE_MALI_REG(MALI_MMU_CMD, 1); WRITE_MALI_REG(MALI_MMU_CMD, 6); for (i = 0; i<100; i++) udelay(500); WRITE_MALI_REG(MALI_APB_GP_INT_CLEAR, 0x3ff); WRITE_MALI_REG(MALI_MMU_INT_CLEAR, INT_ALL); WRITE_MALI_REG(MALI_MMU_INT_MASK, 0); WRITE_MALI_REG(MALI_APB_GP_INT_CLEAR, 0x707bff); WRITE_MALI_REG(MALI_APB_GP_INT_MASK, int_mask); spin_unlock_irqrestore(&lock, flags); dma_unmap_single(NULL, p_phy, 4096 * 3, DMA_TO_DEVICE); kfree((void *)p); /* Mali revision detection */ if (last_power_mode == -1) mali_revb_flag = mali_meson_is_revb(); }
static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { char buf[64]; unsigned long val; int ret; if (cnt >= sizeof(buf)) { return -EINVAL; } if (copy_from_user(&buf, ubuf, cnt)) { return -EFAULT; } buf[cnt] = 0; ret = strict_strtoul(buf, 10, &val); if (ret < 0) { return ret; } if (val != 0) { u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */ /* check if we are already recording */ if (MALI_TRUE == _mali_profiling_is_recording()) { MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n")); return -EFAULT; } /* check if we need to clear out an old recording first */ if (MALI_TRUE == _mali_profiling_have_recording()) { if (_MALI_OSK_ERR_OK != _mali_profiling_clear()) { MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n")); return -EFAULT; } } /* start recording profiling data */ if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit)) { MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n")); return -EFAULT; } MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit)); } else { /* stop recording profiling data */ u32 count = 0; if (_MALI_OSK_ERR_OK != _mali_profiling_stop(&count)) { MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n")); return -EFAULT; } MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count)); } *ppos += cnt; return cnt; }
_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode) { unsigned long flags; unsigned cpu_divider, mali_divider; unsigned ddr_pll_setting, sys_pll_setting; unsigned cpu_freq, ddr_freq; int mali_flag; MALI_DEBUG_PRINT(3, ( "mali_platform_power_mode_change power_mode=%d\n", power_mode)); switch (power_mode) { case MALI_POWER_MODE_LIGHT_SLEEP: case MALI_POWER_MODE_DEEP_SLEEP: /* Turn off mali clock gating */ if (mali_clk) { mali_clk->disable(mali_clk); } else { spin_lock_irqsave(&lock, flags); CLEAR_CBUS_REG_MASK(HHI_MALI_CLK_CNTL, 1 << 8); spin_unlock_irqrestore(&lock, flags); } break; case MALI_POWER_MODE_ON: /* Turn on MALI clock gating */ if (mali_clk) { mali_clk->enable(mali_clk); } else { spin_lock_irqsave(&lock, flags); CLEAR_CBUS_REG_MASK(HHI_MALI_CLK_CNTL, 1 << 8); sys_pll_setting = READ_MPEG_REG(HHI_SYS_PLL_CNTL); cpu_freq = ((sys_pll_setting&0x1ff)*24)>>(sys_pll_setting>>16); // assume 24M xtal cpu_divider = READ_MPEG_REG_BITS(HHI_SYS_CPU_CLK_CNTL, 2, 2); if (cpu_divider == 3) cpu_divider = 2; // now fix at /4 cpu_freq >>= cpu_divider; ddr_pll_setting = READ_MPEG_REG(HHI_DDR_PLL_CNTL); ddr_freq = ((ddr_pll_setting&0x1ff)*24)>>((ddr_pll_setting>>16)&3); mali_divider = 1; while ((mali_divider * cpu_freq < ddr_freq) || (264 * mali_divider < ddr_freq)) // assume mali max 264M mali_divider++; mali_flag = ((mali_divider-1) != (READ_MPEG_REG(HHI_MALI_CLK_CNTL)&0x7f)); if (mali_flag){ WRITE_CBUS_REG(HHI_MALI_CLK_CNTL, (3 << 9) | // select ddr pll as clock source ((mali_divider-1) << 0)); // ddr clk / divider READ_CBUS_REG(HHI_MALI_CLK_CNTL); // delay } SET_CBUS_REG_MASK(HHI_MALI_CLK_CNTL, 1 << 8); spin_unlock_irqrestore(&lock, flags); if (mali_flag) MALI_DEBUG_PRINT(3, ("(CTS_MALI_CLK) = %d/%d = %dMHz --- when mali gate on\n", ddr_freq, mali_divider, ddr_freq/mali_divider)); } mali_meson_poweron(0); break; } last_power_mode = power_mode; MALI_SUCCESS; }
void mali_mmu_page_fault_done(struct mali_mmu_core *mmu) { MALI_DEBUG_PRINT(4, ("Mali MMU: %s: Leaving page fault mode\n", mmu->hw_core.description)); mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE); }
static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend) { MALI_ASSERT_GROUP_LOCKED(core->group); if (NULL != core->running_job) { u32 val0 = 0; u32 val1 = 0; #if MALI_TIMELINE_PROFILING_ENABLED u32 event_id; #endif #if PROFILING_PRINT_L2_HITRATE_ON_GP_FINISH { u32 src0, value0, src1, value1, sum, per_thousand, per_thousand_now, diff0, diff1; static u32 print_nr=0; static u32 prev0=0; static u32 prev1=0; if ( !(++print_nr&511) ) { mali_l2_cache_core_get_counter_values(mali_l2_cache_core_get_glob_l2_core(0), &src0, &value0, &src1, &value1); MALI_DEBUG_ASSERT( src0==20 ); /* Read hits */ MALI_DEBUG_ASSERT( src1==21 ); /* Read misses */ sum = value0+value1; if ( sum > 1000000 ) { per_thousand = value0 / (sum/1000); } else { per_thousand = (value0*1000) / (sum); } diff0 = value0-prev0; diff1 = value1-prev1; sum = diff0 + diff1 ; if ( sum > 1000000 ) { per_thousand_now = diff0 / (sum/1000); } else { per_thousand_now = (diff0*1000) / (sum); } prev0=value0; prev1=value1; if (per_thousand_now<=1000) { MALI_DEBUG_PRINT(2, ("Mali L2: Read hits/misses: %d/%d = %d thousand_parts total, since previous: %d\n", value0, value1, per_thousand, per_thousand_now)); } } } #endif if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used) { val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE); if (mali_gp_job_get_perf_counter_flag(core->running_job) && _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_gp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used) { /* We retrieved the counter that user space asked for, so return the value through the job object */ mali_gp_job_set_perf_counter_value0(core->running_job, val0); } else { /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */ mali_gp_job_set_perf_counter_value0(core->running_job, MALI_HW_CORE_INVALID_VALUE); } #if MALI_TIMELINE_PROFILING_ENABLED _mali_osk_profiling_report_hw_counter(COUNTER_VP_C0, val0); #endif } if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used) { val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE); if (mali_gp_job_get_perf_counter_flag(core->running_job) && _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_gp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used) { /* We retrieved the counter that user space asked for, so return the value through the job object */ mali_gp_job_set_perf_counter_value1(core->running_job, val1); } else { /* User space asked for a counter, but this is not what we retrieved (overridden by counter src set on core) */ mali_gp_job_set_perf_counter_value1(core->running_job, MALI_HW_CORE_INVALID_VALUE); } #if MALI_TIMELINE_PROFILING_ENABLED _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, val1); #endif } #if MALI_TIMELINE_PROFILING_ENABLED if (MALI_TRUE == suspend) { event_id = MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0); } else { event_id = MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0); } _mali_osk_profiling_add_event(event_id, val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0); #endif mali_gp_job_set_current_heap_addr(core->running_job, mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR)); if (MALI_TRUE != suspend) { /* We are no longer running a job... */ core->running_job = NULL; _mali_osk_timer_del(core->timeout_timer); } } }