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 {