ARM: Tegra: Floor the calculated CPU leakage current
Diwakar Tundlam [Wed, 6 Mar 2013 21:08:08 +0000 (13:08 -0800)]
Also handle leakage calculation failure as an error in EDP-init

Bug 1251570

Change-Id: Ia5f0495f3019c54d1c56701f289618b82a100e05
Reviewed-on: http://git-master/r/239861
(cherry picked from commit 5ed581841d235cb2d0154002f457da668012d32e)
Signed-off-by: Diwakar Tundlam <dtundlam@nvidia.com>
Reviewed-on: http://git-master/r/253748

arch/arm/mach-tegra/edp.c

index 6964acb..f2cd9bd 100644 (file)
@@ -94,8 +94,8 @@ static inline s64 edp_pow(s64 val, int pwr)
 /*
  * Find the maximum frequency that results in dynamic and leakage current that
  * is less than the regulator current limit.
- * temp_C - always valid
- * power_mW - valid or -1 (infinite)
+ * temp_C - valid or -EINVAL
+ * power_mW - valid or -1 (infinite) or -EINVAL
  */
 static unsigned int edp_calculate_maxf(
                                struct tegra_edp_cpu_leakage_params *params,
@@ -154,17 +154,10 @@ static unsigned int edp_calculate_maxf(
                        }
                }
 
-               /* if specified, set floor for leakage current */
-               if (params->leakage_min && leakage_mA <= params->leakage_min)
+               /* set floor for leakage current */
+               if (leakage_mA <= params->leakage_min)
                        leakage_mA = params->leakage_min;
 
-               /* leakage cannot be negative => leakage model has error */
-               if (leakage_mA <= 0) {
-                       pr_err("VDD_CPU EDP failed: IDDQ too high (%d mA)\n",
-                              iddq_mA);
-                       return -EINVAL;
-               }
-
                leakage_mA *= params->leakage_consts_n[n_cores_idx];
 
                /* leakage_const_n was scaled */
@@ -187,7 +180,7 @@ static unsigned int edp_calculate_maxf(
                        return freq_KHz;
                }
        }
-       return 0;
+       return -EINVAL;
 }
 
 static int edp_relate_freq_voltage(struct clk *clk_cpu_g,
@@ -353,6 +346,8 @@ static int init_cpu_edp_limits_calculated(void)
                                                   -1,
                                                   iddq_mA,
                                                   n_cores_idx);
+                       if (limit == -EINVAL)
+                               return -EINVAL;
                        /* apply safety cap if it is specified */
                        if (n_cores_idx < 4) {
                                cap = params->safety_cap[n_cores_idx];
@@ -372,6 +367,8 @@ static int init_cpu_edp_limits_calculated(void)
                                                   power_cap_levels[pwr_idx],
                                                   iddq_mA,
                                                   n_cores_idx);
+                       if (limit == -EINVAL)
+                               return -EINVAL;
                        power_edp_calc_limits[pwr_idx].
                                freq_limits[n_cores_idx] = limit;
                }
@@ -408,9 +405,19 @@ static int init_cpu_edp_limits_calculated(void)
 
 void tegra_recalculate_cpu_edp_limits(void)
 {
-       if (tegra_chip_id == TEGRA_CHIPID_TEGRA11 ||
-           tegra_chip_id == TEGRA_CHIPID_TEGRA14)
-               init_cpu_edp_limits_calculated();
+       if (tegra_chip_id != TEGRA_CHIPID_TEGRA11 &&
+           tegra_chip_id != TEGRA_CHIPID_TEGRA14)
+               return;
+
+       if (init_cpu_edp_limits_calculated() == 0)
+               return;
+
+       /* Revert to default EDP table on error */
+       edp_limits = edp_default_limits;
+       edp_limits_size = ARRAY_SIZE(edp_default_limits);
+
+       power_edp_limits = power_edp_default_limits;
+       power_edp_limits_size = ARRAY_SIZE(power_edp_default_limits);
 }
 
 /*