diff options
author | Ilan Aelion <iaelion@nvidia.com> | 2013-03-25 18:31:16 -0600 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 13:12:30 -0700 |
commit | bf59a4844194c33d66f9e3eee1ff6dbf84e7e828 (patch) | |
tree | 8401d51092a2d9deb6add266aa0addde488a9bc3 /drivers/misc/tegra-throughput.c | |
parent | 52448a4fd727af1363f6c4a8e89228056bdfbbd7 (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.c | 58 |
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; } |