diff options
author | Alex Frid <afrid@nvidia.com> | 2011-04-02 18:15:45 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:42:29 -0800 |
commit | 80126ffc8ce8a45968b174d54d2f4ce5173a7394 (patch) | |
tree | c8ccac14e18964d5cda5cd6df5821ec8974ac178 /arch/arm | |
parent | 94c3df8e013357feb576ae631f78aae21db2ad71 (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.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_dvfs.c | 78 |
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); |