Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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();
}
Exemplo n.º 7
0
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) ));
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
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)));
}
Exemplo n.º 11
0
_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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 21
0
void mali_pm_runtime_suspend(void)
{
	MALI_DEBUG_PRINT(2, ("Mali PM: Runtime suspend\n"));
	mali_group_power_off();
	mali_power_on = MALI_FALSE;
}
Exemplo n.º 22
0
	/* 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;
}
Exemplo n.º 23
0
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;
}
Exemplo n.º 25
0
/** @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;
}
Exemplo n.º 26
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;
}
Exemplo n.º 28
0
_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);
}
Exemplo n.º 30
0
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);
		}
	}
}