summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra2_dvfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/tegra2_dvfs.c')
-rw-r--r--arch/arm/mach-tegra/tegra2_dvfs.c155
1 files changed, 106 insertions, 49 deletions
diff --git a/arch/arm/mach-tegra/tegra2_dvfs.c b/arch/arm/mach-tegra/tegra2_dvfs.c
index 9b5397414e03..61218af5b97f 100644
--- a/arch/arm/mach-tegra/tegra2_dvfs.c
+++ b/arch/arm/mach-tegra/tegra2_dvfs.c
@@ -38,33 +38,41 @@ static bool tegra_dvfs_cpu_disabled = true;
#endif
static const int core_millivolts[MAX_DVFS_FREQS] =
- {950, 1000, 1100, 1200, 1275};
+ {950, 1000, 1100, 1200, 1225, 1275, 1300};
static const int cpu_millivolts[MAX_DVFS_FREQS] =
- {750, 775, 800, 825, 875, 900, 925, 975, 1000, 1050, 1100};
+ {750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1100, 1125};
+
+static const int cpu_speedo_nominal_millivolts[] =
+/* spedo_id 0, 1, 2 */
+ { 1100, 1025, 1125 };
+
+static const int core_speedo_nominal_millivolts[] =
+/* spedo_id 0, 1, 2 */
+ { 1225, 1225, 1300 };
#define KHZ 1000
#define MHZ 1000000
static struct dvfs_rail tegra2_dvfs_rail_vdd_cpu = {
.reg_id = "vdd_cpu",
- .max_millivolts = 1100,
+ .max_millivolts = 1125,
.min_millivolts = 750,
- .nominal_millivolts = 1100,
+ .nominal_millivolts = 1125,
};
static struct dvfs_rail tegra2_dvfs_rail_vdd_core = {
.reg_id = "vdd_core",
- .max_millivolts = 1275,
+ .max_millivolts = 1300,
.min_millivolts = 950,
- .nominal_millivolts = 1200,
+ .nominal_millivolts = 1225,
.step = 150, /* step vdd_core by 150 mV to allow vdd_aon to follow */
};
static struct dvfs_rail tegra2_dvfs_rail_vdd_aon = {
.reg_id = "vdd_aon",
- .max_millivolts = 1275,
+ .max_millivolts = 1300,
.min_millivolts = 950,
- .nominal_millivolts = 1200,
+ .nominal_millivolts = 1225,
#ifndef CONFIG_TEGRA_CORE_DVFS
.disabled = true,
#endif
@@ -120,10 +128,11 @@ static struct dvfs_rail *tegra2_dvfs_rails[] = {
&tegra2_dvfs_rail_vdd_aon,
};
-#define CPU_DVFS(_clk_name, _process_id, _mult, _freqs...) \
+#define CPU_DVFS(_clk_name, _speedo_id, _process_id, _mult, _freqs...) \
{ \
.clk_name = _clk_name, \
- .cpu_process_id = _process_id, \
+ .speedo_id = _speedo_id, \
+ .process_id = _process_id, \
.freqs = {_freqs}, \
.freqs_mult = _mult, \
.millivolts = cpu_millivolts, \
@@ -131,10 +140,11 @@ static struct dvfs_rail *tegra2_dvfs_rails[] = {
.dvfs_rail = &tegra2_dvfs_rail_vdd_cpu, \
}
-#define CORE_DVFS(_clk_name, _auto, _mult, _freqs...) \
+#define CORE_DVFS(_clk_name, _process_id, _auto, _mult, _freqs...) \
{ \
.clk_name = _clk_name, \
- .cpu_process_id = -1, \
+ .speedo_id = -1, \
+ .process_id = _process_id, \
.freqs = {_freqs}, \
.freqs_mult = _mult, \
.millivolts = core_millivolts, \
@@ -143,14 +153,24 @@ static struct dvfs_rail *tegra2_dvfs_rails[] = {
}
static struct dvfs dvfs_init[] = {
- /* Cpu voltages (mV): 750, 775, 800, 825, 875, 900, 925, 975, 1000, 1050, 1100 */
- CPU_DVFS("cpu", 0, MHZ, 314, 314, 314, 456, 456, 608, 608, 760, 817, 912, 1000),
- CPU_DVFS("cpu", 1, MHZ, 314, 314, 314, 456, 456, 618, 618, 770, 827, 922, 1000),
- CPU_DVFS("cpu", 2, MHZ, 494, 675, 675, 675, 817, 817, 922, 1000),
- CPU_DVFS("cpu", 3, MHZ, 730, 760, 845, 845, 1000),
+ /* Cpu voltages (mV): 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1100, 1125 */
+ CPU_DVFS("cpu", 0, 0, MHZ, 314, 314, 314, 456, 456, 456, 608, 608, 608, 760, 817, 817, 912, 1000),
+ CPU_DVFS("cpu", 0, 1, MHZ, 314, 314, 314, 456, 456, 456, 618, 618, 618, 770, 827, 827, 922, 1000),
+ CPU_DVFS("cpu", 0, 2, MHZ, 494, 494, 494, 675, 675, 817, 817, 922, 922, 1000),
+ CPU_DVFS("cpu", 0, 3, MHZ, 730, 760, 845, 845, 940, 1000),
+
+ CPU_DVFS("cpu", 1, 0, MHZ, 380, 380, 503, 503, 655, 655, 798, 798, 902, 902, 960, 1000),
+ CPU_DVFS("cpu", 1, 1, MHZ, 389, 389, 503, 503, 655, 760, 798, 798, 950, 950, 1000),
+ CPU_DVFS("cpu", 1, 2, MHZ, 598, 598, 750, 750, 893, 893, 1000),
+ CPU_DVFS("cpu", 1, 3, MHZ, 730, 760, 845, 845, 940, 1000),
- /* Core voltages (mV): 950, 1000, 1100, 1200, 1275 */
- CORE_DVFS("emc", 1, KHZ, 57000, 333000, 333000, 666000, 666000),
+ CPU_DVFS("cpu", 2, 0, MHZ, 0, 0, 0, 0, 655, 655, 798, 798, 902, 902, 960, 1000, 1100, 1100, 1200),
+ CPU_DVFS("cpu", 2, 1, MHZ, 0, 0, 0, 0, 655, 760, 798, 798, 950, 950, 1015, 1015, 1100, 1200),
+ CPU_DVFS("cpu", 2, 2, MHZ, 0, 0, 0, 0, 769, 769, 902, 902, 1026, 1026, 1140, 1140, 1200),
+ CPU_DVFS("cpu", 2, 3, MHZ, 0, 0, 0, 0, 940, 1000, 1000, 1000, 1130, 1130, 1200),
+
+ /* Core voltages (mV): 950, 1000, 1100, 1200, 1225, 1275, 1300 */
+ CORE_DVFS("emc", -1, 1, KHZ, 57000, 333000, 380000, 666000, 666000, 666000, 760000),
#if 0
/*
@@ -159,22 +179,22 @@ static struct dvfs dvfs_init[] = {
* For now, boards must ensure that the core voltage does not drop
* below 1V, or that the sdmmc busses are set to 44 MHz or less.
*/
- CORE_DVFS("sdmmc1", 1, KHZ, 44000, 52000, 52000, 52000, 52000),
- CORE_DVFS("sdmmc2", 1, KHZ, 44000, 52000, 52000, 52000, 52000),
- CORE_DVFS("sdmmc3", 1, KHZ, 44000, 52000, 52000, 52000, 52000),
- CORE_DVFS("sdmmc4", 1, KHZ, 44000, 52000, 52000, 52000, 52000),
+ CORE_DVFS("sdmmc1", -1, 1, KHZ, 44000, 52000, 52000, 52000, 52000, 52000, 52000),
+ CORE_DVFS("sdmmc2", -1, 1, KHZ, 44000, 52000, 52000, 52000, 52000, 52000, 52000),
+ CORE_DVFS("sdmmc3", -1, 1, KHZ, 44000, 52000, 52000, 52000, 52000, 52000, 52000),
+ CORE_DVFS("sdmmc4", -1, 1, KHZ, 44000, 52000, 52000, 52000, 52000, 52000, 52000),
#endif
- CORE_DVFS("ndflash", 1, KHZ, 130000, 150000, 158000, 164000, 164000),
- CORE_DVFS("nor", 1, KHZ, 0, 92000, 92000, 92000, 92000),
- CORE_DVFS("ide", 1, KHZ, 0, 0, 100000, 100000, 100000),
- CORE_DVFS("mipi", 1, KHZ, 0, 40000, 40000, 40000, 60000),
- CORE_DVFS("usbd", 1, KHZ, 0, 0, 0, 480000, 480000),
- CORE_DVFS("usb2", 1, KHZ, 0, 0, 0, 480000, 480000),
- CORE_DVFS("usb3", 1, KHZ, 0, 0, 0, 480000, 480000),
- CORE_DVFS("pcie", 1, KHZ, 0, 0, 0, 250000, 250000),
- CORE_DVFS("dsi", 1, KHZ, 100000, 100000, 100000, 500000, 500000),
- CORE_DVFS("tvo", 1, KHZ, 0, 0, 0, 250000, 250000),
+ CORE_DVFS("ndflash", -1, 1, KHZ, 130000, 150000, 158000, 164000, 164000, 164000, 164000),
+ CORE_DVFS("nor", -1, 1, KHZ, 0, 92000, 92000, 92000, 92000, 92000, 92000),
+ CORE_DVFS("ide", -1, 1, KHZ, 0, 0, 100000, 100000, 100000, 100000, 100000),
+ CORE_DVFS("mipi", -1, 1, KHZ, 0, 40000, 40000, 40000, 40000, 60000, 60000),
+ CORE_DVFS("usbd", -1, 1, KHZ, 0, 0, 480000, 480000, 480000, 480000, 480000),
+ CORE_DVFS("usb2", -1, 1, KHZ, 0, 0, 480000, 480000, 480000, 480000, 480000),
+ CORE_DVFS("usb3", -1, 1, KHZ, 0, 0, 480000, 480000, 480000, 480000, 480000),
+ CORE_DVFS("pcie", -1, 1, KHZ, 0, 0, 0, 250000, 250000, 250000, 250000),
+ CORE_DVFS("dsi", -1, 1, KHZ, 100000, 100000, 100000, 500000, 500000, 500000, 500000),
+ CORE_DVFS("tvo", -1, 1, KHZ, 0, 0, 0, 250000, 250000, 250000, 250000),
/*
* The clock rate for the display controllers that determines the
@@ -182,24 +202,43 @@ static struct dvfs dvfs_init[] = {
* to the display block. Disable auto-dvfs on the display clocks,
* and let the display driver call tegra_dvfs_set_rate manually
*/
- CORE_DVFS("disp1", 0, KHZ, 158000, 158000, 190000, 190000, 190000),
- CORE_DVFS("disp2", 0, KHZ, 158000, 158000, 190000, 190000, 190000),
- CORE_DVFS("hdmi", 0, KHZ, 0, 0, 0, 148500, 148500),
+ CORE_DVFS("disp1", -1, 0, KHZ, 158000, 158000, 190000, 190000, 190000, 190000, 190000),
+ CORE_DVFS("disp2", -1, 0, KHZ, 158000, 158000, 190000, 190000, 190000, 190000, 190000),
+ CORE_DVFS("hdmi", -1, 0, KHZ, 0, 0, 0, 148500, 148500, 148500, 148500),
/*
- * These clocks technically depend on the core process id,
- * but just use the worst case value for now
+ * Clocks below depend on the core process id. Define per process_id
+ * tables for SCLK/VDE/3D clocks (maximum rate for these clocks is
+ * increased depending on tegra2 sku). Use the worst case value for
+ * other clocks for now.
*/
- CORE_DVFS("host1x", 1, KHZ, 104500, 133000, 166000, 166000, 166000),
- CORE_DVFS("epp", 1, KHZ, 133000, 171000, 247000, 300000, 300000),
- CORE_DVFS("2d", 1, KHZ, 133000, 171000, 247000, 300000, 300000),
- CORE_DVFS("3d", 1, KHZ, 114000, 161500, 247000, 300000, 300000),
- CORE_DVFS("mpe", 1, KHZ, 104500, 152000, 228000, 250000, 250000),
- CORE_DVFS("vi", 1, KHZ, 85000, 100000, 150000, 150000, 150000),
- CORE_DVFS("sclk", 1, KHZ, 95000, 133000, 190000, 250000, 250000),
- CORE_DVFS("vde", 1, KHZ, 95000, 123500, 209000, 250000, 250000),
+ CORE_DVFS("host1x", -1, 1, KHZ, 104500, 133000, 166000, 166000, 166000, 166000, 166000),
+ CORE_DVFS("epp", -1, 1, KHZ, 133000, 171000, 247000, 300000, 300000, 300000, 300000),
+ CORE_DVFS("2d", -1, 1, KHZ, 133000, 171000, 247000, 300000, 300000, 300000, 300000),
+
+ CORE_DVFS("3d", 0, 1, KHZ, 114000, 161500, 247000, 304000, 304000, 333500, 333500),
+ CORE_DVFS("3d", 1, 1, KHZ, 161500, 209000, 285000, 333500, 333500, 361000, 361000),
+ CORE_DVFS("3d", 2, 1, KHZ, 218500, 256500, 323000, 380000, 380000, 400000, 400000),
+ CORE_DVFS("3d", 3, 1, KHZ, 247000, 285000, 351500, 400000, 400000, 400000, 400000),
+
+ CORE_DVFS("mpe", 0, 1, KHZ, 104500, 152000, 228000, 300000, 300000, 300000, 300000),
+ CORE_DVFS("mpe", 1, 1, KHZ, 142500, 190000, 275500, 300000, 300000, 300000, 300000),
+ CORE_DVFS("mpe", 2, 1, KHZ, 190000, 237500, 300000, 300000, 300000, 300000, 300000),
+ CORE_DVFS("mpe", 3, 1, KHZ, 228000, 266000, 300000, 300000, 300000, 300000, 300000),
+
+ CORE_DVFS("vi", -1, 1, KHZ, 85000, 100000, 150000, 150000, 150000, 150000, 150000),
+
+ CORE_DVFS("sclk", 0, 1, KHZ, 95000, 133000, 190000, 222500, 240000, 247000, 262000),
+ CORE_DVFS("sclk", 1, 1, KHZ, 123500, 159500, 207000, 240000, 240000, 264000, 277500),
+ CORE_DVFS("sclk", 2, 1, KHZ, 152000, 180500, 229500, 260000, 260000, 285000, 300000),
+ CORE_DVFS("sclk", 3, 1, KHZ, 171000, 218500, 256500, 292500, 292500, 300000, 300000),
+
+ CORE_DVFS("vde", 0, 1, KHZ, 95000, 123500, 209000, 275500, 275500, 300000, 300000),
+ CORE_DVFS("vde", 1, 1, KHZ, 123500, 152000, 237500, 300000, 300000, 300000, 300000),
+ CORE_DVFS("vde", 2, 1, KHZ, 152000, 209000, 285000, 300000, 300000, 300000, 300000),
+ CORE_DVFS("vde", 3, 1, KHZ, 171000, 218500, 300000, 300000, 300000, 300000, 300000),
/* What is this? */
- CORE_DVFS("NVRM_DEVID_CLK_SRC", 1, MHZ, 480, 600, 800, 1067, 1067),
+ CORE_DVFS("NVRM_DEVID_CLK_SRC", -1, 1, MHZ, 480, 600, 800, 1067, 1067, 1067, 1067),
};
int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp)
@@ -259,8 +298,20 @@ void __init tegra2_init_dvfs(void)
int i;
struct clk *c;
struct dvfs *d;
+ int process_id;
int ret;
int cpu_process_id = tegra_cpu_process_id();
+ int core_process_id = tegra_core_process_id();
+ int speedo_id = tegra_soc_speedo_id();
+
+ BUG_ON(speedo_id >= ARRAY_SIZE(cpu_speedo_nominal_millivolts));
+ tegra2_dvfs_rail_vdd_cpu.nominal_millivolts =
+ cpu_speedo_nominal_millivolts[speedo_id];
+ BUG_ON(speedo_id >= ARRAY_SIZE(core_speedo_nominal_millivolts));
+ tegra2_dvfs_rail_vdd_core.nominal_millivolts =
+ core_speedo_nominal_millivolts[speedo_id];
+ tegra2_dvfs_rail_vdd_aon.nominal_millivolts =
+ core_speedo_nominal_millivolts[speedo_id];
tegra_dvfs_init_rails(tegra2_dvfs_rails, ARRAY_SIZE(tegra2_dvfs_rails));
tegra_dvfs_add_relationships(tegra2_dvfs_relationships,
@@ -272,9 +323,15 @@ void __init tegra2_init_dvfs(void)
for (i = 0; i < ARRAY_SIZE(dvfs_init); i++) {
d = &dvfs_init[i];
- if (d->cpu_process_id != -1 &&
- d->cpu_process_id != cpu_process_id)
+ process_id = strcmp(d->clk_name, "cpu") ?
+ core_process_id : cpu_process_id;
+ if ((d->process_id != -1 && d->process_id != process_id) ||
+ (d->speedo_id != -1 && d->speedo_id != speedo_id)) {
+ pr_debug("tegra_dvfs: rejected %s speedo %d,"
+ " process %d\n", d->clk_name, d->speedo_id,
+ d->process_id);
continue;
+ }
c = tegra_get_clock_by_name(d->clk_name);