ARM: tegra: dvfs: Update rail statistic
Alex Frid [Sat, 20 Oct 2012 06:04:29 +0000 (23:04 -0700)]
- Replaced fixed rail bins with per-rail-per-platform bins (by
default use backward compatible 12.5mV bin)
- On Tegra11 set bins for all rails on cvb alignment boundary (10mV)
- Increased maximum number of bins to 50
- Fixed rail voltage report in dfll mode: compensate 1mV adjustment
used in this mode to force voltage update

Change-Id: I0b7fb49900656de33bc77bb8267dbde713a2441f
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/146113
Reviewed-on: http://git-master/r/159642
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bo Yan <byan@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>

Rebase-Id: Ra61edc2a0fec90c4018e7dba6b2c74b32a7e66af

arch/arm/mach-tegra/dvfs.c
arch/arm/mach-tegra/dvfs.h
arch/arm/mach-tegra/tegra11_dvfs.c

index 3f335ee..92f923f 100644 (file)
 #include "clock.h"
 #include "dvfs.h"
 
-#define DVFS_RAIL_STATS_BIN    25
-#define DVFS_RAIL_STATS_SCALE  2
-#define DVFS_RAIL_STATS_RANGE   ((DVFS_RAIL_STATS_TOP_BIN - 1) * \
-                                DVFS_RAIL_STATS_BIN / DVFS_RAIL_STATS_SCALE)
+#define DVFS_RAIL_STATS_BIN    12500
 
 struct dvfs_rail *tegra_cpu_rail;
 struct dvfs_rail *tegra_core_rail;
@@ -105,19 +102,26 @@ static int dvfs_solve_relationship(struct dvfs_relationship *rel)
    CPU0 only on-line, and interrupts disabled */
 static void dvfs_rail_stats_init(struct dvfs_rail *rail, int millivolts)
 {
+       int dvfs_rail_stats_range;
+
+       if (!rail->stats.bin_uV)
+               rail->stats.bin_uV = DVFS_RAIL_STATS_BIN;
+
+       dvfs_rail_stats_range =
+               (DVFS_RAIL_STATS_TOP_BIN - 1) * rail->stats.bin_uV / 1000;
+
        rail->stats.last_update = ktime_get();
        if (millivolts >= rail->min_millivolts) {
-               int i = 1 + (2 * (millivolts - rail->min_millivolts) *
-                       DVFS_RAIL_STATS_SCALE + DVFS_RAIL_STATS_BIN) /
-                       (2 * DVFS_RAIL_STATS_BIN);
+               int i = 1 + (2 * (millivolts - rail->min_millivolts) * 1000 +
+                            rail->stats.bin_uV) / (2 * rail->stats.bin_uV);
                rail->stats.last_index = min(i, DVFS_RAIL_STATS_TOP_BIN);
        }
 
        if (rail->max_millivolts >
-           rail->min_millivolts + DVFS_RAIL_STATS_RANGE)
+           rail->min_millivolts + dvfs_rail_stats_range)
                pr_warn("tegra_dvfs: %s: stats above %d mV will be squashed\n",
                        rail->reg_id,
-                       rail->min_millivolts + DVFS_RAIL_STATS_RANGE);
+                       rail->min_millivolts + dvfs_rail_stats_range);
 }
 
 static void dvfs_rail_stats_update(
@@ -132,9 +136,8 @@ static void dvfs_rail_stats_update(
                return;
 
        if (millivolts >= rail->min_millivolts) {
-               int i = 1 + (2 * (millivolts - rail->min_millivolts) *
-                       DVFS_RAIL_STATS_SCALE + DVFS_RAIL_STATS_BIN) /
-                       (2 * DVFS_RAIL_STATS_BIN);
+               int i = 1 + (2 * (millivolts - rail->min_millivolts) * 1000 +
+                            rail->stats.bin_uV) / (2 * rail->stats.bin_uV);
                rail->stats.last_index = min(i, DVFS_RAIL_STATS_TOP_BIN);
        } else if (millivolts == 0)
                        rail->stats.last_index = 0;
@@ -841,13 +844,15 @@ static int dvfs_tree_show(struct seq_file *s, void *data)
        mutex_lock(&dvfs_lock);
 
        list_for_each_entry(rail, &dvfs_rail_list, node) {
-               seq_printf(s, "%s %d mV%s:\n", rail->reg_id, rail->millivolts,
+               seq_printf(s, "%s %d mV%s:\n", rail->reg_id,
+                          rail->millivolts + (rail->dfll_mode ? 1 : 0),
                           rail->dfll_mode ? " dfll mode" :
                                rail->disabled ? " disabled" : "");
                list_for_each_entry(rel, &rail->relationships_from, from_node) {
                        seq_printf(s, "   %-10s %-7d mV %-4d mV\n",
                                rel->from->reg_id,
-                               rel->from->millivolts,
+                               rel->from->millivolts +
+                                  (rel->from->dfll_mode ? 1 : 0),
                                dvfs_solve_relationship(rel));
                }
                seq_printf(s, "   offset     %-7d mV\n", rail->offs_millivolts);
@@ -882,14 +887,15 @@ static int rail_stats_show(struct seq_file *s, void *data)
        int i;
        struct dvfs_rail *rail;
 
-       seq_printf(s, "%-12s %-10s (bin: %d.%dmV)\n", "millivolts", "time",
-                  DVFS_RAIL_STATS_BIN / DVFS_RAIL_STATS_SCALE,
-                  ((DVFS_RAIL_STATS_BIN * 100) / DVFS_RAIL_STATS_SCALE) % 100);
+       seq_printf(s, "%-12s %-10s\n", "millivolts", "time");
 
        mutex_lock(&dvfs_lock);
 
        list_for_each_entry(rail, &dvfs_rail_list, node) {
-               seq_printf(s, "%s\n", rail->reg_id);
+               seq_printf(s, "%s (bin: %d.%dmV)\n", rail->reg_id,
+                          rail->stats.bin_uV / 1000,
+                          (rail->stats.bin_uV / 10) % 100);
+
                dvfs_rail_stats_update(rail, -1, ktime_get());
 
                seq_printf(s, "%-12d %-10llu\n", 0,
@@ -900,9 +906,8 @@ static int rail_stats_show(struct seq_file *s, void *data)
                        ktime_t ktime_zero = ktime_set(0, 0);
                        if (ktime_equal(rail->stats.time_at_mv[i], ktime_zero))
                                continue;
-                       seq_printf(s, "%-12d %-10llu\n",
-                                  rail->min_millivolts + (i - 1) *
-                                  DVFS_RAIL_STATS_BIN / DVFS_RAIL_STATS_SCALE,
+                       seq_printf(s, "%-12d %-10llu\n", rail->min_millivolts +
+                               (i - 1) * rail->stats.bin_uV / 1000,
                                cputime64_to_clock_t(msecs_to_jiffies(
                                        ktime_to_ms(rail->stats.time_at_mv[i])))
                        );
index 5015ba9..d426295 100644 (file)
@@ -25,7 +25,7 @@
 
 #define MAX_DVFS_FREQS 40
 #define MAX_DVFS_TABLES        80
-#define DVFS_RAIL_STATS_TOP_BIN        42
+#define DVFS_RAIL_STATS_TOP_BIN        50
 
 struct clk;
 struct dvfs_rail;
@@ -52,6 +52,7 @@ struct rail_stats {
        ktime_t last_update;
        int last_index;
        bool off;
+       int bin_uV;
 };
 
 struct dvfs_rail {
index d6e4ee3..2466859 100644 (file)
@@ -540,6 +540,9 @@ void __init tegra11x_init_dvfs(void)
 #ifndef CONFIG_TEGRA_CPU_DVFS
        tegra_dvfs_cpu_disabled = true;
 #endif
+       /* Setup rail bins */
+       tegra11_dvfs_rail_vdd_cpu.stats.bin_uV = tegra_get_cvb_alignment_uV();
+       tegra11_dvfs_rail_vdd_core.stats.bin_uV = tegra_get_cvb_alignment_uV();
 
        /*
         * Find nominal voltages for core (1st) and cpu rails before rail