Esempio n. 1
0
void mali_pm_core_event(enum mali_core_event core_event)
{
	MALI_DEBUG_ASSERT(MALI_CORE_EVENT_GP_START == core_event ||
	                  MALI_CORE_EVENT_PP_START == core_event ||
	                  MALI_CORE_EVENT_GP_STOP  == core_event ||
	                  MALI_CORE_EVENT_PP_STOP  == core_event);

	if (MALI_CORE_EVENT_GP_START == core_event || MALI_CORE_EVENT_PP_START == core_event)
	{      
		_mali_osk_pm_dev_ref_add();
		
		if (mali_utilization_enabled())
		{
			mali_utilization_core_start(_mali_osk_time_get_ns());
		}
	}
	else
	{
		_mali_osk_pm_dev_ref_dec();		
		if (mali_utilization_enabled())
		{
			mali_utilization_core_end(_mali_osk_time_get_ns());
		}
	}
}
static void calculate_gpu_utilization(void* arg)
{
	u64 time_now;
	u64 time_period;
	u32 leading_zeroes;
	u32 shift_val;
	u32 work_normalized;
	u32 period_normalized;
	u32 utilization;

	_mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);

	if (accumulated_work_time == 0 && work_start_time == 0)
	{
		/* Don't reschedule timer, this will be started if new work arrives */
		timer_running = MALI_FALSE;

		_mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);

		/* No work done for this period, report zero usage */
		mali_gpu_utilization_handler(0);

		return;
	}

	time_now = _mali_osk_time_get_ns();
	time_period = time_now - period_start_time;

	/* If we are currently busy, update working period up to now */
	if (work_start_time != 0)
	{
		accumulated_work_time += (time_now - work_start_time);
		work_start_time = time_now;
	}

	/*
	 * We have two 64-bit values, a dividend and a divisor.
	 * To avoid dependencies to a 64-bit divider, we shift down the two values
	 * equally first.
	 * We shift the dividend up and possibly the divisor down, making the result X in 256.
	 */

	/* Shift the 64-bit values down so they fit inside a 32-bit integer */
	leading_zeroes = _mali_osk_clz((u32)(time_period >> 32));
	shift_val = 32 - leading_zeroes;
	work_normalized = (u32)(accumulated_work_time >> shift_val);
	period_normalized = (u32)(time_period >> shift_val);

	/*
	 * Now, we should report the usage in parts of 256
	 * this means we must shift up the dividend or down the divisor by 8
	 * (we could do a combination, but we just use one for simplicity,
	 * but the end result should be good enough anyway)
	 */
	if (period_normalized > 0x00FFFFFF)
	{
		/* The divisor is so big that it is safe to shift it down */
		period_normalized >>= 8;
	}
static void calculate_gpu_utilization(void *arg)
{
	u64 time_now;
	u64 time_period;
	u32 leading_zeroes;
	u32 shift_val;
	u32 work_normalized_gpu;
	u32 work_normalized_gp;
	u32 work_normalized_pp;
	u32 period_normalized;
	u32 utilization_gpu;
	u32 utilization_gp;
	u32 utilization_pp;
#if defined(CONFIG_MALI400_POWER_PERFORMANCE_POLICY)
	u32 window_render_fps;
#endif

	_mali_osk_spinlock_irq_lock(time_data_lock);

	if (accumulated_work_time_gpu == 0 && work_start_time_gpu == 0) {
		/*
		 * No work done for this period
		 * - No need to reschedule timer
		 * - Report zero usage
		 */
		timer_running = MALI_FALSE;

		last_utilization_gpu = 0;
		last_utilization_gp = 0;
		last_utilization_pp = 0;

		_mali_osk_spinlock_irq_unlock(time_data_lock);

		if (NULL != mali_utilization_callback) {
			struct mali_gpu_utilization_data data = { 0, };
			mali_utilization_callback(&data);
		}

		mali_scheduler_hint_disable(MALI_SCHEDULER_HINT_GP_BOUND);

		return;
	}

	time_now = _mali_osk_time_get_ns();

	time_period = time_now - period_start_time;

	/* If we are currently busy, update working period up to now */
	if (work_start_time_gpu != 0) {
		accumulated_work_time_gpu += (time_now - work_start_time_gpu);
		work_start_time_gpu = time_now;

		/* GP and/or PP will also be busy if the GPU is busy at this point */

		if (work_start_time_gp != 0) {
			accumulated_work_time_gp += (time_now - work_start_time_gp);
			work_start_time_gp = time_now;
		}

		if (work_start_time_pp != 0) {
			accumulated_work_time_pp += (time_now - work_start_time_pp);
			work_start_time_pp = time_now;
		}
	}

	/*
	 * We have two 64-bit values, a dividend and a divisor.
	 * To avoid dependencies to a 64-bit divider, we shift down the two values
	 * equally first.
	 * We shift the dividend up and possibly the divisor down, making the result X in 256.
	 */

	/* Shift the 64-bit values down so they fit inside a 32-bit integer */
	leading_zeroes = _mali_osk_clz((u32)(time_period >> 32));
	shift_val = 32 - leading_zeroes;
	work_normalized_gpu = (u32)(accumulated_work_time_gpu >> shift_val);
	work_normalized_gp = (u32)(accumulated_work_time_gp >> shift_val);
	work_normalized_pp = (u32)(accumulated_work_time_pp >> shift_val);
	period_normalized = (u32)(time_period >> shift_val);

	/*
	 * Now, we should report the usage in parts of 256
	 * this means we must shift up the dividend or down the divisor by 8
	 * (we could do a combination, but we just use one for simplicity,
	 * but the end result should be good enough anyway)
	 */
	if (period_normalized > 0x00FFFFFF) {
		/* The divisor is so big that it is safe to shift it down */
		period_normalized >>= 8;
	} else {
struct mali_gpu_utilization_data *mali_utilization_calculate(u64 *start_time, u64 *time_period, mali_bool *need_add_timer)
{
	u64 time_now;
	u32 leading_zeroes;
	u32 shift_val;
	u32 work_normalized_gpu;
	u32 work_normalized_gp;
	u32 work_normalized_pp;
	u32 period_normalized;
	u32 utilization_gpu;
	u32 utilization_gp;
	u32 utilization_pp;

	mali_utilization_data_lock();

	time_now = _mali_osk_time_get_ns();

	*time_period = time_now - *start_time;

	if (accumulated_work_time_gpu == 0 && work_start_time_gpu == 0) {
		mali_control_timer_pause();
		/*
		 * No work done for this period
		 * - No need to reschedule timer
		 * - Report zero usage
		 */
		last_utilization_gpu = 0;
		last_utilization_gp = 0;
		last_utilization_pp = 0;

		mali_util_data.utilization_gpu = last_utilization_gpu;
		mali_util_data.utilization_gp = last_utilization_gp;
		mali_util_data.utilization_pp = last_utilization_pp;

		mali_utilization_data_unlock();

		*need_add_timer = MALI_FALSE;

		mali_executor_hint_disable(MALI_EXECUTOR_HINT_GP_BOUND);

		MALI_DEBUG_PRINT(4, ("last_utilization_gpu = %d \n", last_utilization_gpu));
		MALI_DEBUG_PRINT(4, ("last_utilization_gp = %d \n", last_utilization_gp));
		MALI_DEBUG_PRINT(4, ("last_utilization_pp = %d \n", last_utilization_pp));

		return &mali_util_data;
	}

	/* If we are currently busy, update working period up to now */
	if (work_start_time_gpu != 0) {
		accumulated_work_time_gpu += (time_now - work_start_time_gpu);
		work_start_time_gpu = time_now;

		/* GP and/or PP will also be busy if the GPU is busy at this point */

		if (work_start_time_gp != 0) {
			accumulated_work_time_gp += (time_now - work_start_time_gp);
			work_start_time_gp = time_now;
		}

		if (work_start_time_pp != 0) {
			accumulated_work_time_pp += (time_now - work_start_time_pp);
			work_start_time_pp = time_now;
		}
	}

	/*
	 * We have two 64-bit values, a dividend and a divisor.
	 * To avoid dependencies to a 64-bit divider, we shift down the two values
	 * equally first.
	 * We shift the dividend up and possibly the divisor down, making the result X in 256.
	 */

	/* Shift the 64-bit values down so they fit inside a 32-bit integer */
	leading_zeroes = _mali_osk_clz((u32)(*time_period >> 32));
	shift_val = 32 - leading_zeroes;
	work_normalized_gpu = (u32)(accumulated_work_time_gpu >> shift_val);
	work_normalized_gp = (u32)(accumulated_work_time_gp >> shift_val);
	work_normalized_pp = (u32)(accumulated_work_time_pp >> shift_val);
	period_normalized = (u32)(*time_period >> shift_val);

	/*
	 * Now, we should report the usage in parts of 256
	 * this means we must shift up the dividend or down the divisor by 8
	 * (we could do a combination, but we just use one for simplicity,
	 * but the end result should be good enough anyway)
	 */
	if (period_normalized > 0x00FFFFFF) {
		/* The divisor is so big that it is safe to shift it down */
		period_normalized >>= 8;
	} else {