2 * OMAP CPU overclocking hacks
4 * Licensed under the GPL-2 or later.
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/proc_fs.h>
10 #include <linux/clk.h>
11 #include <linux/uaccess.h>
13 #include <plat/omap_device.h>
15 #define PROC_DIR "pandora"
16 #define PROC_CPUMHZ "pandora/cpu_mhz_max"
17 #define PROC_CPUOPP "pandora/cpu_opp_max"
18 #define PROC_SYSMHZ "pandora/sys_mhz_max"
20 /* FIXME: could use opp3xxx_data.c, but that's initdata.. */
21 static const unsigned long nominal_freqs_35xx[] = {
22 125000000, 250000000, 500000000, 550000000, 600000000,
25 static const unsigned long nominal_freqs_36xx[] = {
26 300000000, 600000000, 800000000, 1000000000,
29 static const unsigned long *nominal_freqs;
31 static int opp_max_avail, opp_max;
33 static int set_opp_max(int new_opp_max)
35 struct device *mpu_dev;
38 if (new_opp_max == opp_max)
41 mpu_dev = omap_device_get_by_hwmod_name("mpu");
42 if (IS_ERR(mpu_dev)) {
43 pr_err("%s: mpu device not available (%ld)\n",
44 __func__, PTR_ERR(mpu_dev));
48 for (i = 1; i < new_opp_max; i++) {
49 ret = opp_enable_i(mpu_dev, i);
51 dev_err(mpu_dev, "%s: opp_enable returned %d\n",
55 for (i = new_opp_max; i < opp_max_avail; i++) {
56 ret = opp_disable_i(mpu_dev, i);
58 dev_err(mpu_dev, "%s: opp_disable returned %d\n",
62 opp_max = new_opp_max;
63 dev_info(mpu_dev, "max OPP set to %d\n", opp_max);
68 static int set_cpu_mhz_max(unsigned long new_mhz_max)
70 unsigned long cur_mhz_max = 0;
71 struct device *mpu_dev;
74 new_mhz_max *= 1000000;
76 if (opp_max < 1 || opp_max > opp_max_avail) {
77 pr_err("%s: corrupt opp_max: %d\n", __func__, opp_max);
82 /* going below nominal makes no sense, it will save us nothing,
83 * user should reduce max OPP instead */
84 if (new_mhz_max < nominal_freqs[index])
85 new_mhz_max = nominal_freqs[index];
87 mpu_dev = omap_device_get_by_hwmod_name("mpu");
88 if (IS_ERR(mpu_dev)) {
89 pr_err("%s: mpu device not available (%ld)\n",
90 __func__, PTR_ERR(mpu_dev));
94 opp_hack_get_freq(mpu_dev, index, &cur_mhz_max);
95 if (cur_mhz_max == new_mhz_max)
98 ret = opp_hack_set_freq(mpu_dev, index, new_mhz_max);
100 dev_err(mpu_dev, "%s: opp_hack_set_freq returned %d\n",
108 static int get_cpu_mhz_max(void)
110 unsigned long cur_mhz_max = 0;
111 struct device *mpu_dev;
113 if (opp_max < 1 || opp_max > opp_max_avail) {
114 pr_err("%s: corrupt opp_max: %d\n", __func__, opp_max);
118 mpu_dev = omap_device_get_by_hwmod_name("mpu");
119 if (IS_ERR(mpu_dev)) {
120 pr_err("%s: mpu device not available (%ld)\n",
121 __func__, PTR_ERR(mpu_dev));
125 opp_hack_get_freq(mpu_dev, opp_max - 1, &cur_mhz_max);
127 return cur_mhz_max / 1000000;
130 static int init_opp_hacks(void)
132 struct device *mpu_dev;
134 mpu_dev = omap_device_get_by_hwmod_name("mpu");
135 if (IS_ERR(mpu_dev)) {
136 pr_err("%s: mpu device not available (%ld)\n",
137 __func__, PTR_ERR(mpu_dev));
141 if (cpu_is_omap3630()) {
142 nominal_freqs = nominal_freqs_36xx;
143 opp_max_avail = sizeof(nominal_freqs_36xx) / sizeof(nominal_freqs_36xx[0]);
145 } else if (cpu_is_omap34xx()) {
146 nominal_freqs = nominal_freqs_35xx;
147 opp_max_avail = sizeof(nominal_freqs_35xx) / sizeof(nominal_freqs_35xx[0]);
148 opp_max = opp_max_avail;
150 dev_err(mpu_dev, "%s: unsupported CPU\n", __func__);
157 static int set_sys_mhz_max(unsigned long rate)
159 struct clk *dpll3_m2_ck;
164 dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
165 if (IS_ERR(dpll3_m2_ck)) {
166 pr_err("%s: dpll3_m2_clk not available: %ld\n",
167 __func__, PTR_ERR(dpll3_m2_ck));
171 pr_info("Reprogramming CORE clock to %luHz\n", rate);
172 ret = clk_set_rate(dpll3_m2_ck, rate);
174 pr_err("dpll3_m2_clk rate change failed: %d\n", ret);
176 clk_put(dpll3_m2_ck);
181 static int get_sys_mhz_max(void)
183 struct clk *dpll3_m2_ck;
186 dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
187 if (IS_ERR(dpll3_m2_ck)) {
188 pr_err("%s: dpll3_m2_clk not available: %ld\n",
189 __func__, PTR_ERR(dpll3_m2_ck));
193 ret = clk_get_rate(dpll3_m2_ck);
194 clk_put(dpll3_m2_ck);
196 return ret / 1000000;
199 static int proc_read_val(char *page, char **start, off_t off, int count,
205 p += sprintf(p, "%d\n", val);
207 len = (p - page) - off;
211 *eof = (len <= count) ? 1 : 0;
217 static int proc_write_val(struct file *file, const char __user *buffer,
218 unsigned long count, unsigned long *val)
223 count = strncpy_from_user(buff, buffer,
224 count < sizeof(buff) ? count : sizeof(buff) - 1);
227 ret = strict_strtoul(buff, 0, val);
229 pr_err("error %i parsing %s\n", ret, buff);
236 static int cpu_clk_read(char *page, char **start, off_t off, int count,
237 int *eof, void *data)
239 return proc_read_val(page, start, off, count, eof, get_cpu_mhz_max());
242 static int cpu_clk_write(struct file *file, const char __user *buffer,
243 unsigned long count, void *data)
248 retval = proc_write_val(file, buffer, count, &val);
252 ret = set_cpu_mhz_max(val);
259 static int cpu_maxopp_read(char *page, char **start, off_t off, int count,
260 int *eof, void *data)
262 return proc_read_val(page, start, off, count, eof, opp_max);
265 static int cpu_maxopp_write(struct file *file, const char __user *buffer,
266 unsigned long count, void *data)
271 retval = proc_write_val(file, buffer, count, &val);
275 if (val > opp_max_avail)
281 ret = set_opp_max(val);
288 static int sys_clk_read(char *page, char **start, off_t off, int count,
289 int *eof, void *data)
291 return proc_read_val(page, start, off, count, eof, get_sys_mhz_max());
294 static int sys_clk_write(struct file *file, const char __user *buffer,
295 unsigned long count, void *data)
300 retval = proc_write_val(file, buffer, count, &val);
304 ret = set_sys_mhz_max(val);
311 static void proc_create_rw(const char *name, void *pdata,
312 read_proc_t *read_proc, write_proc_t *write_proc)
314 struct proc_dir_entry *pret;
316 pret = create_proc_entry(name, S_IWUSR | S_IRUGO, NULL);
318 proc_mkdir(PROC_DIR, NULL);
319 pret = create_proc_entry(name, S_IWUSR | S_IRUGO, NULL);
321 pr_err("%s: failed to create proc file %s\n",
328 pret->read_proc = read_proc;
329 pret->write_proc = write_proc;
332 static int pndctrl_init(void)
336 ret = init_opp_hacks();
338 pr_err("init_opp_hacks failed: %d\n", ret);
342 proc_create_rw(PROC_CPUMHZ, NULL, cpu_clk_read, cpu_clk_write);
343 proc_create_rw(PROC_CPUOPP, NULL, cpu_maxopp_read, cpu_maxopp_write);
344 proc_create_rw(PROC_SYSMHZ, NULL, sys_clk_read, sys_clk_write);
346 pr_info("OMAP overclocker loaded.\n");
351 static void pndctrl_cleanup(void)
353 remove_proc_entry(PROC_CPUOPP, NULL);
354 remove_proc_entry(PROC_CPUMHZ, NULL);
355 remove_proc_entry(PROC_SYSMHZ, NULL);
358 module_init(pndctrl_init);
359 module_exit(pndctrl_cleanup);
361 MODULE_AUTHOR("GraÅžvydas Ignotas");
362 MODULE_LICENSE("GPL");
363 MODULE_DESCRIPTION("OMAP overclocking support");