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;
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
}
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
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;
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:
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);
soc_speedo_id = 0;
gpu_speedo_id = 0;
threshold_index = 0;
+ core_min_mv = 950;
break;
}
}
{
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)
{
}
}
+int tegra_core_speedo_min_mv(void)
+{
+ return core_min_mv;
+}
+
int tegra_get_cpu_iddq_value(void)
{
return cpu_iddq_value;
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);