diff options
Diffstat (limited to 'pvr-source/services4/system/omap4/sgxfreq_on3demand.c')
-rwxr-xr-x | pvr-source/services4/system/omap4/sgxfreq_on3demand.c | 324 |
1 files changed, 0 insertions, 324 deletions
diff --git a/pvr-source/services4/system/omap4/sgxfreq_on3demand.c b/pvr-source/services4/system/omap4/sgxfreq_on3demand.c deleted file mode 100755 index c4e4bd9..0000000 --- a/pvr-source/services4/system/omap4/sgxfreq_on3demand.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2012 Texas Instruments, Inc - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/sysfs.h> -#include <linux/vmalloc.h> -#include <asm/io.h> -#include "sgxfreq.h" - -static int on3demand_start(struct sgxfreq_sgx_data *data); -static void on3demand_stop(void); -static void on3demand_predict(void); -static void on3demand_frame_done(void); -static void on3demand_active(void); -static void on3demand_timeout(struct work_struct *work); - - -static struct sgxfreq_governor on3demand_gov = { - .name = "on3demand", - .gov_start = on3demand_start, - .gov_stop = on3demand_stop, - .sgx_frame_done = on3demand_frame_done, - .sgx_active = on3demand_active, -}; - -static struct on3demand_data { - unsigned int load; - unsigned int up_threshold; - unsigned int down_threshold; - unsigned int history_size; - unsigned long prev_total_idle; - unsigned long prev_total_active; - unsigned int low_load_cnt; - unsigned int poll_interval; - unsigned long delta_active; - unsigned long delta_idle; - bool polling_enabled; - struct delayed_work work; - struct mutex mutex; -} odd; - -#define ON3DEMAND_DEFAULT_UP_THRESHOLD 80 -#define ON3DEMAND_DEFAULT_DOWN_THRESHOLD 30 -#define ON3DEMAND_DEFAULT_HISTORY_SIZE_THRESHOLD 5 -/* For Live wallpaper frame done at interval of ~64ms */ -#define ON3DEMAND_DEFAULT_POLL_INTERVAL 75 - -/*FIXME: This should be dynamic and queried from platform */ -#define ON3DEMAND_FRAME_DONE_DEADLINE_MS 16 - - -/*********************** begin sysfs interface ***********************/ - -extern struct kobject *sgxfreq_kobj; - -static ssize_t show_down_threshold(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", odd.down_threshold); -} - -static ssize_t store_down_threshold(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int ret; - unsigned int thres; - - ret = sscanf(buf, "%u", &thres); - if (ret != 1) - return -EINVAL; - - mutex_lock(&odd.mutex); - - if (thres <= 100) { - odd.down_threshold = thres; - odd.low_load_cnt = 0; - } else { - return -EINVAL; - } - - mutex_unlock(&odd.mutex); - - return count; -} - -static ssize_t show_up_threshold(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", odd.up_threshold); -} - -static ssize_t store_up_threshold(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int ret; - unsigned int thres; - - ret = sscanf(buf, "%u", &thres); - if (ret != 1) - return -EINVAL; - - mutex_lock(&odd.mutex); - - if (thres <= 100) { - odd.up_threshold = thres; - odd.low_load_cnt = 0; - } else { - return -EINVAL; - } - - mutex_unlock(&odd.mutex); - - return count; -} - -static ssize_t show_history_size(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", odd.history_size); -} - -static ssize_t store_history_size(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int ret; - unsigned int size; - - ret = sscanf(buf, "%u", &size); - if (ret != 1) - return -EINVAL; - - mutex_lock(&odd.mutex); - - if (size >= 1) { - odd.history_size = size; - odd.low_load_cnt = 0; - } else { - return -EINVAL; - } - - mutex_unlock(&odd.mutex); - - return count; -} - -static ssize_t show_load(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", odd.load); -} - -static DEVICE_ATTR(down_threshold, 0644, - show_down_threshold, store_down_threshold); -static DEVICE_ATTR(up_threshold, 0644, - show_up_threshold, store_up_threshold); -static DEVICE_ATTR(history_size, 0644, - show_history_size, store_history_size); -static DEVICE_ATTR(load, 0444, - show_load, NULL); - -static struct attribute *on3demand_attributes[] = { - &dev_attr_down_threshold.attr, - &dev_attr_up_threshold.attr, - &dev_attr_history_size.attr, - &dev_attr_load.attr, - NULL -}; - -static struct attribute_group on3demand_attr_group = { - .attrs = on3demand_attributes, - .name = "on3demand", -}; -/************************ end sysfs interface ************************/ - -int on3demand_init(void) -{ - int ret; - - mutex_init(&odd.mutex); - - ret = sgxfreq_register_governor(&on3demand_gov); - if (ret) - return ret; - - return 0; -} - -int on3demand_deinit(void) -{ - return 0; -} - -static int on3demand_start(struct sgxfreq_sgx_data *data) -{ - int ret; - - odd.load = 0; - odd.up_threshold = ON3DEMAND_DEFAULT_UP_THRESHOLD; - odd.down_threshold = ON3DEMAND_DEFAULT_DOWN_THRESHOLD; - odd.history_size = ON3DEMAND_DEFAULT_HISTORY_SIZE_THRESHOLD; - odd.prev_total_active = 0; - odd.prev_total_idle = 0; - odd.low_load_cnt = 0; - odd.poll_interval = ON3DEMAND_DEFAULT_POLL_INTERVAL; - odd.polling_enabled = false; - - INIT_DELAYED_WORK(&odd.work, on3demand_timeout); - - ret = sysfs_create_group(sgxfreq_kobj, &on3demand_attr_group); - if (ret) - return ret; - - return 0; -} - -static void on3demand_stop(void) -{ - cancel_delayed_work_sync(&odd.work); - sysfs_remove_group(sgxfreq_kobj, &on3demand_attr_group); -} - -static void on3demand_predict(void) -{ - static unsigned short first_sample = 1; - unsigned long total_active, total_idle; - unsigned long freq; - - if (first_sample == 1) { - first_sample = 0; - odd.prev_total_active = sgxfreq_get_total_active_time(); - odd.prev_total_idle = sgxfreq_get_total_idle_time(); - return; - } - - /* Sample new active and idle times */ - total_active = sgxfreq_get_total_active_time(); - total_idle = sgxfreq_get_total_idle_time(); - - /* Compute load */ - odd.delta_active = __delta32(total_active, odd.prev_total_active); - odd.delta_idle = __delta32(total_idle, odd.prev_total_idle); - - /* - * If SGX was active for longer than frame display time (1/fps), - * scale to highest possible frequency. - */ - if (odd.delta_active > ON3DEMAND_FRAME_DONE_DEADLINE_MS) { - odd.low_load_cnt = 0; - sgxfreq_set_freq_request(sgxfreq_get_freq_max()); - } - - if ((odd.delta_active + odd.delta_idle)) - odd.load = (100 * odd.delta_active / (odd.delta_active + odd.delta_idle)); - - odd.prev_total_active = total_active; - odd.prev_total_idle = total_idle; - - /* Scale GPU frequency on purpose */ - if (odd.load >= odd.up_threshold) { - odd.low_load_cnt = 0; - sgxfreq_set_freq_request(sgxfreq_get_freq_max()); - } else if (odd.load <= odd.down_threshold) { - if (odd.low_load_cnt == odd.history_size) { - /* Convert load to frequency */ - freq = (sgxfreq_get_freq() * odd.load) / 100; - sgxfreq_set_freq_request(freq); - odd.low_load_cnt = 0; - } else { - odd.low_load_cnt++; - } - } else { - odd.low_load_cnt = 0; - } -} - - -static void on3demand_active(void) -{ - if (!odd.polling_enabled) { - sgxfreq_set_freq_request(sgxfreq_get_freq_max()); - odd.low_load_cnt = 0; - odd.polling_enabled = true; - schedule_delayed_work(&odd.work, odd.poll_interval * HZ/1000); - } - -} - -static void on3demand_frame_done(void) -{ - if (odd.polling_enabled) { - cancel_delayed_work_sync(&odd.work); - schedule_delayed_work(&odd.work, odd.poll_interval * HZ/1000); - } - on3demand_predict(); -} - -static void on3demand_timeout(struct work_struct *work) -{ - /* - * If sgx was idle all throughout timer disable polling and - * enable it on next sgx active event - */ - if (!odd.delta_active) { - sgxfreq_set_freq_request(sgxfreq_get_freq_min()); - odd.low_load_cnt = 0; - odd.polling_enabled = false; - } else { - on3demand_predict(); - odd.polling_enabled = true; - schedule_delayed_work(&odd.work, odd.poll_interval * HZ/1000); - } -} |