1/* 2 * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved. 3 * 4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2 5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. 6 * 7 * A copy of the licence is included with the program, and can also be obtained from Free Software 8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 9 */ 10 11#include "mali_kernel_utilization.h" 12#include "mali_osk.h" 13#include "mali_osk_mali.h" 14#include "mali_kernel_common.h" 15#include "mali_session.h" 16#include "mali_dvfs_policy.h" 17#include "mali_control_timer.h" 18 19static u64 period_start_time = 0; 20 21static _mali_osk_timer_t *mali_control_timer = NULL; 22static mali_bool timer_running = MALI_FALSE; 23 24static u32 mali_control_timeout = 1000; 25 26void mali_control_timer_add(u32 timeout) 27{ 28 _mali_osk_timer_add(mali_control_timer, _mali_osk_time_mstoticks(timeout)); 29} 30 31static void mali_control_timer_callback(void *arg) 32{ 33 if (mali_utilization_enabled()) { 34 struct mali_gpu_utilization_data *util_data = NULL; 35 u64 time_period = 0; 36 mali_bool need_add_timer = MALI_TRUE; 37 38 /* Calculate gpu utilization */ 39 util_data = mali_utilization_calculate(&period_start_time, &time_period, &need_add_timer); 40 41 if (util_data) { 42#if defined(CONFIG_MALI_DVFS) 43 mali_dvfs_policy_realize(util_data, time_period); 44#else 45 mali_utilization_platform_realize(util_data); 46#endif 47 48 if (MALI_TRUE == need_add_timer) { 49 mali_control_timer_add(mali_control_timeout); 50 } 51 } 52 } 53} 54 55/* Init a timer (for now it is used for GPU utilization and dvfs) */ 56_mali_osk_errcode_t mali_control_timer_init(void) 57{ 58 _mali_osk_device_data data; 59 60 if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) { 61 /* Use device specific settings (if defined) */ 62 if (0 != data.control_interval) { 63 mali_control_timeout = data.control_interval; 64 MALI_DEBUG_PRINT(2, ("Mali GPU Timer: %u\n", mali_control_timeout)); 65 } 66 } 67 68 mali_control_timer = _mali_osk_timer_init(); 69 if (NULL == mali_control_timer) { 70 return _MALI_OSK_ERR_FAULT; 71 } 72 _mali_osk_timer_setcallback(mali_control_timer, mali_control_timer_callback, NULL); 73 74 return _MALI_OSK_ERR_OK; 75} 76 77void mali_control_timer_term(void) 78{ 79 if (NULL != mali_control_timer) { 80 _mali_osk_timer_del(mali_control_timer); 81 timer_running = MALI_FALSE; 82 _mali_osk_timer_term(mali_control_timer); 83 mali_control_timer = NULL; 84 } 85} 86 87mali_bool mali_control_timer_resume(u64 time_now) 88{ 89 mali_utilization_data_assert_locked(); 90 91 if (timer_running != MALI_TRUE) { 92 timer_running = MALI_TRUE; 93 94 period_start_time = time_now; 95 96 mali_utilization_reset(); 97 98 return MALI_TRUE; 99 } 100 101 return MALI_FALSE; 102} 103 104void mali_control_timer_pause(void) 105{ 106 mali_utilization_data_assert_locked(); 107 if (timer_running == MALI_TRUE) { 108 timer_running = MALI_FALSE; 109 } 110} 111 112void mali_control_timer_suspend(mali_bool suspend) 113{ 114 mali_utilization_data_lock(); 115 116 if (timer_running == MALI_TRUE) { 117 timer_running = MALI_FALSE; 118 119 mali_utilization_data_unlock(); 120 121 if (suspend == MALI_TRUE) { 122 _mali_osk_timer_del(mali_control_timer); 123 mali_utilization_reset(); 124 } 125 } else { 126 mali_utilization_data_unlock(); 127 } 128} 129