2 * Copyright (C) 2004-2007 Atmel Corporation
4 * Based on MIPS implementation arch/mips/kernel/time.c
5 * Copyright 2001 MontaVista Software Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
14 #include <linux/kernel.h>
15 #include <linux/types.h>
16 #include <linux/init.h>
17 #include <linux/cpufreq.h>
19 #include <linux/clk.h>
20 #include <linux/err.h>
21 #include <linux/export.h>
22 #include <linux/slab.h>
24 static struct clk
*cpuclk
;
25 static struct cpufreq_frequency_table
*freq_table
;
27 static unsigned int at32_get_speed(unsigned int cpu
)
32 return (unsigned int)((clk_get_rate(cpuclk
) + 500) / 1000);
35 static unsigned int ref_freq
;
36 static unsigned long loops_per_jiffy_ref
;
38 static int at32_set_target(struct cpufreq_policy
*policy
, unsigned int index
)
40 unsigned int old_freq
, new_freq
;
42 old_freq
= at32_get_speed(0);
43 new_freq
= freq_table
[index
].frequency
;
47 loops_per_jiffy_ref
= boot_cpu_data
.loops_per_jiffy
;
50 if (old_freq
< new_freq
)
51 boot_cpu_data
.loops_per_jiffy
= cpufreq_scale(
52 loops_per_jiffy_ref
, ref_freq
, new_freq
);
53 clk_set_rate(cpuclk
, new_freq
* 1000);
54 if (new_freq
< old_freq
)
55 boot_cpu_data
.loops_per_jiffy
= cpufreq_scale(
56 loops_per_jiffy_ref
, ref_freq
, new_freq
);
61 static int __init
at32_cpufreq_driver_init(struct cpufreq_policy
*policy
)
63 unsigned int frequency
, rate
, min_freq
;
69 cpuclk
= clk_get(NULL
, "cpu");
71 pr_debug("cpufreq: could not get CPU clk\n");
72 retval
= PTR_ERR(cpuclk
);
76 min_freq
= (clk_round_rate(cpuclk
, 1) + 500) / 1000;
77 frequency
= (clk_round_rate(cpuclk
, ~0UL) + 500) / 1000;
78 policy
->cpuinfo
.transition_latency
= 0;
81 * AVR32 CPU frequency rate scales in power of two between maximum and
82 * minimum, also add space for the table end marker.
84 * Further validate that the frequency is usable, and append it to the
87 steps
= fls(frequency
/ min_freq
) + 1;
88 freq_table
= kzalloc(steps
* sizeof(struct cpufreq_frequency_table
),
95 for (i
= 0; i
< (steps
- 1); i
++) {
96 rate
= clk_round_rate(cpuclk
, frequency
* 1000) / 1000;
98 if (rate
!= frequency
)
99 freq_table
[i
].frequency
= CPUFREQ_ENTRY_INVALID
;
101 freq_table
[i
].frequency
= frequency
;
106 freq_table
[steps
- 1].frequency
= CPUFREQ_TABLE_END
;
108 retval
= cpufreq_table_validate_and_show(policy
, freq_table
);
110 printk("cpufreq: AT32AP CPU frequency driver\n");
121 static struct cpufreq_driver at32_driver
= {
123 .init
= at32_cpufreq_driver_init
,
124 .verify
= cpufreq_generic_frequency_table_verify
,
125 .target_index
= at32_set_target
,
126 .get
= at32_get_speed
,
127 .flags
= CPUFREQ_STICKY
,
130 static int __init
at32_cpufreq_init(void)
132 return cpufreq_register_driver(&at32_driver
);
134 late_initcall(at32_cpufreq_init
);