2 * arch/sh/kernel/cpu/sh4a/clock-sh7785.c
4 * SH7785 support for the clock framework
6 * Copyright (C) 2007 - 2009 Paul Mundt
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/clk.h>
16 #include <linux/cpufreq.h>
17 #include <asm/clock.h>
20 static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18,
25 /* allowable divisor bitmap */
26 unsigned long div_bitmap;
28 /* Supportable frequencies + termination entry */
29 struct cpufreq_frequency_table freq_table[ARRAY_SIZE(div2)+1];
32 #define FRQMR_CLK_DATA(_name, _shift, _div_bitmap) \
33 static struct clk_priv _name##_data = { \
35 .div_bitmap = _div_bitmap, \
39 .frequency = CPUFREQ_TABLE_END, \
43 FRQMR_CLK_DATA(pfc, 0, 0x0f80);
44 FRQMR_CLK_DATA(s3fc, 4, 0x0ff0);
45 FRQMR_CLK_DATA(s2fc, 8, 0x0030);
46 FRQMR_CLK_DATA(mfc, 12, 0x000c);
47 FRQMR_CLK_DATA(bfc, 16, 0x0fe0);
48 FRQMR_CLK_DATA(sfc, 20, 0x000c);
49 FRQMR_CLK_DATA(ufc, 24, 0x000c);
50 FRQMR_CLK_DATA(ifc, 28, 0x000e);
52 static unsigned long frqmr_recalc(struct clk *clk)
54 struct clk_priv *data = clk->priv;
57 idx = (__raw_readl(FRQMR1) >> data->shift) & 0x000f;
60 * XXX: PLL1 multiplier is locked for the default clock mode,
61 * when mode pin detection and configuration support is added,
62 * select the multiplier dynamically.
64 return clk->parent->rate * 36 / div2[idx];
67 static void frqmr_build_rate_table(struct clk *clk)
69 struct clk_priv *data = clk->priv;
72 for (i = entry = 0; i < ARRAY_SIZE(div2); i++) {
73 if ((data->div_bitmap & (1 << i)) == 0)
76 data->freq_table[entry].index = entry;
77 data->freq_table[entry].frequency =
78 clk->parent->rate * 36 / div2[i];
84 pr_warning("clkfwk: failed to build frequency table "
85 "for \"%s\" clk!\n", clk->name);
89 /* Termination entry */
90 data->freq_table[entry].index = entry;
91 data->freq_table[entry].frequency = CPUFREQ_TABLE_END;
94 static long frqmr_round_rate(struct clk *clk, unsigned long rate)
96 struct clk_priv *data = clk->priv;
97 unsigned long rate_error, rate_error_prev = ~0UL;
98 unsigned long rate_best_fit = rate;
99 unsigned long highest, lowest;
102 highest = lowest = 0;
104 for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
105 unsigned long freq = data->freq_table[i].frequency;
107 if (freq == CPUFREQ_ENTRY_INVALID)
115 rate_error = abs(freq - rate);
116 if (rate_error < rate_error_prev) {
117 rate_best_fit = freq;
118 rate_error_prev = rate_error;
126 rate_best_fit = highest;
128 rate_best_fit = lowest;
130 return rate_best_fit;
133 static struct clk_ops frqmr_clk_ops = {
134 .recalc = frqmr_recalc,
135 .build_rate_table = frqmr_build_rate_table,
136 .round_rate = frqmr_round_rate,
140 * Default rate for the root input clock, reset this with clk_set_rate()
141 * from the platform code.
143 static struct clk extal_clk = {
149 static struct clk cpu_clk = {
150 .name = "cpu_clk", /* Ick */
152 .ops = &frqmr_clk_ops,
153 .parent = &extal_clk,
154 .flags = CLK_ENABLE_ON_INIT,
158 static struct clk shyway_clk = {
159 .name = "shyway_clk", /* SHck */
161 .ops = &frqmr_clk_ops,
162 .parent = &extal_clk,
163 .flags = CLK_ENABLE_ON_INIT,
167 static struct clk peripheral_clk = {
168 .name = "peripheral_clk", /* Pck */
170 .ops = &frqmr_clk_ops,
171 .parent = &extal_clk,
172 .flags = CLK_ENABLE_ON_INIT,
176 static struct clk ddr_clk = {
177 .name = "ddr_clk", /* DDRck */
179 .ops = &frqmr_clk_ops,
180 .parent = &extal_clk,
181 .flags = CLK_ENABLE_ON_INIT,
185 static struct clk bus_clk = {
186 .name = "bus_clk", /* Bck */
188 .ops = &frqmr_clk_ops,
189 .parent = &extal_clk,
190 .flags = CLK_ENABLE_ON_INIT,
194 static struct clk ga_clk = {
195 .name = "ga_clk", /* GAck */
197 .ops = &frqmr_clk_ops,
198 .parent = &extal_clk,
202 static struct clk du_clk = {
203 .name = "du_clk", /* DUck */
205 .ops = &frqmr_clk_ops,
206 .parent = &extal_clk,
210 static struct clk umem_clk = {
211 .name = "umem_clk", /* uck */
213 .ops = &frqmr_clk_ops,
214 .parent = &extal_clk,
215 .flags = CLK_ENABLE_ON_INIT,
219 static struct clk *clks[] = {
231 int __init arch_clk_init(void)
235 for (i = 0; i < ARRAY_SIZE(clks); i++)
236 ret |= clk_register(clks[i]);