summaryrefslogtreecommitdiff
path: root/drivers/misc/tegra-throughput.c
diff options
context:
space:
mode:
authorIlan Aelion <iaelion@nvidia.com>2013-03-25 18:31:16 -0600
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:12:30 -0700
commitbf59a4844194c33d66f9e3eee1ff6dbf84e7e828 (patch)
tree8401d51092a2d9deb6add266aa0addde488a9bc3 /drivers/misc/tegra-throughput.c
parent52448a4fd727af1363f6c4a8e89228056bdfbbd7 (diff)
misc: tegra-throughput: fix fps reading
fixed a bug in values written to /d/fps Bug 1171636 Change-Id: Idb6036c5658c1a5c8df79a4bda982655a63ad053 Signed-off-by: Ilan Aelion <iaelion@nvidia.com> Reviewed-on: http://git-master/r/212823 (cherry picked from commit eb1a6c5089acadb5d2d16b3fd934419aee94649c) Reviewed-on: http://git-master/r/218587 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Diffstat (limited to 'drivers/misc/tegra-throughput.c')
-rw-r--r--drivers/misc/tegra-throughput.c58
1 files changed, 30 insertions, 28 deletions
diff --git a/drivers/misc/tegra-throughput.c b/drivers/misc/tegra-throughput.c
index eb9473503d1d..2b5cf1447027 100644
--- a/drivers/misc/tegra-throughput.c
+++ b/drivers/misc/tegra-throughput.c
@@ -1,7 +1,7 @@
/*
* drivers/misc/throughput.c
*
- * Copyright (C) 2012-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,13 +31,11 @@
#define DEFAULT_SYNC_RATE 60000 /* 60 Hz */
-static unsigned short target_frame_time;
-static unsigned short last_frame_time;
+static unsigned int target_frame_time;
static ktime_t last_flip;
static spinlock_t lock;
-#define EMA_PERIOD 16
-#define EMA_SHIFT 4
+#define EMA_PERIOD 8
static int frame_time_sum_init = 1;
static long frame_time_sum; /* used for fps EMA */
@@ -64,30 +62,26 @@ static void throughput_flip_callback(void)
if (last_flip.tv64 != 0) {
timediff = (long) ktime_us_delta(now, last_flip);
- if (timediff > (long) USHRT_MAX)
- last_frame_time = USHRT_MAX;
- else
- last_frame_time = (unsigned short) timediff;
-
- if (last_frame_time == 0) {
+ if (timediff <= 0) {
pr_warn("%s: flips %lld nsec apart\n",
__func__, now.tv64 - last_flip.tv64);
return;
}
throughput_hint =
- ((int) target_frame_time * 1000) / last_frame_time;
+ ((int) target_frame_time * 1000) / timediff;
/* only deliver throughput hints when a single app is active */
if (throughput_active_app_count == 1 && !work_pending(&work))
schedule_work(&work);
if (frame_time_sum_init) {
- frame_time_sum = last_frame_time * EMA_PERIOD;
+ frame_time_sum = timediff * EMA_PERIOD;
frame_time_sum_init = 0;
} else {
- int t = frame_time_sum * (EMA_PERIOD - 1);
- frame_time_sum = (t >> EMA_SHIFT) + last_frame_time;
+ int t = (frame_time_sum / EMA_PERIOD) *
+ (EMA_PERIOD - 1);
+ frame_time_sum = t + timediff;
}
}
@@ -103,7 +97,7 @@ static void reset_target_frame_time(void)
sync_rate = DEFAULT_SYNC_RATE;
}
- target_frame_time = (unsigned short) (1000000000 / sync_rate);
+ target_frame_time = (unsigned int) (1000000000 / sync_rate);
pr_debug("%s: panel sync rate %d, target frame time %u\n",
__func__, sync_rate, target_frame_time);
@@ -115,7 +109,6 @@ static int throughput_open(struct inode *inode, struct file *file)
throughput_active_app_count++;
frame_time_sum_init = 1;
- frame_time_sum = 0;
spin_unlock(&lock);
@@ -131,7 +124,6 @@ static int throughput_release(struct inode *inode, struct file *file)
throughput_active_app_count--;
frame_time_sum_init = 1;
- frame_time_sum = 0;
if (throughput_active_app_count == 1)
reset_target_frame_time();
@@ -155,14 +147,8 @@ static int throughput_set_target_fps(unsigned long arg)
if (arg == 0)
reset_target_frame_time();
- else {
- unsigned long frame_time = (1000000 / arg);
-
- if (frame_time > USHRT_MAX)
- frame_time = USHRT_MAX;
-
- target_frame_time = (unsigned short) frame_time;
- }
+ else
+ target_frame_time = (unsigned int) (1000000 / arg);
return 0;
}
@@ -209,8 +195,24 @@ static struct miscdevice throughput_miscdev = {
static int fps_show(struct seq_file *s, void *unused)
{
- int frame_time_avg = frame_time_sum >> EMA_SHIFT;
- int fps = frame_time_avg > 0 ? 1000000 / frame_time_avg : 0;
+ int frame_time_avg;
+ int fps;
+ ktime_t now;
+ long timediff;
+
+ fps = 0;
+ if (frame_time_sum_init)
+ goto DONE;
+
+ now = ktime_get();
+ timediff = (long) ktime_us_delta(now, last_flip);
+ if (timediff > 1000000)
+ goto DONE;
+
+ frame_time_avg = frame_time_sum / EMA_PERIOD;
+ fps = frame_time_avg > 0 ? 1000000 / frame_time_avg : 0;
+
+DONE:
seq_printf(s, "%d\n", fps);
return 0;
}