aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/clock.c159
-rw-r--r--arch/arm/mach-tegra/clock.h24
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c2
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h5
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c2
-rw-r--r--arch/arm/mach-tegra/tegra2_dvfs.c86
-rw-r--r--arch/arm/mach-tegra/tegra2_dvfs.h20
8 files changed, 2 insertions, 297 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 6b537de5a38f..23de0600a19d 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -9,7 +9,6 @@ obj-y += powergate.o
9obj-y += fuse.o 9obj-y += fuse.o
10obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o 10obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o
11obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o 11obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
12obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_dvfs.o
13obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o 12obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o
14obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o 13obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
15obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 14obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 92bcc2072302..8fd96bfb0cde 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -24,81 +24,14 @@
24#include <linux/debugfs.h> 24#include <linux/debugfs.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/seq_file.h> 26#include <linux/seq_file.h>
27#include <linux/regulator/consumer.h>
28#include <linux/clkdev.h> 27#include <linux/clkdev.h>
29 28
30#include "clock.h"
31#include "board.h" 29#include "board.h"
32#include "fuse.h" 30#include "clock.h"
33 31
34static LIST_HEAD(clocks); 32static LIST_HEAD(clocks);
35 33
36static DEFINE_SPINLOCK(clock_lock); 34static DEFINE_SPINLOCK(clock_lock);
37static DEFINE_MUTEX(dvfs_lock);
38
39static int clk_is_dvfs(struct clk *c)
40{
41 return (c->dvfs != NULL);
42};
43
44static int dvfs_set_rate(struct dvfs *d, unsigned long rate)
45{
46 struct dvfs_table *t;
47
48 if (d->table == NULL)
49 return -ENODEV;
50
51 for (t = d->table; t->rate != 0; t++) {
52 if (rate <= t->rate) {
53 if (!d->reg)
54 return 0;
55
56 return regulator_set_voltage(d->reg,
57 t->millivolts * 1000,
58 d->max_millivolts * 1000);
59 }
60 }
61
62 return -EINVAL;
63}
64
65static void dvfs_init(struct clk *c)
66{
67 int process_id;
68 int i;
69 struct dvfs_table *table;
70
71 process_id = c->dvfs->cpu ? tegra_core_process_id() :
72 tegra_cpu_process_id();
73
74 for (i = 0; i < c->dvfs->process_id_table_length; i++)
75 if (process_id == c->dvfs->process_id_table[i].process_id)
76 c->dvfs->table = c->dvfs->process_id_table[i].table;
77
78 if (c->dvfs->table == NULL) {
79 pr_err("Failed to find dvfs table for clock %s process %d\n",
80 c->name, process_id);
81 return;
82 }
83
84 c->dvfs->max_millivolts = 0;
85 for (table = c->dvfs->table; table->rate != 0; table++)
86 if (c->dvfs->max_millivolts < table->millivolts)
87 c->dvfs->max_millivolts = table->millivolts;
88
89 c->dvfs->reg = regulator_get(NULL, c->dvfs->reg_id);
90
91 if (IS_ERR(c->dvfs->reg)) {
92 pr_err("Failed to get regulator %s for clock %s\n",
93 c->dvfs->reg_id, c->name);
94 c->dvfs->reg = NULL;
95 return;
96 }
97
98 if (c->refcnt > 0)
99 dvfs_set_rate(c->dvfs, c->rate);
100}
101
102struct clk *tegra_get_clock_by_name(const char *name) 35struct clk *tegra_get_clock_by_name(const char *name)
103{ 36{
104 struct clk *c; 37 struct clk *c;
@@ -214,34 +147,11 @@ int clk_enable_locked(struct clk *c)
214 return 0; 147 return 0;
215} 148}
216 149
217int clk_enable_cansleep(struct clk *c)
218{
219 int ret;
220 unsigned long flags;
221
222 mutex_lock(&dvfs_lock);
223
224 if (clk_is_dvfs(c) && c->refcnt > 0)
225 dvfs_set_rate(c->dvfs, c->rate);
226
227 spin_lock_irqsave(&clock_lock, flags);
228 ret = clk_enable_locked(c);
229 spin_unlock_irqrestore(&clock_lock, flags);
230
231 mutex_unlock(&dvfs_lock);
232
233 return ret;
234}
235EXPORT_SYMBOL(clk_enable_cansleep);
236
237int clk_enable(struct clk *c) 150int clk_enable(struct clk *c)
238{ 151{
239 int ret; 152 int ret;
240 unsigned long flags; 153 unsigned long flags;
241 154
242 if (clk_is_dvfs(c))
243 BUG();
244
245 spin_lock_irqsave(&clock_lock, flags); 155 spin_lock_irqsave(&clock_lock, flags);
246 ret = clk_enable_locked(c); 156 ret = clk_enable_locked(c);
247 spin_unlock_irqrestore(&clock_lock, flags); 157 spin_unlock_irqrestore(&clock_lock, flags);
@@ -268,30 +178,10 @@ void clk_disable_locked(struct clk *c)
268 c->refcnt--; 178 c->refcnt--;
269} 179}
270 180
271void clk_disable_cansleep(struct clk *c)
272{
273 unsigned long flags;
274
275 mutex_lock(&dvfs_lock);
276
277 spin_lock_irqsave(&clock_lock, flags);
278 clk_disable_locked(c);
279 spin_unlock_irqrestore(&clock_lock, flags);
280
281 if (clk_is_dvfs(c) && c->refcnt == 0)
282 dvfs_set_rate(c->dvfs, c->rate);
283
284 mutex_unlock(&dvfs_lock);
285}
286EXPORT_SYMBOL(clk_disable_cansleep);
287
288void clk_disable(struct clk *c) 181void clk_disable(struct clk *c)
289{ 182{
290 unsigned long flags; 183 unsigned long flags;
291 184
292 if (clk_is_dvfs(c))
293 BUG();
294
295 spin_lock_irqsave(&clock_lock, flags); 185 spin_lock_irqsave(&clock_lock, flags);
296 clk_disable_locked(c); 186 clk_disable_locked(c);
297 spin_unlock_irqrestore(&clock_lock, flags); 187 spin_unlock_irqrestore(&clock_lock, flags);
@@ -356,41 +246,11 @@ int clk_set_rate_locked(struct clk *c, unsigned long rate)
356 return 0; 246 return 0;
357} 247}
358 248
359int clk_set_rate_cansleep(struct clk *c, unsigned long rate)
360{
361 int ret = 0;
362 unsigned long flags;
363
364 mutex_lock(&dvfs_lock);
365
366 if (rate > c->rate)
367 ret = dvfs_set_rate(c->dvfs, rate);
368 if (ret)
369 goto out;
370
371 spin_lock_irqsave(&clock_lock, flags);
372 ret = clk_set_rate_locked(c, rate);
373 spin_unlock_irqrestore(&clock_lock, flags);
374
375 if (ret)
376 goto out;
377
378 ret = dvfs_set_rate(c->dvfs, rate);
379
380out:
381 mutex_unlock(&dvfs_lock);
382 return ret;
383}
384EXPORT_SYMBOL(clk_set_rate_cansleep);
385
386int clk_set_rate(struct clk *c, unsigned long rate) 249int clk_set_rate(struct clk *c, unsigned long rate)
387{ 250{
388 int ret = 0; 251 int ret = 0;
389 unsigned long flags; 252 unsigned long flags;
390 253
391 if (clk_is_dvfs(c))
392 BUG();
393
394 spin_lock_irqsave(&clock_lock, flags); 254 spin_lock_irqsave(&clock_lock, flags);
395 ret = clk_set_rate_locked(c, rate); 255 ret = clk_set_rate_locked(c, rate);
396 spin_unlock_irqrestore(&clock_lock, flags); 256 spin_unlock_irqrestore(&clock_lock, flags);
@@ -503,23 +363,6 @@ void __init tegra_init_clock(void)
503 tegra2_init_clocks(); 363 tegra2_init_clocks();
504} 364}
505 365
506int __init tegra_init_dvfs(void)
507{
508 struct clk *c, *safe;
509
510 mutex_lock(&dvfs_lock);
511
512 list_for_each_entry_safe(c, safe, &clocks, node)
513 if (c->dvfs)
514 dvfs_init(c);
515
516 mutex_unlock(&dvfs_lock);
517
518 return 0;
519}
520
521late_initcall(tegra_init_dvfs);
522
523#ifdef CONFIG_DEBUG_FS 366#ifdef CONFIG_DEBUG_FS
524static struct dentry *clk_debugfs_root; 367static struct dentry *clk_debugfs_root;
525 368
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index b76d33df88d7..198f2344d02f 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -41,28 +41,6 @@
41#define ENABLE_ON_INIT (1 << 28) 41#define ENABLE_ON_INIT (1 << 28)
42 42
43struct clk; 43struct clk;
44struct regulator;
45
46struct dvfs_table {
47 unsigned long rate;
48 int millivolts;
49};
50
51struct dvfs_process_id_table {
52 int process_id;
53 struct dvfs_table *table;
54};
55
56struct dvfs {
57 struct regulator *reg;
58 struct dvfs_table *table;
59 int max_millivolts;
60
61 int process_id_table_length;
62 const char *reg_id;
63 bool cpu;
64 struct dvfs_process_id_table process_id_table[];
65};
66 44
67struct clk_mux_sel { 45struct clk_mux_sel {
68 struct clk *input; 46 struct clk *input;
@@ -141,8 +119,6 @@ struct clk {
141 /* Virtual cpu clock */ 119 /* Virtual cpu clock */
142 struct clk *main; 120 struct clk *main;
143 struct clk *backup; 121 struct clk *backup;
144
145 struct dvfs *dvfs;
146}; 122};
147 123
148 124
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index ad26a9f3a134..cda03f11550e 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -91,7 +91,7 @@ static int tegra_update_cpu_speed(unsigned long rate)
91 freqs.old, freqs.new); 91 freqs.old, freqs.new);
92#endif 92#endif
93 93
94 ret = clk_set_rate_cansleep(cpu_clk, freqs.new * 1000); 94 ret = clk_set_rate(cpu_clk, freqs.new * 1000);
95 if (ret) { 95 if (ret) {
96 pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n", 96 pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n",
97 freqs.new); 97 freqs.new);
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index a217f68ba57c..633865298ae4 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -25,9 +25,4 @@ struct clk;
25void tegra_periph_reset_deassert(struct clk *c); 25void tegra_periph_reset_deassert(struct clk *c);
26void tegra_periph_reset_assert(struct clk *c); 26void tegra_periph_reset_assert(struct clk *c);
27 27
28int clk_enable_cansleep(struct clk *clk);
29void clk_disable_cansleep(struct clk *clk);
30int clk_set_rate_cansleep(struct clk *clk, unsigned long rate);
31int clk_set_parent_cansleep(struct clk *clk, struct clk *parent);
32
33#endif 28#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index eb4e9ca5c6ae..d0b759023582 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -31,7 +31,6 @@
31 31
32#include "clock.h" 32#include "clock.h"
33#include "fuse.h" 33#include "fuse.h"
34#include "tegra2_dvfs.h"
35 34
36#define RST_DEVICES 0x004 35#define RST_DEVICES 0x004
37#define RST_DEVICES_SET 0x300 36#define RST_DEVICES_SET 0x300
@@ -1650,7 +1649,6 @@ static struct clk tegra_clk_virtual_cpu = {
1650 .backup = &tegra_pll_p, 1649 .backup = &tegra_pll_p,
1651 .ops = &tegra_cpu_ops, 1650 .ops = &tegra_cpu_ops,
1652 .max_rate = 1000000000, 1651 .max_rate = 1000000000,
1653 .dvfs = &tegra_dvfs_virtual_cpu_dvfs,
1654}; 1652};
1655 1653
1656static struct clk tegra_clk_hclk = { 1654static struct clk tegra_clk_hclk = {
diff --git a/arch/arm/mach-tegra/tegra2_dvfs.c b/arch/arm/mach-tegra/tegra2_dvfs.c
deleted file mode 100644
index 5529c238dd77..000000000000
--- a/arch/arm/mach-tegra/tegra2_dvfs.c
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2 * arch/arm/mach-tegra/tegra2_dvfs.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/kernel.h>
21
22#include "clock.h"
23#include "tegra2_dvfs.h"
24
25static struct dvfs_table virtual_cpu_process_0[] = {
26 {314000000, 750},
27 {456000000, 825},
28 {608000000, 900},
29 {760000000, 975},
30 {817000000, 1000},
31 {912000000, 1050},
32 {1000000000, 1100},
33 {0, 0},
34};
35
36static struct dvfs_table virtual_cpu_process_1[] = {
37 {314000000, 750},
38 {456000000, 825},
39 {618000000, 900},
40 {770000000, 975},
41 {827000000, 1000},
42 {922000000, 1050},
43 {1000000000, 1100},
44 {0, 0},
45};
46
47static struct dvfs_table virtual_cpu_process_2[] = {
48 {494000000, 750},
49 {675000000, 825},
50 {817000000, 875},
51 {922000000, 925},
52 {1000000000, 975},
53 {0, 0},
54};
55
56static struct dvfs_table virtual_cpu_process_3[] = {
57 {730000000, 750},
58 {760000000, 775},
59 {845000000, 800},
60 {1000000000, 875},
61 {0, 0},
62};
63
64struct dvfs tegra_dvfs_virtual_cpu_dvfs = {
65 .reg_id = "vdd_cpu",
66 .process_id_table = {
67 {
68 .process_id = 0,
69 .table = virtual_cpu_process_0,
70 },
71 {
72 .process_id = 1,
73 .table = virtual_cpu_process_1,
74 },
75 {
76 .process_id = 2,
77 .table = virtual_cpu_process_2,
78 },
79 {
80 .process_id = 3,
81 .table = virtual_cpu_process_3,
82 },
83 },
84 .process_id_table_length = 4,
85 .cpu = 1,
86};
diff --git a/arch/arm/mach-tegra/tegra2_dvfs.h b/arch/arm/mach-tegra/tegra2_dvfs.h
deleted file mode 100644
index f8c1adba96a6..000000000000
--- a/arch/arm/mach-tegra/tegra2_dvfs.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * arch/arm/mach-tegra/tegra2_dvfs.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 *
6 * Author:
7 * Colin Cross <ccross@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20extern struct dvfs tegra_dvfs_virtual_cpu_dvfs;