ARM: tegra13: dvfs: Add CPU SiMon offsets
Alex Frid [Tue, 17 Jun 2014 23:44:08 +0000 (16:44 -0700)]
Added CPU Vmin -20mV offset for high SiMon grade on Tegra13 platforms.
Since no SiMon grading is available this offset is not actually applied.

Bug 1511506

Change-Id: Ia7fa83db6a6ee003c0e1211c8a7fb9ac89630487
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/424907
Reviewed-by: Sai Gurrappadi <sgurrappadi@nvidia.com>
Tested-by: Sai Gurrappadi <sgurrappadi@nvidia.com>
Reviewed-by: Thomas Cherry <tcherry@nvidia.com>

arch/arm/mach-tegra/tegra13_dvfs.c

index 2e61549..c54ed4c 100644 (file)
@@ -32,6 +32,7 @@
 #include "tegra_cl_dvfs.h"
 #include "tegra_core_sysfs_limits.h"
 #include "pm.h"
+#include "tegra_simon.h"
 
 static bool tegra_dvfs_cpu_disabled;
 static bool tegra_dvfs_core_disabled;
@@ -42,6 +43,8 @@ static bool tegra_dvfs_gpu_disabled;
 
 #define VDD_SAFE_STEP                  100
 
+static int cpu_vmin_offsets[] = { 0, -20, };
+
 static int vdd_core_vmin_trips_table[MAX_THERMAL_LIMITS] = { 20, };
 static int vdd_core_therm_floors_table[MAX_THERMAL_LIMITS] = { 950, };
 
@@ -81,7 +84,8 @@ static struct dvfs_rail tegra13_dvfs_rail_vdd_cpu = {
        .reg_id = "vdd_cpu",
        .version = "p4v12",
        .max_millivolts = 1300,
-       .min_millivolts = 700,
+       .min_millivolts = 680,
+       .simon_domain = TEGRA_SIMON_DOMAIN_CPU,
        .step = VDD_SAFE_STEP,
        .jmp_to_zero = true,
        .vmin_cdev = &cpu_vmin_cdev,
@@ -229,7 +233,7 @@ static struct cpu_cvb_dvfs cpu_cvb_dvfs_table[] = {
                        .tune1          = 0x00000099,
                        .droop_rate_min = 1000000,
                        .tune_high_min_millivolts = 900,
-                       .min_millivolts = 700,
+                       .min_millivolts = 680,
                        .tune_high_margin_mv = 30,
                },
                .max_mv = 1260,
@@ -800,14 +804,15 @@ static int __init set_cpu_dvfs_data(unsigned long max_freq,
        unsigned long fmin_use_dfll = 0;
        struct cvb_dvfs_table *table = NULL;
        int speedo = tegra_cpu_speedo_value();
-       struct rail_alignment *align = &tegra13_dvfs_rail_vdd_cpu.alignment;
+       struct dvfs_rail *rail = &tegra13_dvfs_rail_vdd_cpu;
+       struct rail_alignment *align = &rail->alignment;
 
        set_cpu_dfll_tuning_data(d, speedo);
 
        min_dfll_mv = d->dfll_tune_data.min_millivolts;
        min_dfll_mv =  round_voltage(min_dfll_mv, align, true);
        d->max_mv = round_voltage(d->max_mv, align, false);
-       BUG_ON(min_dfll_mv < tegra13_dvfs_rail_vdd_cpu.min_millivolts);
+       BUG_ON(min_dfll_mv < rail->min_millivolts);
 
        /*
         * Use CVB table to fill in CPU dvfs frequencies and voltages. Each
@@ -901,9 +906,28 @@ static int __init set_cpu_dvfs_data(unsigned long max_freq,
 #ifndef CONFIG_TEGRA_CPU_VOLT_CAP
        tegra_dvfs_rail_init_vmax_thermal_profile(
                vdd_cpu_vmax_trips_table, vdd_cpu_therm_caps_table,
-               &tegra13_dvfs_rail_vdd_cpu, &cpu_dvfs->dfll_data);
+               rail, &cpu_dvfs->dfll_data);
 
 #endif
+       if (cpu_dvfs->speedo_id == 0)
+               return 0;
+
+       /* Init cpu Vmin SiMon offsets */
+       tegra_dvfs_rail_init_simon_vmin_offsets(cpu_vmin_offsets,
+               ARRAY_SIZE(cpu_vmin_offsets), rail);
+
+       /* check Vmin SiMon offset: ignore SiMon if it pushes too low */
+       if (rail->therm_mv_floors && rail->simon_vmin_offsets) {
+               mv = rail->therm_mv_floors[rail->therm_mv_floors_num - 1];
+               mv += rail->simon_vmin_offsets[rail->simon_vmin_offs_num - 1];
+               mv = round_voltage(mv, align, true);
+               if (mv < min_dfll_mv) {
+                       WARN(1, "tegra13_dvfs: cpu simon min %dmV below dfll min %dmV\n",
+                            mv, min_dfll_mv);
+                       rail->simon_vmin_offsets = NULL;
+                       rail->simon_vmin_offs_num = 0;
+               }
+       }
 
        return 0;
 }