summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-04-02 18:15:45 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:42:29 -0800
commit80126ffc8ce8a45968b174d54d2f4ce5173a7394 (patch)
treec8ccac14e18964d5cda5cd6df5821ec8974ac178 /arch/arm
parent94c3df8e013357feb576ae631f78aae21db2ad71 (diff)
ARM: tegra: power: Split Tegra3 CPU-G and CPU-LP dvfs
On Tegra3 CPU power is supplied by different rails in G-mode (VDD_CPU) and LP mode (VDD_CORE) - updated dvfs dependencies respectively. Original-Change-Id: Ifae8ae501b227a44e46ce1577bcd532e2e778322 Reviewed-on: http://git-master/r/25200 Reviewed-by: Aleksandr Frid <afrid@nvidia.com> Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com> Tested-by: Diwakar Tundlam <dtundlam@nvidia.com> Reviewed-by: Scott Williams <scwilliams@nvidia.com> Original-Change-Id: I96e6cb7e3dcdf8514714d2900d8f947b6438c95f Rebase-Id: R4d16a0002c701f6ee2f0f8c0f66c5313e4546d53
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-tegra/clock.c14
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c78
2 files changed, 68 insertions, 24 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index cce16b29aaf7..2fe6df739fd6 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -175,10 +175,16 @@ static void __clk_set_cansleep(struct clk *c)
if (child->parent != c)
continue;
- WARN(child->ops && child->ops->set_parent,
- "can't make child clock %s of %s "
- "sleepable if it's parent could change",
- child->name, c->name);
+ /* If set_parent operation is implemented for virtual cpu,
+ all possible parents are sleeping clocks - hence, no
+ warning. FIXME: another way to make this exception ? */
+ if(strcmp(child->name, "cpu")) {
+ WARN(child->ops && child->ops->set_parent,
+ "sleepable clock %s is not a sole parent"
+ " of its child %s - if child is reparented"
+ " only sleepable parents should be used",
+ c->name, child->name);
+ }
__clk_set_cansleep(child);
}
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c
index 994d45715de2..7ff7cc3c1bbb 100644
--- a/arch/arm/mach-tegra/tegra3_dvfs.c
+++ b/arch/arm/mach-tegra/tegra3_dvfs.c
@@ -28,6 +28,9 @@ static bool tegra_dvfs_cpu_disabled = false;
static const int cpu_millivolts[MAX_DVFS_FREQS] =
{750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1100, 1125};
+static const int core_millivolts[MAX_DVFS_FREQS] =
+ {950, 1000, 1100, 1200};
+
#define KHZ 1000
#define MHZ 1000000
@@ -38,8 +41,18 @@ static struct dvfs_rail tegra3_dvfs_rail_vdd_cpu = {
.nominal_millivolts = 1000,
};
+static struct dvfs_rail tegra3_dvfs_rail_vdd_core = {
+ .reg_id = "vdd_core",
+ .max_millivolts = 1300,
+ .min_millivolts = 950,
+ .nominal_millivolts = 1200,
+ .step = 100, /* FIXME: step vdd_core by 100 mV - maybe not needed */
+ .disabled = true, /* FIXME: replace with sysfs control */
+};
+
static struct dvfs_rail *tegra3_dvfs_rails[] = {
&tegra3_dvfs_rail_vdd_cpu,
+ &tegra3_dvfs_rail_vdd_core,
};
#define CPU_DVFS(_clk_name, _speedo_id, _process_id, _mult, _freqs...) \
@@ -54,9 +67,26 @@ static struct dvfs_rail *tegra3_dvfs_rails[] = {
.dvfs_rail = &tegra3_dvfs_rail_vdd_cpu, \
}
-static struct dvfs dvfs_init[] = {
- /* Cpu voltages (mV): 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1100, 1125 */
- CPU_DVFS("cpu", 0, 0, MHZ, 0, 0, 614, 614, 714, 714, 815, 815, 915, 915, 1000),
+static struct dvfs cpu_dvfs_table[] = {
+ /* Cpu voltages (mV): 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000, 1025, 1050, 1100, 1125 */
+ CPU_DVFS("cpu_g", 0, 0, MHZ, 0, 0, 614, 614, 714, 714, 815, 815, 915, 915, 1000),
+};
+
+#define CORE_DVFS(_clk_name, _process_id, _auto, _mult, _freqs...) \
+ { \
+ .clk_name = _clk_name, \
+ .speedo_id = -1, \
+ .process_id = _process_id, \
+ .freqs = {_freqs}, \
+ .freqs_mult = _mult, \
+ .millivolts = core_millivolts, \
+ .auto_dvfs = _auto, \
+ .dvfs_rail = &tegra3_dvfs_rail_vdd_core, \
+ }
+
+static struct dvfs core_dvfs_table[] = {
+ /* Cpu voltages (mV): 950, 1000, 1100, 1200 */
+ CORE_DVFS("cpu_lp", 0, 1, KHZ, 313500, 361000, 456000, 456000)
};
int tegra_dvfs_disable_cpu_set(const char *arg, const struct kernel_param *kp)
@@ -87,28 +117,16 @@ static struct kernel_param_ops tegra_dvfs_disable_cpu_ops = {
module_param_cb(disable_cpu, &tegra_dvfs_disable_cpu_ops, &tegra_dvfs_cpu_disabled, 0644);
-void __init tegra_soc_init_dvfs(void)
+static void init_dvfs_from_table(struct dvfs *dvfs_table, int table_size,
+ int speedo_id, int process_id)
{
- int i;
+ int i, ret;
struct clk *c;
struct dvfs *d;
- int process_id;
- int cpu_process_id = 0;
- int speedo_id = 0;
- int ret;
-
-#ifndef CONFIG_TEGRA_CPU_DVFS
- tegra_dvfs_cpu_disabled = true;
-#endif
- tegra_dvfs_init_rails(tegra3_dvfs_rails, ARRAY_SIZE(tegra3_dvfs_rails));
+ for (i = 0; i < table_size; i++) {
+ d = &dvfs_table[i];
- /* FIXME: add [CPU/CORE/AON] relationships here */
-
- for (i = 0; i < ARRAY_SIZE(dvfs_init); i++) {
- d = &dvfs_init[i];
-
- 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("tegra3_dvfs: rejected %s speedo %d,"
@@ -130,6 +148,26 @@ void __init tegra_soc_init_dvfs(void)
pr_err("tegra3_dvfs: failed to enable dvfs on %s\n",
c->name);
}
+}
+
+void __init tegra_soc_init_dvfs(void)
+{
+ int speedo_id = 0; /* FIXME: get real speedo ID */
+ int cpu_process_id = 0; /* FIXME: get real CPU process ID */
+ int core_process_id = 0; /* FIXME: get real core process ID */
+
+#ifndef CONFIG_TEGRA_CPU_DVFS
+ tegra_dvfs_cpu_disabled = true;
+#endif
+
+ tegra_dvfs_init_rails(tegra3_dvfs_rails, ARRAY_SIZE(tegra3_dvfs_rails));
+
+ /* FIXME: add [CPU/CORE/AON] relationships here */
+
+ init_dvfs_from_table(cpu_dvfs_table, ARRAY_SIZE(cpu_dvfs_table),
+ speedo_id, cpu_process_id);
+ init_dvfs_from_table(core_dvfs_table, ARRAY_SIZE(core_dvfs_table),
+ speedo_id, core_process_id);
if (tegra_dvfs_cpu_disabled)
tegra_dvfs_rail_disable(&tegra3_dvfs_rail_vdd_cpu);