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;
}
示例#2
0
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;

}
示例#8
0
_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);
}
示例#9
0
_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, &notification);
	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);
}
示例#17
0
_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);
}
示例#20
0
_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;   
}
示例#23
0
_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;
}
示例#24
0
_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);
}
示例#25
0
/* 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;
}
示例#26
0
_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);
}