1 /* arch/arm/mach-rk2818/cpufreq.c
3 * Copyright (C) 2010 ROCKCHIP, Inc.
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #ifdef CONFIG_CPU_FREQ_DEBUG
19 #define pr_fmt(fmt) "%s: " fmt, __func__
21 #include <linux/clk.h>
22 #include <linux/cpufreq.h>
23 #include <linux/err.h>
24 #include <linux/init.h>
25 #include <linux/regulator/consumer.h>
26 #include <linux/suspend.h>
27 #include <mach/cpufreq.h>
29 #define dprintk(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
31 #define SLEEP_FREQ (800 * 1000) /* Use 800MHz when entering sleep */
33 static int no_cpufreq_access;
35 static struct cpufreq_frequency_table default_freq_table[] = {
36 // { .index = 1100000, .frequency = 24000 },
37 // { .index = 1200000, .frequency = 204000 },
38 // { .index = 1200000, .frequency = 300000 },
39 { .index = 1200000, .frequency = 408000 },
40 // { .index = 1200000, .frequency = 600000 },
41 { .index = 1200000, .frequency = 816000 }, /* must enable, see SLEEP_FREQ above */
42 // { .index = 1250000, .frequency = 1008000 },
43 // { .index = 1300000, .frequency = 1104000 },
44 // { .index = 1400000, .frequency = 1176000 },
45 // { .index = 1400000, .frequency = 1200000 },
46 { .frequency = CPUFREQ_TABLE_END },
48 static struct cpufreq_frequency_table *freq_table = default_freq_table;
49 static struct clk *arm_clk;
50 static struct regulator *vcore;
53 int board_update_cpufreq_table(struct cpufreq_frequency_table *table)
59 static int rk29_cpufreq_verify(struct cpufreq_policy *policy)
61 return cpufreq_frequency_table_verify(policy, freq_table);
64 static int rk29_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation)
67 struct cpufreq_freqs freqs;
68 const struct cpufreq_frequency_table *freq;
74 if ((relation & ENABLE_FURTHER_CPUFREQ) &&
75 (relation & DISABLE_FURTHER_CPUFREQ)) {
76 /* Invalidate both if both marked */
77 relation &= ~ENABLE_FURTHER_CPUFREQ;
78 relation &= ~DISABLE_FURTHER_CPUFREQ;
79 pr_err("denied marking FURTHER_CPUFREQ as both marked.\n");
81 if (relation & ENABLE_FURTHER_CPUFREQ)
83 if (no_cpufreq_access) {
84 #ifdef CONFIG_PM_VERBOSE
85 pr_err("denied access to %s as it is disabled temporarily\n", __func__);
89 if (relation & DISABLE_FURTHER_CPUFREQ)
91 relation &= ~MASK_FURTHER_CPUFREQ;
93 if (cpufreq_frequency_table_target(policy, freq_table, target_freq, relation, &index)) {
94 pr_err("invalid target_freq: %d\n", target_freq);
97 freq = &freq_table[index];
99 if (policy->cur == freq->frequency)
102 freqs.old = policy->cur;
103 freqs.new = freq->frequency;
105 dprintk("%dHz r %d(%c) selected %dHz (%duV)\n",
106 target_freq, relation, relation == CPUFREQ_RELATION_L ? 'L' : 'H',
107 freq->frequency, freq->index);
109 #ifdef CONFIG_REGULATOR
110 if (vcore && freqs.new > freqs.old && vcore_uV != freq->index) {
111 err = regulator_set_voltage(vcore, freq->index, freq->index);
113 pr_err("fail to set vcore (%duV) for %dkHz: %d\n",
114 freq->index, freqs.new, err);
117 vcore_uV = freq->index;
121 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
122 dprintk("pre change\n");
123 clk_set_rate(arm_clk, freqs.new * 1000);
124 dprintk("post change\n");
125 freqs.new = clk_get_rate(arm_clk) / 1000;
126 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
128 #ifdef CONFIG_REGULATOR
129 if (vcore && freqs.new < freqs.old && vcore_uV != freq->index) {
130 err = regulator_set_voltage(vcore, freq->index, freq->index);
132 pr_err("fail to set vcore (%duV) for %dkHz: %d\n",
133 freq->index, freqs.new, err);
135 vcore_uV = freq->index;
138 dprintk("ok, got %dkHz\n", freqs.new);
144 static int __init rk29_cpufreq_init(struct cpufreq_policy *policy)
146 arm_clk = clk_get(NULL, "arm_pll");
148 return PTR_ERR(arm_clk);
150 if (policy->cpu != 0)
153 #ifdef CONFIG_REGULATOR
154 vcore = regulator_get(NULL, "vcore");
156 pr_err("fail to get regulator vcore: %ld\n", PTR_ERR(vcore));
161 BUG_ON(cpufreq_frequency_table_cpuinfo(policy, freq_table));
162 cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
163 policy->cur = clk_get_rate(arm_clk) / 1000;
165 policy->cpuinfo.transition_latency = 400 * NSEC_PER_USEC; // make default sampling_rate to 40000
170 static int rk29_cpufreq_exit(struct cpufreq_policy *policy)
173 regulator_put(vcore);
178 static struct freq_attr *rk29_cpufreq_attr[] = {
179 &cpufreq_freq_attr_scaling_available_freqs,
183 static struct cpufreq_driver rk29_cpufreq_driver = {
184 .flags = CPUFREQ_STICKY,
185 .init = rk29_cpufreq_init,
186 .exit = rk29_cpufreq_exit,
187 .verify = rk29_cpufreq_verify,
188 .target = rk29_cpufreq_target,
190 .attr = rk29_cpufreq_attr,
193 static int rk29_cpufreq_pm_notifier_event(struct notifier_block *this,
194 unsigned long event, void *ptr)
199 case PM_SUSPEND_PREPARE:
200 ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
201 DISABLE_FURTHER_CPUFREQ);
205 case PM_POST_RESTORE:
206 case PM_POST_SUSPEND:
207 cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
208 ENABLE_FURTHER_CPUFREQ);
214 static struct notifier_block rk29_cpufreq_pm_notifier = {
215 .notifier_call = rk29_cpufreq_pm_notifier_event,
218 static int __init rk29_cpufreq_register(void)
220 register_pm_notifier(&rk29_cpufreq_pm_notifier);
222 return cpufreq_register_driver(&rk29_cpufreq_driver);
225 device_initcall(rk29_cpufreq_register);