]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
dvfs: tegra21: Make core Vmin chip dependent
authorAlex Frid <afrid@nvidia.com>
Wed, 1 Apr 2015 02:42:46 +0000 (19:42 -0700)
committerAleksandr Frid <afrid@nvidia.com>
Thu, 2 Apr 2015 01:52:39 +0000 (18:52 -0700)
Added get minimum core voltage interface to specify different levels
depending on chip SKU and revision.

Bug 1558421

Change-Id: If5edbae9b3953a4e9f2ae0d6bc747c64ddcd684a
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/726018
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
drivers/platform/tegra/tegra21_dvfs.c
drivers/platform/tegra/tegra21_speedo.c
include/linux/tegra-fuse.h

index c0030c5df010434d4f5fd0ea4218da47202418b3..a19adf021c8479f5e7d69192039479fa270bd723 100644 (file)
@@ -1609,6 +1609,26 @@ static int __init get_core_nominal_mv_index(int speedo_id)
        return i - 1;
 }
 
+/*
+ * Clip sku-based core minimum voltage to core DVFS voltage ladder
+ */
+static int __init get_core_minimum_mv_index(void)
+{
+       int i;
+       int mv = tegra_core_speedo_min_mv();
+
+       /*
+        * Start with minimum level for the chip sku/speedo. Then, make sure it
+        * is above initial rail minimum, and finally round up to DVFS voltages.
+        */
+       mv = max(mv, tegra21_dvfs_rail_vdd_core.min_millivolts);
+       for (i = 0; i < MAX_DVFS_FREQS - 1; i++) {
+               if ((core_millivolts[i+1] == 0) || (mv <= core_millivolts[i]))
+                       break;
+       }
+       return i;
+}
+
 static int __init init_core_rail_thermal_profile(void)
 {
        struct dvfs_rail *rail = &tegra21_dvfs_rail_vdd_core;
@@ -1681,7 +1701,7 @@ void __init tegra21x_init_dvfs(void)
        of_tegra_dvfs_init(tegra21_dvfs_rail_of_match);
 
        /*
-        * Find nominal voltages for core (1st) and cpu rails before rail
+        * Find nominal and minimum voltages for core rail before rail
         * init. Nominal voltage index in core scaling ladder can also be
         * used to determine max dvfs frequencies for all core clocks. In
         * case of error disable core scaling and set index to 0, so that
@@ -1695,9 +1715,10 @@ void __init tegra21x_init_dvfs(void)
        }
        tegra21_dvfs_rail_vdd_core.nominal_millivolts =
                core_millivolts[core_nominal_mv_index];
-       tegra21_dvfs_rail_vdd_core.min_millivolts =
-               max(tegra21_dvfs_rail_vdd_core.min_millivolts,
-               core_millivolts[0]);
+
+       i = get_core_minimum_mv_index();
+       BUG_ON(i > core_nominal_mv_index);
+       tegra21_dvfs_rail_vdd_core.min_millivolts = core_millivolts[i];
 
        /*
         * Construct fast and slow CPU DVFS tables from CVB data; find maximum
index ee76d0ed0408a8b5b59a9c7eb20ea8208f2f63d5..409ca6cdae664980aeef36501267a8bc29377bfa 100644 (file)
@@ -61,6 +61,8 @@ static int soc_speedo_id;
 static int gpu_speedo_id;
 static int package_id;
 
+static int core_min_mv;
+
 static int cpu_iddq_value;
 static int gpu_iddq_value;
 static int soc_iddq_value;
@@ -116,12 +118,14 @@ static void rev_sku_to_speedo_ids(int rev, int sku, int speedo_rev)
                soc_speedo_id = 0;
                gpu_speedo_id = speedo_rev >= 2 ? 1 : 0;
                threshold_index = 0;
+               core_min_mv = 825;
                break;
        case 0x13:
                cpu_speedo_id = shield_sku ? 2 : 1;
                soc_speedo_id = 0;
                gpu_speedo_id = speedo_rev >= 2 ? 1 : 0;
                threshold_index = 0;
+               core_min_mv = 825;
                break;
        case 0x83:
        case 0x87:
@@ -129,6 +133,7 @@ static void rev_sku_to_speedo_ids(int rev, int sku, int speedo_rev)
                soc_speedo_id = 0;
                gpu_speedo_id = speedo_rev >= 2 ? 2 : 0;
                threshold_index = 0;
+               core_min_mv = 800;
                break;
        default:
                pr_warn("Tegra21: Unknown SKU %d\n", sku);
@@ -136,6 +141,7 @@ static void rev_sku_to_speedo_ids(int rev, int sku, int speedo_rev)
                soc_speedo_id = 0;
                gpu_speedo_id = 0;
                threshold_index = 0;
+               core_min_mv = 950;
                break;
        }
 }
@@ -339,10 +345,10 @@ int tegra_soc_speedo_2_value(void)
 {
        return soc_speedo_2_value;
 }
+
 /*
- * CPU and core nominal voltage levels as determined by chip SKU and speedo
- * (not final - can be lowered by dvfs tables and rail dependencies; the
- * latter is resolved by the dvfs code)
+ * Core nominal and minimum voltage levels as determined by chip SKU and speedo
+ * (not final - will be clipped to dvfs tables).
  */
 int tegra_cpu_speedo_mv(void)
 {
@@ -366,6 +372,11 @@ int tegra_core_speedo_mv(void)
        }
 }
 
+int tegra_core_speedo_min_mv(void)
+{
+       return core_min_mv;
+}
+
 int tegra_get_cpu_iddq_value(void)
 {
        return cpu_iddq_value;
index a65ffcbd02f18f2e9c6cc01240cb48ae6cd374e3..1fc226be766e133b5d157bc77fe9ae9ee20a4555 100644 (file)
@@ -60,6 +60,7 @@ int tegra_cpu_speedo_id(void);
 int tegra_cpu_speedo_mv(void);
 int tegra_cpu_speedo_value(void);
 int tegra_core_speedo_mv(void);
+int tegra_core_speedo_min_mv(void);
 int tegra_gpu_speedo_id(void);
 int tegra_get_sku_override(void);
 int tegra_get_cpu_iddq_value(void);