diff options
author | Colin Cross <ccross@android.com> | 2011-02-12 18:52:04 -0500 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-02-21 03:10:06 -0500 |
commit | 41cfe3676d0f4f07ba79d4f64a21450ab02d22cd (patch) | |
tree | ada86fc6fa5099fdccd57cdb229b2b345d422b0a | |
parent | f035530b799a9c945415ad2139bb6494b542639a (diff) |
ARM: tegra: clock: Drop CPU dvfs
The existing version did not extend well to core dvfs, drop it
for now until the new clk api with clk_prepare and clk_unprepare
is ready and non-atomic clocks are possible.
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Colin Cross <ccross@android.com>
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/clock.c | 159 | ||||
-rw-r--r-- | arch/arm/mach-tegra/clock.h | 24 | ||||
-rw-r--r-- | arch/arm/mach-tegra/cpu-tegra.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/clk.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_clocks.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_dvfs.c | 86 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_dvfs.h | 20 |
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 | |||
9 | obj-y += fuse.o | 9 | obj-y += fuse.o |
10 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o | 10 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o |
11 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o | 11 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o |
12 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_dvfs.o | ||
13 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o | 12 | obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o |
14 | obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o | 13 | obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o |
15 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 14 | obj-$(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 | ||
34 | static LIST_HEAD(clocks); | 32 | static LIST_HEAD(clocks); |
35 | 33 | ||
36 | static DEFINE_SPINLOCK(clock_lock); | 34 | static DEFINE_SPINLOCK(clock_lock); |
37 | static DEFINE_MUTEX(dvfs_lock); | ||
38 | |||
39 | static int clk_is_dvfs(struct clk *c) | ||
40 | { | ||
41 | return (c->dvfs != NULL); | ||
42 | }; | ||
43 | |||
44 | static 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 | |||
65 | static 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 | |||
102 | struct clk *tegra_get_clock_by_name(const char *name) | 35 | struct 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 | ||
217 | int 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 | } | ||
235 | EXPORT_SYMBOL(clk_enable_cansleep); | ||
236 | |||
237 | int clk_enable(struct clk *c) | 150 | int 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 | ||
271 | void 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 | } | ||
286 | EXPORT_SYMBOL(clk_disable_cansleep); | ||
287 | |||
288 | void clk_disable(struct clk *c) | 181 | void 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 | ||
359 | int 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 | |||
380 | out: | ||
381 | mutex_unlock(&dvfs_lock); | ||
382 | return ret; | ||
383 | } | ||
384 | EXPORT_SYMBOL(clk_set_rate_cansleep); | ||
385 | |||
386 | int clk_set_rate(struct clk *c, unsigned long rate) | 249 | int 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 | ||
506 | int __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 | |||
521 | late_initcall(tegra_init_dvfs); | ||
522 | |||
523 | #ifdef CONFIG_DEBUG_FS | 366 | #ifdef CONFIG_DEBUG_FS |
524 | static struct dentry *clk_debugfs_root; | 367 | static 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 | ||
43 | struct clk; | 43 | struct clk; |
44 | struct regulator; | ||
45 | |||
46 | struct dvfs_table { | ||
47 | unsigned long rate; | ||
48 | int millivolts; | ||
49 | }; | ||
50 | |||
51 | struct dvfs_process_id_table { | ||
52 | int process_id; | ||
53 | struct dvfs_table *table; | ||
54 | }; | ||
55 | |||
56 | struct 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 | ||
67 | struct clk_mux_sel { | 45 | struct 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; | |||
25 | void tegra_periph_reset_deassert(struct clk *c); | 25 | void tegra_periph_reset_deassert(struct clk *c); |
26 | void tegra_periph_reset_assert(struct clk *c); | 26 | void tegra_periph_reset_assert(struct clk *c); |
27 | 27 | ||
28 | int clk_enable_cansleep(struct clk *clk); | ||
29 | void clk_disable_cansleep(struct clk *clk); | ||
30 | int clk_set_rate_cansleep(struct clk *clk, unsigned long rate); | ||
31 | int 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 | ||
1656 | static struct clk tegra_clk_hclk = { | 1654 | static 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 | |||
25 | static 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 | |||
36 | static 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 | |||
47 | static 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 | |||
56 | static struct dvfs_table virtual_cpu_process_3[] = { | ||
57 | {730000000, 750}, | ||
58 | {760000000, 775}, | ||
59 | {845000000, 800}, | ||
60 | {1000000000, 875}, | ||
61 | {0, 0}, | ||
62 | }; | ||
63 | |||
64 | struct 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 | |||
20 | extern struct dvfs tegra_dvfs_virtual_cpu_dvfs; | ||