OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * Moschip MCS814x clock routines |
||
3 | * |
||
4 | * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org> |
||
5 | * |
||
6 | * Licensed under GPLv2 |
||
7 | */ |
||
8 | #include <linux/kernel.h> |
||
9 | #include <linux/init.h> |
||
10 | #include <linux/export.h> |
||
11 | #include <linux/spinlock.h> |
||
12 | #include <linux/err.h> |
||
13 | #include <linux/io.h> |
||
14 | #include <linux/clkdev.h> |
||
15 | #include <linux/clk.h> |
||
16 | |||
17 | #include <mach/mcs814x.h> |
||
18 | |||
19 | #include "common.h" |
||
20 | |||
21 | #define KHZ 1000 |
||
22 | #define MHZ (KHZ * KHZ) |
||
23 | |||
24 | struct clk_ops { |
||
25 | unsigned long (*get_rate)(struct clk *clk); |
||
26 | int (*set_rate)(struct clk *clk, unsigned long rate); |
||
27 | struct clk *(*get_parent)(struct clk *clk); |
||
28 | int (*enable)(struct clk *clk, int enable); |
||
29 | }; |
||
30 | |||
31 | struct clk { |
||
32 | struct clk *parent; /* parent clk */ |
||
33 | unsigned long rate; /* clock rate in Hz */ |
||
34 | unsigned long divider; /* clock divider */ |
||
35 | u32 usecount; /* reference count */ |
||
36 | struct clk_ops *ops; /* clock operation */ |
||
37 | u32 enable_reg; /* clock enable register */ |
||
38 | u32 enable_mask; /* clock enable mask */ |
||
39 | }; |
||
40 | |||
41 | static unsigned long clk_divide_parent(struct clk *clk) |
||
42 | { |
||
43 | if (clk->parent && clk->divider) |
||
44 | return clk_get_rate(clk->parent) / clk->divider; |
||
45 | else |
||
46 | return 0; |
||
47 | } |
||
48 | |||
49 | static int clk_local_onoff_enable(struct clk *clk, int enable) |
||
50 | { |
||
51 | u32 tmp; |
||
52 | |||
53 | /* no enable_reg means the clock is always enabled */ |
||
54 | if (!clk->enable_reg) |
||
55 | return 0; |
||
56 | |||
57 | tmp = readl_relaxed(mcs814x_sysdbg_base + clk->enable_reg); |
||
58 | if (!enable) |
||
59 | tmp &= ~clk->enable_mask; |
||
60 | else |
||
61 | tmp |= clk->enable_mask; |
||
62 | |||
63 | writel_relaxed(tmp, mcs814x_sysdbg_base + clk->enable_reg); |
||
64 | |||
65 | return 0; |
||
66 | } |
||
67 | |||
68 | static struct clk_ops default_clk_ops = { |
||
69 | .get_rate = clk_divide_parent, |
||
70 | .enable = clk_local_onoff_enable, |
||
71 | }; |
||
72 | |||
73 | static DEFINE_SPINLOCK(clocks_lock); |
||
74 | |||
75 | static const unsigned long cpu_freq_table[] = { |
||
76 | 175000, |
||
77 | 300000, |
||
78 | 125000, |
||
79 | 137500, |
||
80 | 212500, |
||
81 | 250000, |
||
82 | 162500, |
||
83 | 187500, |
||
84 | 162500, |
||
85 | 150000, |
||
86 | 225000, |
||
87 | 237500, |
||
88 | 200000, |
||
89 | 262500, |
||
90 | 275000, |
||
91 | 287500 |
||
92 | }; |
||
93 | |||
94 | static struct clk clk_cpu; |
||
95 | |||
96 | /* System clock is fixed at 50Mhz */ |
||
97 | static struct clk clk_sys = { |
||
98 | .rate = 50 * MHZ, |
||
99 | }; |
||
100 | |||
101 | static struct clk clk_sdram; |
||
102 | |||
103 | static struct clk clk_timer0 = { |
||
104 | .parent = &clk_sdram, |
||
105 | .divider = 2, |
||
106 | .ops = &default_clk_ops, |
||
107 | }; |
||
108 | |||
109 | static struct clk clk_timer1_2 = { |
||
110 | .parent = &clk_sys, |
||
111 | }; |
||
112 | |||
113 | /* Watchdog clock is system clock / 128 */ |
||
114 | static struct clk clk_wdt = { |
||
115 | .parent = &clk_sys, |
||
116 | .divider = 128, |
||
117 | .ops = &default_clk_ops, |
||
118 | }; |
||
119 | |||
120 | static struct clk clk_emac = { |
||
121 | .ops = &default_clk_ops, |
||
122 | .enable_reg = SYSDBG_SYSCTL, |
||
123 | .enable_mask = SYSCTL_EMAC, |
||
124 | }; |
||
125 | |||
126 | static struct clk clk_ephy = { |
||
127 | .ops = &default_clk_ops, |
||
128 | .enable_reg = SYSDBG_PLL_CTL, |
||
129 | .enable_mask = ~SYSCTL_EPHY, /* active low */ |
||
130 | }; |
||
131 | |||
132 | static struct clk clk_cipher = { |
||
133 | .ops = &default_clk_ops, |
||
134 | .enable_reg = SYSDBG_SYSCTL, |
||
135 | .enable_mask = SYSCTL_CIPHER, |
||
136 | }; |
||
137 | |||
138 | #define CLK(_dev, _con, _clk) \ |
||
139 | { .dev_id = (_dev), .con_id = (_con), .clk = (_clk) }, |
||
140 | |||
141 | static struct clk_lookup mcs814x_chip_clks[] = { |
||
142 | CLK("cpu", NULL, &clk_cpu) |
||
143 | CLK("sys", NULL, &clk_sys) |
||
144 | CLK("sdram", NULL, &clk_sdram) |
||
145 | /* 32-bits timer0 */ |
||
146 | CLK("timer0", NULL, &clk_timer0) |
||
147 | /* 16-bits timer1 */ |
||
148 | CLK("timer1", NULL, &clk_timer1_2) |
||
149 | /* 64-bits timer2, same as timer 1 */ |
||
150 | CLK("timer2", NULL, &clk_timer1_2) |
||
151 | CLK(NULL, "wdt", &clk_wdt) |
||
152 | CLK(NULL, "emac", &clk_emac) |
||
153 | CLK(NULL, "ephy", &clk_ephy) |
||
154 | CLK(NULL, "cipher", &clk_cipher) |
||
155 | }; |
||
156 | |||
157 | static void local_clk_disable(struct clk *clk) |
||
158 | { |
||
159 | WARN_ON(!clk->usecount); |
||
160 | |||
161 | if (clk->usecount > 0) { |
||
162 | clk->usecount--; |
||
163 | |||
164 | if ((clk->usecount == 0) && (clk->ops->enable)) |
||
165 | clk->ops->enable(clk, 0); |
||
166 | |||
167 | if (clk->parent) |
||
168 | local_clk_disable(clk->parent); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | static int local_clk_enable(struct clk *clk) |
||
173 | { |
||
174 | int ret = 0; |
||
175 | |||
176 | if (clk->parent) |
||
177 | ret = local_clk_enable(clk->parent); |
||
178 | |||
179 | if (ret) |
||
180 | return ret; |
||
181 | |||
182 | if ((clk->usecount == 0) && (clk->ops->enable)) |
||
183 | ret = clk->ops->enable(clk, 1); |
||
184 | |||
185 | if (!ret) |
||
186 | clk->usecount++; |
||
187 | else if (clk->parent && clk->parent->ops->enable) |
||
188 | local_clk_disable(clk->parent); |
||
189 | |||
190 | return ret; |
||
191 | } |
||
192 | |||
193 | int clk_enable(struct clk *clk) |
||
194 | { |
||
195 | int ret; |
||
196 | unsigned long flags; |
||
197 | |||
198 | spin_lock_irqsave(&clocks_lock, flags); |
||
199 | ret = local_clk_enable(clk); |
||
200 | spin_unlock_irqrestore(&clocks_lock, flags); |
||
201 | |||
202 | return ret; |
||
203 | } |
||
204 | EXPORT_SYMBOL(clk_enable); |
||
205 | |||
206 | void clk_disable(struct clk *clk) |
||
207 | { |
||
208 | unsigned long flags; |
||
209 | |||
210 | spin_lock_irqsave(&clocks_lock, flags); |
||
211 | local_clk_disable(clk); |
||
212 | spin_unlock_irqrestore(&clocks_lock, flags); |
||
213 | } |
||
214 | EXPORT_SYMBOL(clk_disable); |
||
215 | |||
216 | unsigned long clk_get_rate(struct clk *clk) |
||
217 | { |
||
218 | if (unlikely(IS_ERR_OR_NULL(clk))) |
||
219 | return 0; |
||
220 | |||
221 | if (clk->rate) |
||
222 | return clk->rate; |
||
223 | |||
224 | if (clk->ops && clk->ops->get_rate) |
||
225 | return clk->ops->get_rate(clk); |
||
226 | |||
227 | return clk_get_rate(clk->parent); |
||
228 | } |
||
229 | EXPORT_SYMBOL(clk_get_rate); |
||
230 | |||
231 | struct clk *clk_get_parent(struct clk *clk) |
||
232 | { |
||
233 | unsigned long flags; |
||
234 | |||
235 | if (unlikely(IS_ERR_OR_NULL(clk))) |
||
236 | return NULL; |
||
237 | |||
238 | if (!clk->ops || !clk->ops->get_parent) |
||
239 | return clk->parent; |
||
240 | |||
241 | spin_lock_irqsave(&clocks_lock, flags); |
||
242 | clk->parent = clk->ops->get_parent(clk); |
||
243 | spin_unlock_irqrestore(&clocks_lock, flags); |
||
244 | |||
245 | return clk->parent; |
||
246 | } |
||
247 | EXPORT_SYMBOL(clk_get_parent); |
||
248 | |||
249 | void __init mcs814x_clk_init(void) |
||
250 | { |
||
251 | u32 bs1; |
||
252 | u8 cpu_freq; |
||
253 | |||
254 | clkdev_add_table(mcs814x_chip_clks, ARRAY_SIZE(mcs814x_chip_clks)); |
||
255 | |||
256 | /* read the bootstrap registers to know the exact clocking scheme */ |
||
257 | bs1 = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS1); |
||
258 | cpu_freq = (bs1 >> CPU_FREQ_SHIFT) & CPU_FREQ_MASK; |
||
259 | |||
260 | pr_info("CPU frequency: %lu (kHz)\n", cpu_freq_table[cpu_freq]); |
||
261 | clk_cpu.rate = cpu_freq * KHZ; |
||
262 | |||
263 | /* read SDRAM frequency */ |
||
264 | if (bs1 & SDRAM_FREQ_BIT) |
||
265 | clk_sdram.rate = 100 * MHZ; |
||
266 | else |
||
267 | clk_sdram.rate = 133 * MHZ; |
||
268 | |||
269 | pr_info("SDRAM frequency: %lu (MHz)\n", clk_sdram.rate / MHZ); |
||
270 | } |
||
271 |