diff options
author | viresh kumar <viresh.kumar@st.com> | 2011-02-16 01:40:39 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-03-09 04:49:45 -0500 |
commit | af89fd812b00a52c54a3b9b2290fae4d31c7be9a (patch) | |
tree | 3892de4165b23e98424f672c23b7a6d456ad235d /arch/arm | |
parent | cf285434ac0880f94bf4afdd90b06a4655f56570 (diff) |
ARM: 6703/1: SPEAr: update clk API support
- Add support for divisor per parent clock
- Add ENABLED_ON_INIT feature in clk
- Add clk_set_rate(), round_rate_index & clk_round_rate()
- Simplify clk_recalc functions
- Add/update clock definitions
Reviewed-by: Stanley Miao <stanley.miao@windriver.com>
Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
Signed-off-by: shiraz hashim <shiraz.hashim@st.com>
Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-spear3xx/clock.c | 431 | ||||
-rw-r--r-- | arch/arm/mach-spear3xx/include/mach/misc_regs.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-spear6xx/clock.c | 331 | ||||
-rw-r--r-- | arch/arm/mach-spear6xx/include/mach/misc_regs.h | 5 | ||||
-rw-r--r-- | arch/arm/plat-spear/clock.c | 705 | ||||
-rw-r--r-- | arch/arm/plat-spear/include/plat/clock.h | 94 |
6 files changed, 1259 insertions, 312 deletions
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c index 7ea8749ddf28..8ae4ad0326a9 100644 --- a/arch/arm/mach-spear3xx/clock.c +++ b/arch/arm/mach-spear3xx/clock.c | |||
@@ -60,12 +60,22 @@ static struct pll_clk_config pll1_config = { | |||
60 | .masks = &pll1_masks, | 60 | .masks = &pll1_masks, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* pll rate configuration table, in ascending order of rates */ | ||
64 | struct pll_rate_tbl pll_rtbl[] = { | ||
65 | {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */ | ||
66 | {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */ | ||
67 | }; | ||
68 | |||
63 | /* PLL1 clock */ | 69 | /* PLL1 clock */ |
64 | static struct clk pll1_clk = { | 70 | static struct clk pll1_clk = { |
71 | .flags = ENABLED_ON_INIT, | ||
65 | .pclk = &osc_24m_clk, | 72 | .pclk = &osc_24m_clk, |
66 | .en_reg = PLL1_CTR, | 73 | .en_reg = PLL1_CTR, |
67 | .en_reg_bit = PLL_ENABLE, | 74 | .en_reg_bit = PLL_ENABLE, |
75 | .calc_rate = &pll_calc_rate, | ||
68 | .recalc = &pll_clk_recalc, | 76 | .recalc = &pll_clk_recalc, |
77 | .set_rate = &pll_clk_set_rate, | ||
78 | .rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1}, | ||
69 | .private_data = &pll1_config, | 79 | .private_data = &pll1_config, |
70 | }; | 80 | }; |
71 | 81 | ||
@@ -103,11 +113,22 @@ static struct bus_clk_config ahb_config = { | |||
103 | .masks = &ahb_masks, | 113 | .masks = &ahb_masks, |
104 | }; | 114 | }; |
105 | 115 | ||
116 | /* ahb rate configuration table, in ascending order of rates */ | ||
117 | struct bus_rate_tbl bus_rtbl[] = { | ||
118 | {.div = 3}, /* == parent divided by 4 */ | ||
119 | {.div = 2}, /* == parent divided by 3 */ | ||
120 | {.div = 1}, /* == parent divided by 2 */ | ||
121 | {.div = 0}, /* == parent divided by 1 */ | ||
122 | }; | ||
123 | |||
106 | /* ahb clock */ | 124 | /* ahb clock */ |
107 | static struct clk ahb_clk = { | 125 | static struct clk ahb_clk = { |
108 | .flags = ALWAYS_ENABLED, | 126 | .flags = ALWAYS_ENABLED, |
109 | .pclk = &pll1_clk, | 127 | .pclk = &pll1_clk, |
128 | .calc_rate = &bus_calc_rate, | ||
110 | .recalc = &bus_clk_recalc, | 129 | .recalc = &bus_clk_recalc, |
130 | .set_rate = &bus_clk_set_rate, | ||
131 | .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2}, | ||
111 | .private_data = &ahb_config, | 132 | .private_data = &ahb_config, |
112 | }; | 133 | }; |
113 | 134 | ||
@@ -123,22 +144,40 @@ static struct aux_clk_masks aux_masks = { | |||
123 | .yscale_sel_shift = AUX_YSCALE_SHIFT, | 144 | .yscale_sel_shift = AUX_YSCALE_SHIFT, |
124 | }; | 145 | }; |
125 | 146 | ||
126 | /* uart configurations */ | 147 | /* uart synth configurations */ |
127 | static struct aux_clk_config uart_config = { | 148 | static struct aux_clk_config uart_synth_config = { |
128 | .synth_reg = UART_CLK_SYNT, | 149 | .synth_reg = UART_CLK_SYNT, |
129 | .masks = &aux_masks, | 150 | .masks = &aux_masks, |
130 | }; | 151 | }; |
131 | 152 | ||
153 | /* aux rate configuration table, in ascending order of rates */ | ||
154 | struct aux_rate_tbl aux_rtbl[] = { | ||
155 | /* For PLL1 = 332 MHz */ | ||
156 | {.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */ | ||
157 | {.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */ | ||
158 | {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */ | ||
159 | }; | ||
160 | |||
161 | /* uart synth clock */ | ||
162 | static struct clk uart_synth_clk = { | ||
163 | .en_reg = UART_CLK_SYNT, | ||
164 | .en_reg_bit = AUX_SYNT_ENB, | ||
165 | .pclk = &pll1_clk, | ||
166 | .calc_rate = &aux_calc_rate, | ||
167 | .recalc = &aux_clk_recalc, | ||
168 | .set_rate = &aux_clk_set_rate, | ||
169 | .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1}, | ||
170 | .private_data = &uart_synth_config, | ||
171 | }; | ||
172 | |||
132 | /* uart parents */ | 173 | /* uart parents */ |
133 | static struct pclk_info uart_pclk_info[] = { | 174 | static struct pclk_info uart_pclk_info[] = { |
134 | { | 175 | { |
135 | .pclk = &pll1_clk, | 176 | .pclk = &uart_synth_clk, |
136 | .pclk_mask = AUX_CLK_PLL1_MASK, | 177 | .pclk_val = AUX_CLK_PLL1_VAL, |
137 | .scalable = 1, | ||
138 | }, { | 178 | }, { |
139 | .pclk = &pll3_48m_clk, | 179 | .pclk = &pll3_48m_clk, |
140 | .pclk_mask = AUX_CLK_PLL3_MASK, | 180 | .pclk_val = AUX_CLK_PLL3_VAL, |
141 | .scalable = 0, | ||
142 | }, | 181 | }, |
143 | }; | 182 | }; |
144 | 183 | ||
@@ -156,26 +195,35 @@ static struct clk uart_clk = { | |||
156 | .en_reg_bit = UART_CLK_ENB, | 195 | .en_reg_bit = UART_CLK_ENB, |
157 | .pclk_sel = &uart_pclk_sel, | 196 | .pclk_sel = &uart_pclk_sel, |
158 | .pclk_sel_shift = UART_CLK_SHIFT, | 197 | .pclk_sel_shift = UART_CLK_SHIFT, |
159 | .recalc = &aux_clk_recalc, | 198 | .recalc = &follow_parent, |
160 | .private_data = &uart_config, | ||
161 | }; | 199 | }; |
162 | 200 | ||
163 | /* firda configurations */ | 201 | /* firda configurations */ |
164 | static struct aux_clk_config firda_config = { | 202 | static struct aux_clk_config firda_synth_config = { |
165 | .synth_reg = FIRDA_CLK_SYNT, | 203 | .synth_reg = FIRDA_CLK_SYNT, |
166 | .masks = &aux_masks, | 204 | .masks = &aux_masks, |
167 | }; | 205 | }; |
168 | 206 | ||
207 | /* firda synth clock */ | ||
208 | static struct clk firda_synth_clk = { | ||
209 | .en_reg = FIRDA_CLK_SYNT, | ||
210 | .en_reg_bit = AUX_SYNT_ENB, | ||
211 | .pclk = &pll1_clk, | ||
212 | .calc_rate = &aux_calc_rate, | ||
213 | .recalc = &aux_clk_recalc, | ||
214 | .set_rate = &aux_clk_set_rate, | ||
215 | .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1}, | ||
216 | .private_data = &firda_synth_config, | ||
217 | }; | ||
218 | |||
169 | /* firda parents */ | 219 | /* firda parents */ |
170 | static struct pclk_info firda_pclk_info[] = { | 220 | static struct pclk_info firda_pclk_info[] = { |
171 | { | 221 | { |
172 | .pclk = &pll1_clk, | 222 | .pclk = &firda_synth_clk, |
173 | .pclk_mask = AUX_CLK_PLL1_MASK, | 223 | .pclk_val = AUX_CLK_PLL1_VAL, |
174 | .scalable = 1, | ||
175 | }, { | 224 | }, { |
176 | .pclk = &pll3_48m_clk, | 225 | .pclk = &pll3_48m_clk, |
177 | .pclk_mask = AUX_CLK_PLL3_MASK, | 226 | .pclk_val = AUX_CLK_PLL3_VAL, |
178 | .scalable = 0, | ||
179 | }, | 227 | }, |
180 | }; | 228 | }; |
181 | 229 | ||
@@ -193,84 +241,155 @@ static struct clk firda_clk = { | |||
193 | .en_reg_bit = FIRDA_CLK_ENB, | 241 | .en_reg_bit = FIRDA_CLK_ENB, |
194 | .pclk_sel = &firda_pclk_sel, | 242 | .pclk_sel = &firda_pclk_sel, |
195 | .pclk_sel_shift = FIRDA_CLK_SHIFT, | 243 | .pclk_sel_shift = FIRDA_CLK_SHIFT, |
196 | .recalc = &aux_clk_recalc, | 244 | .recalc = &follow_parent, |
197 | .private_data = &firda_config, | 245 | }; |
246 | |||
247 | /* gpt synthesizer masks */ | ||
248 | static struct gpt_clk_masks gpt_masks = { | ||
249 | .mscale_sel_mask = GPT_MSCALE_MASK, | ||
250 | .mscale_sel_shift = GPT_MSCALE_SHIFT, | ||
251 | .nscale_sel_mask = GPT_NSCALE_MASK, | ||
252 | .nscale_sel_shift = GPT_NSCALE_SHIFT, | ||
253 | }; | ||
254 | |||
255 | /* gpt rate configuration table, in ascending order of rates */ | ||
256 | struct gpt_rate_tbl gpt_rtbl[] = { | ||
257 | /* For pll1 = 332 MHz */ | ||
258 | {.mscale = 4, .nscale = 0}, /* 41.5 MHz */ | ||
259 | {.mscale = 2, .nscale = 0}, /* 55.3 MHz */ | ||
260 | {.mscale = 1, .nscale = 0}, /* 83 MHz */ | ||
261 | }; | ||
262 | |||
263 | /* gpt0 synth clk config*/ | ||
264 | static struct gpt_clk_config gpt0_synth_config = { | ||
265 | .synth_reg = PRSC1_CLK_CFG, | ||
266 | .masks = &gpt_masks, | ||
267 | }; | ||
268 | |||
269 | /* gpt synth clock */ | ||
270 | static struct clk gpt0_synth_clk = { | ||
271 | .flags = ALWAYS_ENABLED, | ||
272 | .pclk = &pll1_clk, | ||
273 | .calc_rate = &gpt_calc_rate, | ||
274 | .recalc = &gpt_clk_recalc, | ||
275 | .set_rate = &gpt_clk_set_rate, | ||
276 | .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2}, | ||
277 | .private_data = &gpt0_synth_config, | ||
198 | }; | 278 | }; |
199 | 279 | ||
200 | /* gpt parents */ | 280 | /* gpt parents */ |
201 | static struct pclk_info gpt_pclk_info[] = { | 281 | static struct pclk_info gpt0_pclk_info[] = { |
202 | { | 282 | { |
203 | .pclk = &pll1_clk, | 283 | .pclk = &gpt0_synth_clk, |
204 | .pclk_mask = AUX_CLK_PLL1_MASK, | 284 | .pclk_val = AUX_CLK_PLL1_VAL, |
205 | .scalable = 1, | ||
206 | }, { | 285 | }, { |
207 | .pclk = &pll3_48m_clk, | 286 | .pclk = &pll3_48m_clk, |
208 | .pclk_mask = AUX_CLK_PLL3_MASK, | 287 | .pclk_val = AUX_CLK_PLL3_VAL, |
209 | .scalable = 0, | ||
210 | }, | 288 | }, |
211 | }; | 289 | }; |
212 | 290 | ||
213 | /* gpt parent select structure */ | 291 | /* gpt parent select structure */ |
214 | static struct pclk_sel gpt_pclk_sel = { | 292 | static struct pclk_sel gpt0_pclk_sel = { |
215 | .pclk_info = gpt_pclk_info, | 293 | .pclk_info = gpt0_pclk_info, |
216 | .pclk_count = ARRAY_SIZE(gpt_pclk_info), | 294 | .pclk_count = ARRAY_SIZE(gpt0_pclk_info), |
217 | .pclk_sel_reg = PERIP_CLK_CFG, | 295 | .pclk_sel_reg = PERIP_CLK_CFG, |
218 | .pclk_sel_mask = GPT_CLK_MASK, | 296 | .pclk_sel_mask = GPT_CLK_MASK, |
219 | }; | 297 | }; |
220 | 298 | ||
221 | /* gpt synthesizer masks */ | 299 | /* gpt0 timer clock */ |
222 | static struct gpt_clk_masks gpt_masks = { | 300 | static struct clk gpt0_clk = { |
223 | .mscale_sel_mask = GPT_MSCALE_MASK, | 301 | .flags = ALWAYS_ENABLED, |
224 | .mscale_sel_shift = GPT_MSCALE_SHIFT, | 302 | .pclk_sel = &gpt0_pclk_sel, |
225 | .nscale_sel_mask = GPT_NSCALE_MASK, | 303 | .pclk_sel_shift = GPT0_CLK_SHIFT, |
226 | .nscale_sel_shift = GPT_NSCALE_SHIFT, | 304 | .recalc = &follow_parent, |
227 | }; | 305 | }; |
228 | 306 | ||
229 | /* gpt0 configurations */ | 307 | /* gpt1 synth clk configurations */ |
230 | static struct gpt_clk_config gpt0_config = { | 308 | static struct gpt_clk_config gpt1_synth_config = { |
231 | .synth_reg = PRSC1_CLK_CFG, | 309 | .synth_reg = PRSC2_CLK_CFG, |
232 | .masks = &gpt_masks, | 310 | .masks = &gpt_masks, |
233 | }; | 311 | }; |
234 | 312 | ||
235 | /* gpt0 timer clock */ | 313 | /* gpt1 synth clock */ |
236 | static struct clk gpt0_clk = { | 314 | static struct clk gpt1_synth_clk = { |
237 | .flags = ALWAYS_ENABLED, | 315 | .flags = ALWAYS_ENABLED, |
238 | .pclk_sel = &gpt_pclk_sel, | 316 | .pclk = &pll1_clk, |
239 | .pclk_sel_shift = GPT0_CLK_SHIFT, | 317 | .calc_rate = &gpt_calc_rate, |
240 | .recalc = &gpt_clk_recalc, | 318 | .recalc = &gpt_clk_recalc, |
241 | .private_data = &gpt0_config, | 319 | .set_rate = &gpt_clk_set_rate, |
320 | .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2}, | ||
321 | .private_data = &gpt1_synth_config, | ||
242 | }; | 322 | }; |
243 | 323 | ||
244 | /* gpt1 configurations */ | 324 | static struct pclk_info gpt1_pclk_info[] = { |
245 | static struct gpt_clk_config gpt1_config = { | 325 | { |
246 | .synth_reg = PRSC2_CLK_CFG, | 326 | .pclk = &gpt1_synth_clk, |
247 | .masks = &gpt_masks, | 327 | .pclk_val = AUX_CLK_PLL1_VAL, |
328 | }, { | ||
329 | .pclk = &pll3_48m_clk, | ||
330 | .pclk_val = AUX_CLK_PLL3_VAL, | ||
331 | }, | ||
332 | }; | ||
333 | |||
334 | /* gpt parent select structure */ | ||
335 | static struct pclk_sel gpt1_pclk_sel = { | ||
336 | .pclk_info = gpt1_pclk_info, | ||
337 | .pclk_count = ARRAY_SIZE(gpt1_pclk_info), | ||
338 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
339 | .pclk_sel_mask = GPT_CLK_MASK, | ||
248 | }; | 340 | }; |
249 | 341 | ||
250 | /* gpt1 timer clock */ | 342 | /* gpt1 timer clock */ |
251 | static struct clk gpt1_clk = { | 343 | static struct clk gpt1_clk = { |
252 | .en_reg = PERIP1_CLK_ENB, | 344 | .en_reg = PERIP1_CLK_ENB, |
253 | .en_reg_bit = GPT1_CLK_ENB, | 345 | .en_reg_bit = GPT1_CLK_ENB, |
254 | .pclk_sel = &gpt_pclk_sel, | 346 | .pclk_sel = &gpt1_pclk_sel, |
255 | .pclk_sel_shift = GPT1_CLK_SHIFT, | 347 | .pclk_sel_shift = GPT1_CLK_SHIFT, |
256 | .recalc = &gpt_clk_recalc, | 348 | .recalc = &follow_parent, |
257 | .private_data = &gpt1_config, | ||
258 | }; | 349 | }; |
259 | 350 | ||
260 | /* gpt2 configurations */ | 351 | /* gpt2 synth clk configurations */ |
261 | static struct gpt_clk_config gpt2_config = { | 352 | static struct gpt_clk_config gpt2_synth_config = { |
262 | .synth_reg = PRSC3_CLK_CFG, | 353 | .synth_reg = PRSC3_CLK_CFG, |
263 | .masks = &gpt_masks, | 354 | .masks = &gpt_masks, |
264 | }; | 355 | }; |
265 | 356 | ||
357 | /* gpt1 synth clock */ | ||
358 | static struct clk gpt2_synth_clk = { | ||
359 | .flags = ALWAYS_ENABLED, | ||
360 | .pclk = &pll1_clk, | ||
361 | .calc_rate = &gpt_calc_rate, | ||
362 | .recalc = &gpt_clk_recalc, | ||
363 | .set_rate = &gpt_clk_set_rate, | ||
364 | .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2}, | ||
365 | .private_data = &gpt2_synth_config, | ||
366 | }; | ||
367 | |||
368 | static struct pclk_info gpt2_pclk_info[] = { | ||
369 | { | ||
370 | .pclk = &gpt2_synth_clk, | ||
371 | .pclk_val = AUX_CLK_PLL1_VAL, | ||
372 | }, { | ||
373 | .pclk = &pll3_48m_clk, | ||
374 | .pclk_val = AUX_CLK_PLL3_VAL, | ||
375 | }, | ||
376 | }; | ||
377 | |||
378 | /* gpt parent select structure */ | ||
379 | static struct pclk_sel gpt2_pclk_sel = { | ||
380 | .pclk_info = gpt2_pclk_info, | ||
381 | .pclk_count = ARRAY_SIZE(gpt2_pclk_info), | ||
382 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
383 | .pclk_sel_mask = GPT_CLK_MASK, | ||
384 | }; | ||
385 | |||
266 | /* gpt2 timer clock */ | 386 | /* gpt2 timer clock */ |
267 | static struct clk gpt2_clk = { | 387 | static struct clk gpt2_clk = { |
268 | .en_reg = PERIP1_CLK_ENB, | 388 | .en_reg = PERIP1_CLK_ENB, |
269 | .en_reg_bit = GPT2_CLK_ENB, | 389 | .en_reg_bit = GPT2_CLK_ENB, |
270 | .pclk_sel = &gpt_pclk_sel, | 390 | .pclk_sel = &gpt2_pclk_sel, |
271 | .pclk_sel_shift = GPT2_CLK_SHIFT, | 391 | .pclk_sel_shift = GPT2_CLK_SHIFT, |
272 | .recalc = &gpt_clk_recalc, | 392 | .recalc = &follow_parent, |
273 | .private_data = &gpt2_config, | ||
274 | }; | 393 | }; |
275 | 394 | ||
276 | /* clock derived from pll3 clk */ | 395 | /* clock derived from pll3 clk */ |
@@ -290,13 +409,6 @@ static struct clk usbd_clk = { | |||
290 | .recalc = &follow_parent, | 409 | .recalc = &follow_parent, |
291 | }; | 410 | }; |
292 | 411 | ||
293 | /* clcd clock */ | ||
294 | static struct clk clcd_clk = { | ||
295 | .flags = ALWAYS_ENABLED, | ||
296 | .pclk = &pll3_48m_clk, | ||
297 | .recalc = &follow_parent, | ||
298 | }; | ||
299 | |||
300 | /* clock derived from ahb clk */ | 412 | /* clock derived from ahb clk */ |
301 | /* apb masks structure */ | 413 | /* apb masks structure */ |
302 | static struct bus_clk_masks apb_masks = { | 414 | static struct bus_clk_masks apb_masks = { |
@@ -314,7 +426,10 @@ static struct bus_clk_config apb_config = { | |||
314 | static struct clk apb_clk = { | 426 | static struct clk apb_clk = { |
315 | .flags = ALWAYS_ENABLED, | 427 | .flags = ALWAYS_ENABLED, |
316 | .pclk = &ahb_clk, | 428 | .pclk = &ahb_clk, |
429 | .calc_rate = &bus_calc_rate, | ||
317 | .recalc = &bus_clk_recalc, | 430 | .recalc = &bus_clk_recalc, |
431 | .set_rate = &bus_clk_set_rate, | ||
432 | .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2}, | ||
318 | .private_data = &apb_config, | 433 | .private_data = &apb_config, |
319 | }; | 434 | }; |
320 | 435 | ||
@@ -375,8 +490,17 @@ static struct clk adc_clk = { | |||
375 | .recalc = &follow_parent, | 490 | .recalc = &follow_parent, |
376 | }; | 491 | }; |
377 | 492 | ||
493 | #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) | ||
494 | /* emi clock */ | ||
495 | static struct clk emi_clk = { | ||
496 | .flags = ALWAYS_ENABLED, | ||
497 | .pclk = &ahb_clk, | ||
498 | .recalc = &follow_parent, | ||
499 | }; | ||
500 | #endif | ||
501 | |||
378 | /* ssp clock */ | 502 | /* ssp clock */ |
379 | static struct clk ssp_clk = { | 503 | static struct clk ssp0_clk = { |
380 | .pclk = &apb_clk, | 504 | .pclk = &apb_clk, |
381 | .en_reg = PERIP1_CLK_ENB, | 505 | .en_reg = PERIP1_CLK_ENB, |
382 | .en_reg_bit = SSP_CLK_ENB, | 506 | .en_reg_bit = SSP_CLK_ENB, |
@@ -393,6 +517,137 @@ static struct clk gpio_clk = { | |||
393 | 517 | ||
394 | static struct clk dummy_apb_pclk; | 518 | static struct clk dummy_apb_pclk; |
395 | 519 | ||
520 | #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \ | ||
521 | defined(CONFIG_MACH_SPEAR320) | ||
522 | /* fsmc clock */ | ||
523 | static struct clk fsmc_clk = { | ||
524 | .flags = ALWAYS_ENABLED, | ||
525 | .pclk = &ahb_clk, | ||
526 | .recalc = &follow_parent, | ||
527 | }; | ||
528 | #endif | ||
529 | |||
530 | /* common clocks to spear310 and spear320 */ | ||
531 | #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) | ||
532 | /* uart1 clock */ | ||
533 | static struct clk uart1_clk = { | ||
534 | .flags = ALWAYS_ENABLED, | ||
535 | .pclk = &apb_clk, | ||
536 | .recalc = &follow_parent, | ||
537 | }; | ||
538 | |||
539 | /* uart2 clock */ | ||
540 | static struct clk uart2_clk = { | ||
541 | .flags = ALWAYS_ENABLED, | ||
542 | .pclk = &apb_clk, | ||
543 | .recalc = &follow_parent, | ||
544 | }; | ||
545 | #endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */ | ||
546 | |||
547 | /* common clocks to spear300 and spear320 */ | ||
548 | #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320) | ||
549 | /* clcd clock */ | ||
550 | static struct clk clcd_clk = { | ||
551 | .flags = ALWAYS_ENABLED, | ||
552 | .pclk = &pll3_48m_clk, | ||
553 | .recalc = &follow_parent, | ||
554 | }; | ||
555 | |||
556 | /* sdhci clock */ | ||
557 | static struct clk sdhci_clk = { | ||
558 | .flags = ALWAYS_ENABLED, | ||
559 | .pclk = &ahb_clk, | ||
560 | .recalc = &follow_parent, | ||
561 | }; | ||
562 | #endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */ | ||
563 | |||
564 | /* spear300 machine specific clock structures */ | ||
565 | #ifdef CONFIG_MACH_SPEAR300 | ||
566 | /* gpio1 clock */ | ||
567 | static struct clk gpio1_clk = { | ||
568 | .flags = ALWAYS_ENABLED, | ||
569 | .pclk = &apb_clk, | ||
570 | .recalc = &follow_parent, | ||
571 | }; | ||
572 | |||
573 | /* keyboard clock */ | ||
574 | static struct clk kbd_clk = { | ||
575 | .flags = ALWAYS_ENABLED, | ||
576 | .pclk = &apb_clk, | ||
577 | .recalc = &follow_parent, | ||
578 | }; | ||
579 | |||
580 | #endif | ||
581 | |||
582 | /* spear310 machine specific clock structures */ | ||
583 | #ifdef CONFIG_MACH_SPEAR310 | ||
584 | /* uart3 clock */ | ||
585 | static struct clk uart3_clk = { | ||
586 | .flags = ALWAYS_ENABLED, | ||
587 | .pclk = &apb_clk, | ||
588 | .recalc = &follow_parent, | ||
589 | }; | ||
590 | |||
591 | /* uart4 clock */ | ||
592 | static struct clk uart4_clk = { | ||
593 | .flags = ALWAYS_ENABLED, | ||
594 | .pclk = &apb_clk, | ||
595 | .recalc = &follow_parent, | ||
596 | }; | ||
597 | |||
598 | /* uart5 clock */ | ||
599 | static struct clk uart5_clk = { | ||
600 | .flags = ALWAYS_ENABLED, | ||
601 | .pclk = &apb_clk, | ||
602 | .recalc = &follow_parent, | ||
603 | }; | ||
604 | #endif | ||
605 | |||
606 | /* spear320 machine specific clock structures */ | ||
607 | #ifdef CONFIG_MACH_SPEAR320 | ||
608 | /* can0 clock */ | ||
609 | static struct clk can0_clk = { | ||
610 | .flags = ALWAYS_ENABLED, | ||
611 | .pclk = &apb_clk, | ||
612 | .recalc = &follow_parent, | ||
613 | }; | ||
614 | |||
615 | /* can1 clock */ | ||
616 | static struct clk can1_clk = { | ||
617 | .flags = ALWAYS_ENABLED, | ||
618 | .pclk = &apb_clk, | ||
619 | .recalc = &follow_parent, | ||
620 | }; | ||
621 | |||
622 | /* i2c1 clock */ | ||
623 | static struct clk i2c1_clk = { | ||
624 | .flags = ALWAYS_ENABLED, | ||
625 | .pclk = &ahb_clk, | ||
626 | .recalc = &follow_parent, | ||
627 | }; | ||
628 | |||
629 | /* ssp1 clock */ | ||
630 | static struct clk ssp1_clk = { | ||
631 | .flags = ALWAYS_ENABLED, | ||
632 | .pclk = &apb_clk, | ||
633 | .recalc = &follow_parent, | ||
634 | }; | ||
635 | |||
636 | /* ssp2 clock */ | ||
637 | static struct clk ssp2_clk = { | ||
638 | .flags = ALWAYS_ENABLED, | ||
639 | .pclk = &apb_clk, | ||
640 | .recalc = &follow_parent, | ||
641 | }; | ||
642 | |||
643 | /* pwm clock */ | ||
644 | static struct clk pwm_clk = { | ||
645 | .flags = ALWAYS_ENABLED, | ||
646 | .pclk = &apb_clk, | ||
647 | .recalc = &follow_parent, | ||
648 | }; | ||
649 | #endif | ||
650 | |||
396 | /* array of all spear 3xx clock lookups */ | 651 | /* array of all spear 3xx clock lookups */ |
397 | static struct clk_lookup spear_clk_lookups[] = { | 652 | static struct clk_lookup spear_clk_lookups[] = { |
398 | { .con_id = "apb_pclk", .clk = &dummy_apb_pclk}, | 653 | { .con_id = "apb_pclk", .clk = &dummy_apb_pclk}, |
@@ -400,7 +655,7 @@ static struct clk_lookup spear_clk_lookups[] = { | |||
400 | { .con_id = "osc_32k_clk", .clk = &osc_32k_clk}, | 655 | { .con_id = "osc_32k_clk", .clk = &osc_32k_clk}, |
401 | { .con_id = "osc_24m_clk", .clk = &osc_24m_clk}, | 656 | { .con_id = "osc_24m_clk", .clk = &osc_24m_clk}, |
402 | /* clock derived from 32 KHz osc clk */ | 657 | /* clock derived from 32 KHz osc clk */ |
403 | { .dev_id = "rtc", .clk = &rtc_clk}, | 658 | { .dev_id = "rtc-spear", .clk = &rtc_clk}, |
404 | /* clock derived from 24 MHz osc clk */ | 659 | /* clock derived from 24 MHz osc clk */ |
405 | { .con_id = "pll1_clk", .clk = &pll1_clk}, | 660 | { .con_id = "pll1_clk", .clk = &pll1_clk}, |
406 | { .con_id = "pll3_48m_clk", .clk = &pll3_48m_clk}, | 661 | { .con_id = "pll3_48m_clk", .clk = &pll3_48m_clk}, |
@@ -408,18 +663,22 @@ static struct clk_lookup spear_clk_lookups[] = { | |||
408 | /* clock derived from pll1 clk */ | 663 | /* clock derived from pll1 clk */ |
409 | { .con_id = "cpu_clk", .clk = &cpu_clk}, | 664 | { .con_id = "cpu_clk", .clk = &cpu_clk}, |
410 | { .con_id = "ahb_clk", .clk = &ahb_clk}, | 665 | { .con_id = "ahb_clk", .clk = &ahb_clk}, |
666 | { .con_id = "uart_synth_clk", .clk = &uart_synth_clk}, | ||
667 | { .con_id = "firda_synth_clk", .clk = &firda_synth_clk}, | ||
668 | { .con_id = "gpt0_synth_clk", .clk = &gpt0_synth_clk}, | ||
669 | { .con_id = "gpt1_synth_clk", .clk = &gpt1_synth_clk}, | ||
670 | { .con_id = "gpt2_synth_clk", .clk = &gpt2_synth_clk}, | ||
411 | { .dev_id = "uart", .clk = &uart_clk}, | 671 | { .dev_id = "uart", .clk = &uart_clk}, |
412 | { .dev_id = "firda", .clk = &firda_clk}, | 672 | { .dev_id = "firda", .clk = &firda_clk}, |
413 | { .dev_id = "gpt0", .clk = &gpt0_clk}, | 673 | { .dev_id = "gpt0", .clk = &gpt0_clk}, |
414 | { .dev_id = "gpt1", .clk = &gpt1_clk}, | 674 | { .dev_id = "gpt1", .clk = &gpt1_clk}, |
415 | { .dev_id = "gpt2", .clk = &gpt2_clk}, | 675 | { .dev_id = "gpt2", .clk = &gpt2_clk}, |
416 | /* clock derived from pll3 clk */ | 676 | /* clock derived from pll3 clk */ |
417 | { .dev_id = "usbh", .clk = &usbh_clk}, | 677 | { .con_id = "usbh_clk", .clk = &usbh_clk}, |
418 | { .dev_id = "usbd", .clk = &usbd_clk}, | 678 | { .dev_id = "usbd", .clk = &usbd_clk}, |
419 | { .dev_id = "clcd", .clk = &clcd_clk}, | ||
420 | /* clock derived from ahb clk */ | 679 | /* clock derived from ahb clk */ |
421 | { .con_id = "apb_clk", .clk = &apb_clk}, | 680 | { .con_id = "apb_clk", .clk = &apb_clk}, |
422 | { .dev_id = "i2c", .clk = &i2c_clk}, | 681 | { .dev_id = "i2c_designware.0", .clk = &i2c_clk}, |
423 | { .dev_id = "dma", .clk = &dma_clk}, | 682 | { .dev_id = "dma", .clk = &dma_clk}, |
424 | { .dev_id = "jpeg", .clk = &jpeg_clk}, | 683 | { .dev_id = "jpeg", .clk = &jpeg_clk}, |
425 | { .dev_id = "gmac", .clk = &gmac_clk}, | 684 | { .dev_id = "gmac", .clk = &gmac_clk}, |
@@ -427,8 +686,50 @@ static struct clk_lookup spear_clk_lookups[] = { | |||
427 | { .dev_id = "c3", .clk = &c3_clk}, | 686 | { .dev_id = "c3", .clk = &c3_clk}, |
428 | /* clock derived from apb clk */ | 687 | /* clock derived from apb clk */ |
429 | { .dev_id = "adc", .clk = &adc_clk}, | 688 | { .dev_id = "adc", .clk = &adc_clk}, |
430 | { .dev_id = "ssp", .clk = &ssp_clk}, | 689 | { .dev_id = "ssp-pl022.0", .clk = &ssp0_clk}, |
431 | { .dev_id = "gpio", .clk = &gpio_clk}, | 690 | { .dev_id = "gpio", .clk = &gpio_clk}, |
691 | #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) | ||
692 | { .dev_id = "physmap-flash", .clk = &emi_clk}, | ||
693 | #endif | ||
694 | #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \ | ||
695 | defined(CONFIG_MACH_SPEAR320) | ||
696 | { .con_id = "fsmc", .clk = &fsmc_clk}, | ||
697 | #endif | ||
698 | |||
699 | /* common clocks to spear310 and spear320 */ | ||
700 | #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320) | ||
701 | { .dev_id = "uart1", .clk = &uart1_clk}, | ||
702 | { .dev_id = "uart2", .clk = &uart2_clk}, | ||
703 | #endif | ||
704 | |||
705 | /* common clock to spear300 and spear320 */ | ||
706 | #if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320) | ||
707 | { .dev_id = "clcd", .clk = &clcd_clk}, | ||
708 | { .dev_id = "sdhci", .clk = &sdhci_clk}, | ||
709 | #endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */ | ||
710 | |||
711 | /* spear300 machine specific clock structures */ | ||
712 | #ifdef CONFIG_MACH_SPEAR300 | ||
713 | { .dev_id = "gpio1", .clk = &gpio1_clk}, | ||
714 | { .dev_id = "keyboard", .clk = &kbd_clk}, | ||
715 | #endif | ||
716 | |||
717 | /* spear310 machine specific clock structures */ | ||
718 | #ifdef CONFIG_MACH_SPEAR310 | ||
719 | { .dev_id = "uart3", .clk = &uart3_clk}, | ||
720 | { .dev_id = "uart4", .clk = &uart4_clk}, | ||
721 | { .dev_id = "uart5", .clk = &uart5_clk}, | ||
722 | |||
723 | #endif | ||
724 | /* spear320 machine specific clock structures */ | ||
725 | #ifdef CONFIG_MACH_SPEAR320 | ||
726 | { .dev_id = "c_can_platform.0", .clk = &can0_clk}, | ||
727 | { .dev_id = "c_can_platform.1", .clk = &can1_clk}, | ||
728 | { .dev_id = "i2c_designware.1", .clk = &i2c1_clk}, | ||
729 | { .dev_id = "ssp-pl022.1", .clk = &ssp1_clk}, | ||
730 | { .dev_id = "ssp-pl022.2", .clk = &ssp2_clk}, | ||
731 | { .dev_id = "pwm", .clk = &pwm_clk}, | ||
732 | #endif | ||
432 | }; | 733 | }; |
433 | 734 | ||
434 | void __init clk_init(void) | 735 | void __init clk_init(void) |
diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h index 6c919e1f9c43..0b93347c0f11 100644 --- a/arch/arm/mach-spear3xx/include/mach/misc_regs.h +++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h | |||
@@ -63,8 +63,8 @@ | |||
63 | #define GPT1_CLK_SHIFT 11 | 63 | #define GPT1_CLK_SHIFT 11 |
64 | #define GPT2_CLK_SHIFT 12 | 64 | #define GPT2_CLK_SHIFT 12 |
65 | #define GPT_CLK_MASK 0x1 | 65 | #define GPT_CLK_MASK 0x1 |
66 | #define AUX_CLK_PLL3_MASK 0 | 66 | #define AUX_CLK_PLL3_VAL 0 |
67 | #define AUX_CLK_PLL1_MASK 1 | 67 | #define AUX_CLK_PLL1_VAL 1 |
68 | 68 | ||
69 | #define PERIP1_CLK_ENB (MISC_BASE + 0x02C) | 69 | #define PERIP1_CLK_ENB (MISC_BASE + 0x02C) |
70 | /* PERIP1_CLK_ENB register masks */ | 70 | /* PERIP1_CLK_ENB register masks */ |
@@ -113,6 +113,7 @@ | |||
113 | #define RAS3_CLK_SYNT (MISC_BASE + 0x074) | 113 | #define RAS3_CLK_SYNT (MISC_BASE + 0x074) |
114 | #define RAS4_CLK_SYNT (MISC_BASE + 0x078) | 114 | #define RAS4_CLK_SYNT (MISC_BASE + 0x078) |
115 | /* aux clk synthesiser register masks for irda to ras4 */ | 115 | /* aux clk synthesiser register masks for irda to ras4 */ |
116 | #define AUX_SYNT_ENB 31 | ||
116 | #define AUX_EQ_SEL_SHIFT 30 | 117 | #define AUX_EQ_SEL_SHIFT 30 |
117 | #define AUX_EQ_SEL_MASK 1 | 118 | #define AUX_EQ_SEL_MASK 1 |
118 | #define AUX_EQ1_SEL 0 | 119 | #define AUX_EQ1_SEL 0 |
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c index ef88922986e0..91719524766b 100644 --- a/arch/arm/mach-spear6xx/clock.c +++ b/arch/arm/mach-spear6xx/clock.c | |||
@@ -60,12 +60,22 @@ static struct pll_clk_config pll1_config = { | |||
60 | .masks = &pll1_masks, | 60 | .masks = &pll1_masks, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* pll rate configuration table, in ascending order of rates */ | ||
64 | struct pll_rate_tbl pll_rtbl[] = { | ||
65 | {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */ | ||
66 | {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */ | ||
67 | }; | ||
68 | |||
63 | /* PLL1 clock */ | 69 | /* PLL1 clock */ |
64 | static struct clk pll1_clk = { | 70 | static struct clk pll1_clk = { |
71 | .flags = ENABLED_ON_INIT, | ||
65 | .pclk = &osc_30m_clk, | 72 | .pclk = &osc_30m_clk, |
66 | .en_reg = PLL1_CTR, | 73 | .en_reg = PLL1_CTR, |
67 | .en_reg_bit = PLL_ENABLE, | 74 | .en_reg_bit = PLL_ENABLE, |
75 | .calc_rate = &pll_calc_rate, | ||
68 | .recalc = &pll_clk_recalc, | 76 | .recalc = &pll_clk_recalc, |
77 | .set_rate = &pll_clk_set_rate, | ||
78 | .rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1}, | ||
69 | .private_data = &pll1_config, | 79 | .private_data = &pll1_config, |
70 | }; | 80 | }; |
71 | 81 | ||
@@ -103,35 +113,25 @@ static struct bus_clk_config ahb_config = { | |||
103 | .masks = &ahb_masks, | 113 | .masks = &ahb_masks, |
104 | }; | 114 | }; |
105 | 115 | ||
116 | /* ahb rate configuration table, in ascending order of rates */ | ||
117 | struct bus_rate_tbl bus_rtbl[] = { | ||
118 | {.div = 3}, /* == parent divided by 4 */ | ||
119 | {.div = 2}, /* == parent divided by 3 */ | ||
120 | {.div = 1}, /* == parent divided by 2 */ | ||
121 | {.div = 0}, /* == parent divided by 1 */ | ||
122 | }; | ||
123 | |||
106 | /* ahb clock */ | 124 | /* ahb clock */ |
107 | static struct clk ahb_clk = { | 125 | static struct clk ahb_clk = { |
108 | .flags = ALWAYS_ENABLED, | 126 | .flags = ALWAYS_ENABLED, |
109 | .pclk = &pll1_clk, | 127 | .pclk = &pll1_clk, |
128 | .calc_rate = &bus_calc_rate, | ||
110 | .recalc = &bus_clk_recalc, | 129 | .recalc = &bus_clk_recalc, |
130 | .set_rate = &bus_clk_set_rate, | ||
131 | .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2}, | ||
111 | .private_data = &ahb_config, | 132 | .private_data = &ahb_config, |
112 | }; | 133 | }; |
113 | 134 | ||
114 | /* uart parents */ | ||
115 | static struct pclk_info uart_pclk_info[] = { | ||
116 | { | ||
117 | .pclk = &pll1_clk, | ||
118 | .pclk_mask = AUX_CLK_PLL1_MASK, | ||
119 | .scalable = 1, | ||
120 | }, { | ||
121 | .pclk = &pll3_48m_clk, | ||
122 | .pclk_mask = AUX_CLK_PLL3_MASK, | ||
123 | .scalable = 0, | ||
124 | }, | ||
125 | }; | ||
126 | |||
127 | /* uart parent select structure */ | ||
128 | static struct pclk_sel uart_pclk_sel = { | ||
129 | .pclk_info = uart_pclk_info, | ||
130 | .pclk_count = ARRAY_SIZE(uart_pclk_info), | ||
131 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
132 | .pclk_sel_mask = UART_CLK_MASK, | ||
133 | }; | ||
134 | |||
135 | /* auxiliary synthesizers masks */ | 135 | /* auxiliary synthesizers masks */ |
136 | static struct aux_clk_masks aux_masks = { | 136 | static struct aux_clk_masks aux_masks = { |
137 | .eq_sel_mask = AUX_EQ_SEL_MASK, | 137 | .eq_sel_mask = AUX_EQ_SEL_MASK, |
@@ -145,19 +145,57 @@ static struct aux_clk_masks aux_masks = { | |||
145 | }; | 145 | }; |
146 | 146 | ||
147 | /* uart configurations */ | 147 | /* uart configurations */ |
148 | static struct aux_clk_config uart_config = { | 148 | static struct aux_clk_config uart_synth_config = { |
149 | .synth_reg = UART_CLK_SYNT, | 149 | .synth_reg = UART_CLK_SYNT, |
150 | .masks = &aux_masks, | 150 | .masks = &aux_masks, |
151 | }; | 151 | }; |
152 | 152 | ||
153 | /* aux rate configuration table, in ascending order of rates */ | ||
154 | struct aux_rate_tbl aux_rtbl[] = { | ||
155 | /* For PLL1 = 332 MHz */ | ||
156 | {.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */ | ||
157 | {.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */ | ||
158 | {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */ | ||
159 | }; | ||
160 | |||
161 | /* uart synth clock */ | ||
162 | static struct clk uart_synth_clk = { | ||
163 | .en_reg = UART_CLK_SYNT, | ||
164 | .en_reg_bit = AUX_SYNT_ENB, | ||
165 | .pclk = &pll1_clk, | ||
166 | .calc_rate = &aux_calc_rate, | ||
167 | .recalc = &aux_clk_recalc, | ||
168 | .set_rate = &aux_clk_set_rate, | ||
169 | .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2}, | ||
170 | .private_data = &uart_synth_config, | ||
171 | }; | ||
172 | |||
173 | /* uart parents */ | ||
174 | static struct pclk_info uart_pclk_info[] = { | ||
175 | { | ||
176 | .pclk = &uart_synth_clk, | ||
177 | .pclk_val = AUX_CLK_PLL1_VAL, | ||
178 | }, { | ||
179 | .pclk = &pll3_48m_clk, | ||
180 | .pclk_val = AUX_CLK_PLL3_VAL, | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | /* uart parent select structure */ | ||
185 | static struct pclk_sel uart_pclk_sel = { | ||
186 | .pclk_info = uart_pclk_info, | ||
187 | .pclk_count = ARRAY_SIZE(uart_pclk_info), | ||
188 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
189 | .pclk_sel_mask = UART_CLK_MASK, | ||
190 | }; | ||
191 | |||
153 | /* uart0 clock */ | 192 | /* uart0 clock */ |
154 | static struct clk uart0_clk = { | 193 | static struct clk uart0_clk = { |
155 | .en_reg = PERIP1_CLK_ENB, | 194 | .en_reg = PERIP1_CLK_ENB, |
156 | .en_reg_bit = UART0_CLK_ENB, | 195 | .en_reg_bit = UART0_CLK_ENB, |
157 | .pclk_sel = &uart_pclk_sel, | 196 | .pclk_sel = &uart_pclk_sel, |
158 | .pclk_sel_shift = UART_CLK_SHIFT, | 197 | .pclk_sel_shift = UART_CLK_SHIFT, |
159 | .recalc = &aux_clk_recalc, | 198 | .recalc = &follow_parent, |
160 | .private_data = &uart_config, | ||
161 | }; | 199 | }; |
162 | 200 | ||
163 | /* uart1 clock */ | 201 | /* uart1 clock */ |
@@ -166,26 +204,35 @@ static struct clk uart1_clk = { | |||
166 | .en_reg_bit = UART1_CLK_ENB, | 204 | .en_reg_bit = UART1_CLK_ENB, |
167 | .pclk_sel = &uart_pclk_sel, | 205 | .pclk_sel = &uart_pclk_sel, |
168 | .pclk_sel_shift = UART_CLK_SHIFT, | 206 | .pclk_sel_shift = UART_CLK_SHIFT, |
169 | .recalc = &aux_clk_recalc, | 207 | .recalc = &follow_parent, |
170 | .private_data = &uart_config, | ||
171 | }; | 208 | }; |
172 | 209 | ||
173 | /* firda configurations */ | 210 | /* firda configurations */ |
174 | static struct aux_clk_config firda_config = { | 211 | static struct aux_clk_config firda_synth_config = { |
175 | .synth_reg = FIRDA_CLK_SYNT, | 212 | .synth_reg = FIRDA_CLK_SYNT, |
176 | .masks = &aux_masks, | 213 | .masks = &aux_masks, |
177 | }; | 214 | }; |
178 | 215 | ||
216 | /* firda synth clock */ | ||
217 | static struct clk firda_synth_clk = { | ||
218 | .en_reg = FIRDA_CLK_SYNT, | ||
219 | .en_reg_bit = AUX_SYNT_ENB, | ||
220 | .pclk = &pll1_clk, | ||
221 | .calc_rate = &aux_calc_rate, | ||
222 | .recalc = &aux_clk_recalc, | ||
223 | .set_rate = &aux_clk_set_rate, | ||
224 | .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2}, | ||
225 | .private_data = &firda_synth_config, | ||
226 | }; | ||
227 | |||
179 | /* firda parents */ | 228 | /* firda parents */ |
180 | static struct pclk_info firda_pclk_info[] = { | 229 | static struct pclk_info firda_pclk_info[] = { |
181 | { | 230 | { |
182 | .pclk = &pll1_clk, | 231 | .pclk = &firda_synth_clk, |
183 | .pclk_mask = AUX_CLK_PLL1_MASK, | 232 | .pclk_val = AUX_CLK_PLL1_VAL, |
184 | .scalable = 1, | ||
185 | }, { | 233 | }, { |
186 | .pclk = &pll3_48m_clk, | 234 | .pclk = &pll3_48m_clk, |
187 | .pclk_mask = AUX_CLK_PLL3_MASK, | 235 | .pclk_val = AUX_CLK_PLL3_VAL, |
188 | .scalable = 0, | ||
189 | }, | 236 | }, |
190 | }; | 237 | }; |
191 | 238 | ||
@@ -203,26 +250,35 @@ static struct clk firda_clk = { | |||
203 | .en_reg_bit = FIRDA_CLK_ENB, | 250 | .en_reg_bit = FIRDA_CLK_ENB, |
204 | .pclk_sel = &firda_pclk_sel, | 251 | .pclk_sel = &firda_pclk_sel, |
205 | .pclk_sel_shift = FIRDA_CLK_SHIFT, | 252 | .pclk_sel_shift = FIRDA_CLK_SHIFT, |
206 | .recalc = &aux_clk_recalc, | 253 | .recalc = &follow_parent, |
207 | .private_data = &firda_config, | ||
208 | }; | 254 | }; |
209 | 255 | ||
210 | /* clcd configurations */ | 256 | /* clcd configurations */ |
211 | static struct aux_clk_config clcd_config = { | 257 | static struct aux_clk_config clcd_synth_config = { |
212 | .synth_reg = CLCD_CLK_SYNT, | 258 | .synth_reg = CLCD_CLK_SYNT, |
213 | .masks = &aux_masks, | 259 | .masks = &aux_masks, |
214 | }; | 260 | }; |
215 | 261 | ||
262 | /* firda synth clock */ | ||
263 | static struct clk clcd_synth_clk = { | ||
264 | .en_reg = CLCD_CLK_SYNT, | ||
265 | .en_reg_bit = AUX_SYNT_ENB, | ||
266 | .pclk = &pll1_clk, | ||
267 | .calc_rate = &aux_calc_rate, | ||
268 | .recalc = &aux_clk_recalc, | ||
269 | .set_rate = &aux_clk_set_rate, | ||
270 | .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2}, | ||
271 | .private_data = &clcd_synth_config, | ||
272 | }; | ||
273 | |||
216 | /* clcd parents */ | 274 | /* clcd parents */ |
217 | static struct pclk_info clcd_pclk_info[] = { | 275 | static struct pclk_info clcd_pclk_info[] = { |
218 | { | 276 | { |
219 | .pclk = &pll1_clk, | 277 | .pclk = &clcd_synth_clk, |
220 | .pclk_mask = AUX_CLK_PLL1_MASK, | 278 | .pclk_val = AUX_CLK_PLL1_VAL, |
221 | .scalable = 1, | ||
222 | }, { | 279 | }, { |
223 | .pclk = &pll3_48m_clk, | 280 | .pclk = &pll3_48m_clk, |
224 | .pclk_mask = AUX_CLK_PLL3_MASK, | 281 | .pclk_val = AUX_CLK_PLL3_VAL, |
225 | .scalable = 0, | ||
226 | }, | 282 | }, |
227 | }; | 283 | }; |
228 | 284 | ||
@@ -240,29 +296,7 @@ static struct clk clcd_clk = { | |||
240 | .en_reg_bit = CLCD_CLK_ENB, | 296 | .en_reg_bit = CLCD_CLK_ENB, |
241 | .pclk_sel = &clcd_pclk_sel, | 297 | .pclk_sel = &clcd_pclk_sel, |
242 | .pclk_sel_shift = CLCD_CLK_SHIFT, | 298 | .pclk_sel_shift = CLCD_CLK_SHIFT, |
243 | .recalc = &aux_clk_recalc, | 299 | .recalc = &follow_parent, |
244 | .private_data = &clcd_config, | ||
245 | }; | ||
246 | |||
247 | /* gpt parents */ | ||
248 | static struct pclk_info gpt_pclk_info[] = { | ||
249 | { | ||
250 | .pclk = &pll1_clk, | ||
251 | .pclk_mask = AUX_CLK_PLL1_MASK, | ||
252 | .scalable = 1, | ||
253 | }, { | ||
254 | .pclk = &pll3_48m_clk, | ||
255 | .pclk_mask = AUX_CLK_PLL3_MASK, | ||
256 | .scalable = 0, | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | /* gpt parent select structure */ | ||
261 | static struct pclk_sel gpt_pclk_sel = { | ||
262 | .pclk_info = gpt_pclk_info, | ||
263 | .pclk_count = ARRAY_SIZE(gpt_pclk_info), | ||
264 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
265 | .pclk_sel_mask = GPT_CLK_MASK, | ||
266 | }; | 300 | }; |
267 | 301 | ||
268 | /* gpt synthesizer masks */ | 302 | /* gpt synthesizer masks */ |
@@ -273,60 +307,162 @@ static struct gpt_clk_masks gpt_masks = { | |||
273 | .nscale_sel_shift = GPT_NSCALE_SHIFT, | 307 | .nscale_sel_shift = GPT_NSCALE_SHIFT, |
274 | }; | 308 | }; |
275 | 309 | ||
276 | /* gpt0_1 configurations */ | 310 | /* gpt rate configuration table, in ascending order of rates */ |
277 | static struct gpt_clk_config gpt0_1_config = { | 311 | struct gpt_rate_tbl gpt_rtbl[] = { |
312 | /* For pll1 = 332 MHz */ | ||
313 | {.mscale = 4, .nscale = 0}, /* 41.5 MHz */ | ||
314 | {.mscale = 2, .nscale = 0}, /* 55.3 MHz */ | ||
315 | {.mscale = 1, .nscale = 0}, /* 83 MHz */ | ||
316 | }; | ||
317 | |||
318 | /* gpt0 synth clk config*/ | ||
319 | static struct gpt_clk_config gpt0_synth_config = { | ||
278 | .synth_reg = PRSC1_CLK_CFG, | 320 | .synth_reg = PRSC1_CLK_CFG, |
279 | .masks = &gpt_masks, | 321 | .masks = &gpt_masks, |
280 | }; | 322 | }; |
281 | 323 | ||
324 | /* gpt synth clock */ | ||
325 | static struct clk gpt0_synth_clk = { | ||
326 | .flags = ALWAYS_ENABLED, | ||
327 | .pclk = &pll1_clk, | ||
328 | .calc_rate = &gpt_calc_rate, | ||
329 | .recalc = &gpt_clk_recalc, | ||
330 | .set_rate = &gpt_clk_set_rate, | ||
331 | .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2}, | ||
332 | .private_data = &gpt0_synth_config, | ||
333 | }; | ||
334 | |||
335 | /* gpt parents */ | ||
336 | static struct pclk_info gpt0_pclk_info[] = { | ||
337 | { | ||
338 | .pclk = &gpt0_synth_clk, | ||
339 | .pclk_val = AUX_CLK_PLL1_VAL, | ||
340 | }, { | ||
341 | .pclk = &pll3_48m_clk, | ||
342 | .pclk_val = AUX_CLK_PLL3_VAL, | ||
343 | }, | ||
344 | }; | ||
345 | |||
346 | /* gpt parent select structure */ | ||
347 | static struct pclk_sel gpt0_pclk_sel = { | ||
348 | .pclk_info = gpt0_pclk_info, | ||
349 | .pclk_count = ARRAY_SIZE(gpt0_pclk_info), | ||
350 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
351 | .pclk_sel_mask = GPT_CLK_MASK, | ||
352 | }; | ||
353 | |||
282 | /* gpt0 ARM1 subsystem timer clock */ | 354 | /* gpt0 ARM1 subsystem timer clock */ |
283 | static struct clk gpt0_clk = { | 355 | static struct clk gpt0_clk = { |
284 | .flags = ALWAYS_ENABLED, | 356 | .flags = ALWAYS_ENABLED, |
285 | .pclk_sel = &gpt_pclk_sel, | 357 | .pclk_sel = &gpt0_pclk_sel, |
286 | .pclk_sel_shift = GPT0_CLK_SHIFT, | 358 | .pclk_sel_shift = GPT0_CLK_SHIFT, |
287 | .recalc = &gpt_clk_recalc, | 359 | .recalc = &follow_parent, |
288 | .private_data = &gpt0_1_config, | 360 | }; |
361 | |||
362 | |||
363 | /* Note: gpt0 and gpt1 share same parent clocks */ | ||
364 | /* gpt parent select structure */ | ||
365 | static struct pclk_sel gpt1_pclk_sel = { | ||
366 | .pclk_info = gpt0_pclk_info, | ||
367 | .pclk_count = ARRAY_SIZE(gpt0_pclk_info), | ||
368 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
369 | .pclk_sel_mask = GPT_CLK_MASK, | ||
289 | }; | 370 | }; |
290 | 371 | ||
291 | /* gpt1 timer clock */ | 372 | /* gpt1 timer clock */ |
292 | static struct clk gpt1_clk = { | 373 | static struct clk gpt1_clk = { |
293 | .flags = ALWAYS_ENABLED, | 374 | .flags = ALWAYS_ENABLED, |
294 | .pclk_sel = &gpt_pclk_sel, | 375 | .pclk_sel = &gpt1_pclk_sel, |
295 | .pclk_sel_shift = GPT1_CLK_SHIFT, | 376 | .pclk_sel_shift = GPT1_CLK_SHIFT, |
296 | .recalc = &gpt_clk_recalc, | 377 | .recalc = &follow_parent, |
297 | .private_data = &gpt0_1_config, | ||
298 | }; | 378 | }; |
299 | 379 | ||
300 | /* gpt2 configurations */ | 380 | /* gpt2 synth clk config*/ |
301 | static struct gpt_clk_config gpt2_config = { | 381 | static struct gpt_clk_config gpt2_synth_config = { |
302 | .synth_reg = PRSC2_CLK_CFG, | 382 | .synth_reg = PRSC2_CLK_CFG, |
303 | .masks = &gpt_masks, | 383 | .masks = &gpt_masks, |
304 | }; | 384 | }; |
305 | 385 | ||
386 | /* gpt synth clock */ | ||
387 | static struct clk gpt2_synth_clk = { | ||
388 | .flags = ALWAYS_ENABLED, | ||
389 | .pclk = &pll1_clk, | ||
390 | .calc_rate = &gpt_calc_rate, | ||
391 | .recalc = &gpt_clk_recalc, | ||
392 | .set_rate = &gpt_clk_set_rate, | ||
393 | .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2}, | ||
394 | .private_data = &gpt2_synth_config, | ||
395 | }; | ||
396 | |||
397 | /* gpt parents */ | ||
398 | static struct pclk_info gpt2_pclk_info[] = { | ||
399 | { | ||
400 | .pclk = &gpt2_synth_clk, | ||
401 | .pclk_val = AUX_CLK_PLL1_VAL, | ||
402 | }, { | ||
403 | .pclk = &pll3_48m_clk, | ||
404 | .pclk_val = AUX_CLK_PLL3_VAL, | ||
405 | }, | ||
406 | }; | ||
407 | |||
408 | /* gpt parent select structure */ | ||
409 | static struct pclk_sel gpt2_pclk_sel = { | ||
410 | .pclk_info = gpt2_pclk_info, | ||
411 | .pclk_count = ARRAY_SIZE(gpt2_pclk_info), | ||
412 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
413 | .pclk_sel_mask = GPT_CLK_MASK, | ||
414 | }; | ||
415 | |||
306 | /* gpt2 timer clock */ | 416 | /* gpt2 timer clock */ |
307 | static struct clk gpt2_clk = { | 417 | static struct clk gpt2_clk = { |
308 | .en_reg = PERIP1_CLK_ENB, | 418 | .flags = ALWAYS_ENABLED, |
309 | .en_reg_bit = GPT2_CLK_ENB, | 419 | .pclk_sel = &gpt2_pclk_sel, |
310 | .pclk_sel = &gpt_pclk_sel, | ||
311 | .pclk_sel_shift = GPT2_CLK_SHIFT, | 420 | .pclk_sel_shift = GPT2_CLK_SHIFT, |
312 | .recalc = &gpt_clk_recalc, | 421 | .recalc = &follow_parent, |
313 | .private_data = &gpt2_config, | ||
314 | }; | 422 | }; |
315 | 423 | ||
316 | /* gpt3 configurations */ | 424 | /* gpt3 synth clk config*/ |
317 | static struct gpt_clk_config gpt3_config = { | 425 | static struct gpt_clk_config gpt3_synth_config = { |
318 | .synth_reg = PRSC3_CLK_CFG, | 426 | .synth_reg = PRSC3_CLK_CFG, |
319 | .masks = &gpt_masks, | 427 | .masks = &gpt_masks, |
320 | }; | 428 | }; |
321 | 429 | ||
430 | /* gpt synth clock */ | ||
431 | static struct clk gpt3_synth_clk = { | ||
432 | .flags = ALWAYS_ENABLED, | ||
433 | .pclk = &pll1_clk, | ||
434 | .calc_rate = &gpt_calc_rate, | ||
435 | .recalc = &gpt_clk_recalc, | ||
436 | .set_rate = &gpt_clk_set_rate, | ||
437 | .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2}, | ||
438 | .private_data = &gpt3_synth_config, | ||
439 | }; | ||
440 | |||
441 | /* gpt parents */ | ||
442 | static struct pclk_info gpt3_pclk_info[] = { | ||
443 | { | ||
444 | .pclk = &gpt3_synth_clk, | ||
445 | .pclk_val = AUX_CLK_PLL1_VAL, | ||
446 | }, { | ||
447 | .pclk = &pll3_48m_clk, | ||
448 | .pclk_val = AUX_CLK_PLL3_VAL, | ||
449 | }, | ||
450 | }; | ||
451 | |||
452 | /* gpt parent select structure */ | ||
453 | static struct pclk_sel gpt3_pclk_sel = { | ||
454 | .pclk_info = gpt3_pclk_info, | ||
455 | .pclk_count = ARRAY_SIZE(gpt3_pclk_info), | ||
456 | .pclk_sel_reg = PERIP_CLK_CFG, | ||
457 | .pclk_sel_mask = GPT_CLK_MASK, | ||
458 | }; | ||
459 | |||
322 | /* gpt3 timer clock */ | 460 | /* gpt3 timer clock */ |
323 | static struct clk gpt3_clk = { | 461 | static struct clk gpt3_clk = { |
324 | .en_reg = PERIP1_CLK_ENB, | 462 | .flags = ALWAYS_ENABLED, |
325 | .en_reg_bit = GPT3_CLK_ENB, | 463 | .pclk_sel = &gpt3_pclk_sel, |
326 | .pclk_sel = &gpt_pclk_sel, | ||
327 | .pclk_sel_shift = GPT3_CLK_SHIFT, | 464 | .pclk_sel_shift = GPT3_CLK_SHIFT, |
328 | .recalc = &gpt_clk_recalc, | 465 | .recalc = &follow_parent, |
329 | .private_data = &gpt3_config, | ||
330 | }; | 466 | }; |
331 | 467 | ||
332 | /* clock derived from pll3 clk */ | 468 | /* clock derived from pll3 clk */ |
@@ -371,7 +507,10 @@ static struct bus_clk_config apb_config = { | |||
371 | static struct clk apb_clk = { | 507 | static struct clk apb_clk = { |
372 | .flags = ALWAYS_ENABLED, | 508 | .flags = ALWAYS_ENABLED, |
373 | .pclk = &ahb_clk, | 509 | .pclk = &ahb_clk, |
510 | .calc_rate = &bus_calc_rate, | ||
374 | .recalc = &bus_clk_recalc, | 511 | .recalc = &bus_clk_recalc, |
512 | .set_rate = &bus_clk_set_rate, | ||
513 | .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2}, | ||
375 | .private_data = &apb_config, | 514 | .private_data = &apb_config, |
376 | }; | 515 | }; |
377 | 516 | ||
@@ -488,7 +627,7 @@ static struct clk_lookup spear_clk_lookups[] = { | |||
488 | { .con_id = "osc_32k_clk", .clk = &osc_32k_clk}, | 627 | { .con_id = "osc_32k_clk", .clk = &osc_32k_clk}, |
489 | { .con_id = "osc_30m_clk", .clk = &osc_30m_clk}, | 628 | { .con_id = "osc_30m_clk", .clk = &osc_30m_clk}, |
490 | /* clock derived from 32 KHz os clk */ | 629 | /* clock derived from 32 KHz os clk */ |
491 | { .dev_id = "rtc", .clk = &rtc_clk}, | 630 | { .dev_id = "rtc-spear", .clk = &rtc_clk}, |
492 | /* clock derived from 30 MHz os clk */ | 631 | /* clock derived from 30 MHz os clk */ |
493 | { .con_id = "pll1_clk", .clk = &pll1_clk}, | 632 | { .con_id = "pll1_clk", .clk = &pll1_clk}, |
494 | { .con_id = "pll3_48m_clk", .clk = &pll3_48m_clk}, | 633 | { .con_id = "pll3_48m_clk", .clk = &pll3_48m_clk}, |
@@ -496,6 +635,12 @@ static struct clk_lookup spear_clk_lookups[] = { | |||
496 | /* clock derived from pll1 clk */ | 635 | /* clock derived from pll1 clk */ |
497 | { .con_id = "cpu_clk", .clk = &cpu_clk}, | 636 | { .con_id = "cpu_clk", .clk = &cpu_clk}, |
498 | { .con_id = "ahb_clk", .clk = &ahb_clk}, | 637 | { .con_id = "ahb_clk", .clk = &ahb_clk}, |
638 | { .con_id = "uart_synth_clk", .clk = &uart_synth_clk}, | ||
639 | { .con_id = "firda_synth_clk", .clk = &firda_synth_clk}, | ||
640 | { .con_id = "clcd_synth_clk", .clk = &clcd_synth_clk}, | ||
641 | { .con_id = "gpt0_synth_clk", .clk = &gpt0_synth_clk}, | ||
642 | { .con_id = "gpt2_synth_clk", .clk = &gpt2_synth_clk}, | ||
643 | { .con_id = "gpt3_synth_clk", .clk = &gpt3_synth_clk}, | ||
499 | { .dev_id = "uart0", .clk = &uart0_clk}, | 644 | { .dev_id = "uart0", .clk = &uart0_clk}, |
500 | { .dev_id = "uart1", .clk = &uart1_clk}, | 645 | { .dev_id = "uart1", .clk = &uart1_clk}, |
501 | { .dev_id = "firda", .clk = &firda_clk}, | 646 | { .dev_id = "firda", .clk = &firda_clk}, |
@@ -505,22 +650,22 @@ static struct clk_lookup spear_clk_lookups[] = { | |||
505 | { .dev_id = "gpt2", .clk = &gpt2_clk}, | 650 | { .dev_id = "gpt2", .clk = &gpt2_clk}, |
506 | { .dev_id = "gpt3", .clk = &gpt3_clk}, | 651 | { .dev_id = "gpt3", .clk = &gpt3_clk}, |
507 | /* clock derived from pll3 clk */ | 652 | /* clock derived from pll3 clk */ |
508 | { .dev_id = "usbh0", .clk = &usbh0_clk}, | 653 | { .con_id = "usbh.0_clk", .clk = &usbh0_clk}, |
509 | { .dev_id = "usbh1", .clk = &usbh1_clk}, | 654 | { .con_id = "usbh.1_clk", .clk = &usbh1_clk}, |
510 | { .dev_id = "usbd", .clk = &usbd_clk}, | 655 | { .dev_id = "usbd", .clk = &usbd_clk}, |
511 | /* clock derived from ahb clk */ | 656 | /* clock derived from ahb clk */ |
512 | { .con_id = "apb_clk", .clk = &apb_clk}, | 657 | { .con_id = "apb_clk", .clk = &apb_clk}, |
513 | { .dev_id = "i2c", .clk = &i2c_clk}, | 658 | { .dev_id = "i2c_designware.0", .clk = &i2c_clk}, |
514 | { .dev_id = "dma", .clk = &dma_clk}, | 659 | { .dev_id = "dma", .clk = &dma_clk}, |
515 | { .dev_id = "jpeg", .clk = &jpeg_clk}, | 660 | { .dev_id = "jpeg", .clk = &jpeg_clk}, |
516 | { .dev_id = "gmac", .clk = &gmac_clk}, | 661 | { .dev_id = "gmac", .clk = &gmac_clk}, |
517 | { .dev_id = "smi", .clk = &smi_clk}, | 662 | { .dev_id = "smi", .clk = &smi_clk}, |
518 | { .dev_id = "fsmc", .clk = &fsmc_clk}, | 663 | { .con_id = "fsmc", .clk = &fsmc_clk}, |
519 | /* clock derived from apb clk */ | 664 | /* clock derived from apb clk */ |
520 | { .dev_id = "adc", .clk = &adc_clk}, | 665 | { .dev_id = "adc", .clk = &adc_clk}, |
521 | { .dev_id = "ssp0", .clk = &ssp0_clk}, | 666 | { .dev_id = "ssp-pl022.0", .clk = &ssp0_clk}, |
522 | { .dev_id = "ssp1", .clk = &ssp1_clk}, | 667 | { .dev_id = "ssp-pl022.1", .clk = &ssp1_clk}, |
523 | { .dev_id = "ssp2", .clk = &ssp2_clk}, | 668 | { .dev_id = "ssp-pl022.2", .clk = &ssp2_clk}, |
524 | { .dev_id = "gpio0", .clk = &gpio0_clk}, | 669 | { .dev_id = "gpio0", .clk = &gpio0_clk}, |
525 | { .dev_id = "gpio1", .clk = &gpio1_clk}, | 670 | { .dev_id = "gpio1", .clk = &gpio1_clk}, |
526 | { .dev_id = "gpio2", .clk = &gpio2_clk}, | 671 | { .dev_id = "gpio2", .clk = &gpio2_clk}, |
diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h index d15317788d0d..45571c13227a 100644 --- a/arch/arm/mach-spear6xx/include/mach/misc_regs.h +++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h | |||
@@ -66,8 +66,8 @@ | |||
66 | #define GPT2_CLK_SHIFT 11 | 66 | #define GPT2_CLK_SHIFT 11 |
67 | #define GPT3_CLK_SHIFT 12 | 67 | #define GPT3_CLK_SHIFT 12 |
68 | #define GPT_CLK_MASK 0x1 | 68 | #define GPT_CLK_MASK 0x1 |
69 | #define AUX_CLK_PLL3_MASK 0 | 69 | #define AUX_CLK_PLL3_VAL 0 |
70 | #define AUX_CLK_PLL1_MASK 1 | 70 | #define AUX_CLK_PLL1_VAL 1 |
71 | 71 | ||
72 | #define PERIP1_CLK_ENB (MISC_BASE + 0x02C) | 72 | #define PERIP1_CLK_ENB (MISC_BASE + 0x02C) |
73 | /* PERIP1_CLK_ENB register masks */ | 73 | /* PERIP1_CLK_ENB register masks */ |
@@ -123,6 +123,7 @@ | |||
123 | #define RAS3_CLK_SYNT (MISC_BASE + 0x074) | 123 | #define RAS3_CLK_SYNT (MISC_BASE + 0x074) |
124 | #define RAS4_CLK_SYNT (MISC_BASE + 0x078) | 124 | #define RAS4_CLK_SYNT (MISC_BASE + 0x078) |
125 | /* aux clk synthesiser register masks for irda to ras4 */ | 125 | /* aux clk synthesiser register masks for irda to ras4 */ |
126 | #define AUX_SYNT_ENB 31 | ||
126 | #define AUX_EQ_SEL_SHIFT 30 | 127 | #define AUX_EQ_SEL_SHIFT 30 |
127 | #define AUX_EQ_SEL_MASK 1 | 128 | #define AUX_EQ_SEL_MASK 1 |
128 | #define AUX_EQ1_SEL 0 | 129 | #define AUX_EQ1_SEL 0 |
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c index f1cf832e4e3b..7e7ab606dc49 100644 --- a/arch/arm/plat-spear/clock.c +++ b/arch/arm/plat-spear/clock.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/bug.h> | 14 | #include <linux/bug.h> |
15 | #include <linux/clk.h> | ||
15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
16 | #include <linux/io.h> | 17 | #include <linux/io.h> |
17 | #include <linux/list.h> | 18 | #include <linux/list.h> |
@@ -22,7 +23,7 @@ | |||
22 | static DEFINE_SPINLOCK(clocks_lock); | 23 | static DEFINE_SPINLOCK(clocks_lock); |
23 | static LIST_HEAD(root_clks); | 24 | static LIST_HEAD(root_clks); |
24 | 25 | ||
25 | static void propagate_rate(struct list_head *); | 26 | static void propagate_rate(struct clk *, int on_init); |
26 | 27 | ||
27 | static int generic_clk_enable(struct clk *clk) | 28 | static int generic_clk_enable(struct clk *clk) |
28 | { | 29 | { |
@@ -64,6 +65,100 @@ static struct clkops generic_clkops = { | |||
64 | .disable = generic_clk_disable, | 65 | .disable = generic_clk_disable, |
65 | }; | 66 | }; |
66 | 67 | ||
68 | /* returns current programmed clocks clock info structure */ | ||
69 | static struct pclk_info *pclk_info_get(struct clk *clk) | ||
70 | { | ||
71 | unsigned int val, i; | ||
72 | struct pclk_info *info = NULL; | ||
73 | |||
74 | val = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift) | ||
75 | & clk->pclk_sel->pclk_sel_mask; | ||
76 | |||
77 | for (i = 0; i < clk->pclk_sel->pclk_count; i++) { | ||
78 | if (clk->pclk_sel->pclk_info[i].pclk_val == val) | ||
79 | info = &clk->pclk_sel->pclk_info[i]; | ||
80 | } | ||
81 | |||
82 | return info; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Set Update pclk, and pclk_info of clk and add clock sibling node to current | ||
87 | * parents children list | ||
88 | */ | ||
89 | static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info) | ||
90 | { | ||
91 | unsigned long flags; | ||
92 | |||
93 | spin_lock_irqsave(&clocks_lock, flags); | ||
94 | list_del(&clk->sibling); | ||
95 | list_add(&clk->sibling, &pclk_info->pclk->children); | ||
96 | |||
97 | clk->pclk = pclk_info->pclk; | ||
98 | spin_unlock_irqrestore(&clocks_lock, flags); | ||
99 | } | ||
100 | |||
101 | static void do_clk_disable(struct clk *clk) | ||
102 | { | ||
103 | if (!clk) | ||
104 | return; | ||
105 | |||
106 | if (!clk->usage_count) { | ||
107 | WARN_ON(1); | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | clk->usage_count--; | ||
112 | |||
113 | if (clk->usage_count == 0) { | ||
114 | /* | ||
115 | * Surely, there are no active childrens or direct users | ||
116 | * of this clock | ||
117 | */ | ||
118 | if (clk->pclk) | ||
119 | do_clk_disable(clk->pclk); | ||
120 | |||
121 | if (clk->ops && clk->ops->disable) | ||
122 | clk->ops->disable(clk); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static int do_clk_enable(struct clk *clk) | ||
127 | { | ||
128 | int ret = 0; | ||
129 | |||
130 | if (!clk) | ||
131 | return -EFAULT; | ||
132 | |||
133 | if (clk->usage_count == 0) { | ||
134 | if (clk->pclk) { | ||
135 | ret = do_clk_enable(clk->pclk); | ||
136 | if (ret) | ||
137 | goto err; | ||
138 | } | ||
139 | if (clk->ops && clk->ops->enable) { | ||
140 | ret = clk->ops->enable(clk); | ||
141 | if (ret) { | ||
142 | if (clk->pclk) | ||
143 | do_clk_disable(clk->pclk); | ||
144 | goto err; | ||
145 | } | ||
146 | } | ||
147 | /* | ||
148 | * Since the clock is going to be used for the first | ||
149 | * time please reclac | ||
150 | */ | ||
151 | if (clk->recalc) { | ||
152 | ret = clk->recalc(clk); | ||
153 | if (ret) | ||
154 | goto err; | ||
155 | } | ||
156 | } | ||
157 | clk->usage_count++; | ||
158 | err: | ||
159 | return ret; | ||
160 | } | ||
161 | |||
67 | /* | 162 | /* |
68 | * clk_enable - inform the system when the clock source should be running. | 163 | * clk_enable - inform the system when the clock source should be running. |
69 | * @clk: clock source | 164 | * @clk: clock source |
@@ -77,17 +172,9 @@ int clk_enable(struct clk *clk) | |||
77 | unsigned long flags; | 172 | unsigned long flags; |
78 | int ret = 0; | 173 | int ret = 0; |
79 | 174 | ||
80 | if (!clk || IS_ERR(clk)) | ||
81 | return -EFAULT; | ||
82 | |||
83 | spin_lock_irqsave(&clocks_lock, flags); | 175 | spin_lock_irqsave(&clocks_lock, flags); |
84 | if (clk->usage_count == 0) { | 176 | ret = do_clk_enable(clk); |
85 | if (clk->ops && clk->ops->enable) | ||
86 | ret = clk->ops->enable(clk); | ||
87 | } | ||
88 | clk->usage_count++; | ||
89 | spin_unlock_irqrestore(&clocks_lock, flags); | 177 | spin_unlock_irqrestore(&clocks_lock, flags); |
90 | |||
91 | return ret; | 178 | return ret; |
92 | } | 179 | } |
93 | EXPORT_SYMBOL(clk_enable); | 180 | EXPORT_SYMBOL(clk_enable); |
@@ -108,17 +195,8 @@ void clk_disable(struct clk *clk) | |||
108 | { | 195 | { |
109 | unsigned long flags; | 196 | unsigned long flags; |
110 | 197 | ||
111 | if (!clk || IS_ERR(clk)) | ||
112 | return; | ||
113 | |||
114 | WARN_ON(clk->usage_count == 0); | ||
115 | |||
116 | spin_lock_irqsave(&clocks_lock, flags); | 198 | spin_lock_irqsave(&clocks_lock, flags); |
117 | clk->usage_count--; | 199 | do_clk_disable(clk); |
118 | if (clk->usage_count == 0) { | ||
119 | if (clk->ops && clk->ops->disable) | ||
120 | clk->ops->disable(clk); | ||
121 | } | ||
122 | spin_unlock_irqrestore(&clocks_lock, flags); | 200 | spin_unlock_irqrestore(&clocks_lock, flags); |
123 | } | 201 | } |
124 | EXPORT_SYMBOL(clk_disable); | 202 | EXPORT_SYMBOL(clk_disable); |
@@ -152,15 +230,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent) | |||
152 | int i, found = 0, val = 0; | 230 | int i, found = 0, val = 0; |
153 | unsigned long flags; | 231 | unsigned long flags; |
154 | 232 | ||
155 | if (!clk || IS_ERR(clk) || !parent || IS_ERR(parent)) | 233 | if (!clk || !parent) |
156 | return -EFAULT; | 234 | return -EFAULT; |
157 | if (clk->usage_count) | ||
158 | return -EBUSY; | ||
159 | if (!clk->pclk_sel) | ||
160 | return -EPERM; | ||
161 | if (clk->pclk == parent) | 235 | if (clk->pclk == parent) |
162 | return 0; | 236 | return 0; |
237 | if (!clk->pclk_sel) | ||
238 | return -EPERM; | ||
163 | 239 | ||
240 | /* check if requested parent is in clk parent list */ | ||
164 | for (i = 0; i < clk->pclk_sel->pclk_count; i++) { | 241 | for (i = 0; i < clk->pclk_sel->pclk_count; i++) { |
165 | if (clk->pclk_sel->pclk_info[i].pclk == parent) { | 242 | if (clk->pclk_sel->pclk_info[i].pclk == parent) { |
166 | found = 1; | 243 | found = 1; |
@@ -175,13 +252,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent) | |||
175 | /* reflect parent change in hardware */ | 252 | /* reflect parent change in hardware */ |
176 | val = readl(clk->pclk_sel->pclk_sel_reg); | 253 | val = readl(clk->pclk_sel->pclk_sel_reg); |
177 | val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift); | 254 | val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift); |
178 | val |= clk->pclk_sel->pclk_info[i].pclk_mask << clk->pclk_sel_shift; | 255 | val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift; |
179 | writel(val, clk->pclk_sel->pclk_sel_reg); | 256 | writel(val, clk->pclk_sel->pclk_sel_reg); |
180 | spin_unlock_irqrestore(&clocks_lock, flags); | 257 | spin_unlock_irqrestore(&clocks_lock, flags); |
181 | 258 | ||
182 | /* reflect parent change in software */ | 259 | /* reflect parent change in software */ |
183 | clk->recalc(clk); | 260 | clk_reparent(clk, &clk->pclk_sel->pclk_info[i]); |
184 | propagate_rate(&clk->children); | 261 | |
262 | propagate_rate(clk, 0); | ||
185 | return 0; | 263 | return 0; |
186 | } | 264 | } |
187 | EXPORT_SYMBOL(clk_set_parent); | 265 | EXPORT_SYMBOL(clk_set_parent); |
@@ -195,19 +273,37 @@ EXPORT_SYMBOL(clk_set_parent); | |||
195 | */ | 273 | */ |
196 | int clk_set_rate(struct clk *clk, unsigned long rate) | 274 | int clk_set_rate(struct clk *clk, unsigned long rate) |
197 | { | 275 | { |
198 | /* TODO */ | 276 | unsigned long flags; |
199 | return -EINVAL; | 277 | int ret = -EINVAL; |
278 | |||
279 | if (!clk || !rate) | ||
280 | return -EFAULT; | ||
281 | |||
282 | if (clk->set_rate) { | ||
283 | spin_lock_irqsave(&clocks_lock, flags); | ||
284 | ret = clk->set_rate(clk, rate); | ||
285 | if (!ret) | ||
286 | /* if successful -> propagate */ | ||
287 | propagate_rate(clk, 0); | ||
288 | spin_unlock_irqrestore(&clocks_lock, flags); | ||
289 | } else if (clk->pclk) { | ||
290 | u32 mult = clk->div_factor ? clk->div_factor : 1; | ||
291 | ret = clk_set_rate(clk->pclk, mult * rate); | ||
292 | } | ||
293 | |||
294 | return ret; | ||
200 | } | 295 | } |
201 | EXPORT_SYMBOL(clk_set_rate); | 296 | EXPORT_SYMBOL(clk_set_rate); |
202 | 297 | ||
203 | /* registers clock in platform clock framework */ | 298 | /* registers clock in platform clock framework */ |
204 | void clk_register(struct clk_lookup *cl) | 299 | void clk_register(struct clk_lookup *cl) |
205 | { | 300 | { |
206 | struct clk *clk = cl->clk; | 301 | struct clk *clk; |
207 | unsigned long flags; | 302 | unsigned long flags; |
208 | 303 | ||
209 | if (!clk || IS_ERR(clk)) | 304 | if (!cl || !cl->clk) |
210 | return; | 305 | return; |
306 | clk = cl->clk; | ||
211 | 307 | ||
212 | spin_lock_irqsave(&clocks_lock, flags); | 308 | spin_lock_irqsave(&clocks_lock, flags); |
213 | 309 | ||
@@ -220,15 +316,24 @@ void clk_register(struct clk_lookup *cl) | |||
220 | /* root clock don't have any parents */ | 316 | /* root clock don't have any parents */ |
221 | if (!clk->pclk && !clk->pclk_sel) { | 317 | if (!clk->pclk && !clk->pclk_sel) { |
222 | list_add(&clk->sibling, &root_clks); | 318 | list_add(&clk->sibling, &root_clks); |
223 | /* add clocks with only one parent to parent's children list */ | ||
224 | } else if (clk->pclk && !clk->pclk_sel) { | 319 | } else if (clk->pclk && !clk->pclk_sel) { |
320 | /* add clocks with only one parent to parent's children list */ | ||
225 | list_add(&clk->sibling, &clk->pclk->children); | 321 | list_add(&clk->sibling, &clk->pclk->children); |
226 | } else { | 322 | } else { |
227 | /* add clocks with > 1 parent to 1st parent's children list */ | 323 | /* clocks with more than one parent */ |
228 | clk->pclk = clk->pclk_sel->pclk_info[0].pclk; | 324 | struct pclk_info *pclk_info; |
229 | list_add(&clk->sibling, | 325 | |
230 | &clk->pclk_sel->pclk_info[0].pclk->children); | 326 | pclk_info = pclk_info_get(clk); |
327 | if (!pclk_info) { | ||
328 | pr_err("CLKDEV: invalid pclk info of clk with" | ||
329 | " %s dev_id and %s con_id\n", | ||
330 | cl->dev_id, cl->con_id); | ||
331 | } else { | ||
332 | clk->pclk = pclk_info->pclk; | ||
333 | list_add(&clk->sibling, &pclk_info->pclk->children); | ||
334 | } | ||
231 | } | 335 | } |
336 | |||
232 | spin_unlock_irqrestore(&clocks_lock, flags); | 337 | spin_unlock_irqrestore(&clocks_lock, flags); |
233 | 338 | ||
234 | /* add clock to arm clockdev framework */ | 339 | /* add clock to arm clockdev framework */ |
@@ -236,56 +341,142 @@ void clk_register(struct clk_lookup *cl) | |||
236 | } | 341 | } |
237 | 342 | ||
238 | /** | 343 | /** |
239 | * propagate_rate - recalculate and propagate all clocks in list head | 344 | * propagate_rate - recalculate and propagate all clocks to children |
345 | * @pclk: parent clock required to be propogated | ||
346 | * @on_init: flag for enabling clocks which are ENABLED_ON_INIT. | ||
240 | * | 347 | * |
241 | * Recalculates all root clocks in list head, which if the clock's .recalc is | 348 | * Recalculates all children clocks |
242 | * set correctly, should also propagate their rates. | ||
243 | */ | 349 | */ |
244 | static void propagate_rate(struct list_head *lhead) | 350 | void propagate_rate(struct clk *pclk, int on_init) |
245 | { | 351 | { |
246 | struct clk *clkp, *_temp; | 352 | struct clk *clk, *_temp; |
353 | int ret = 0; | ||
354 | |||
355 | list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) { | ||
356 | if (clk->recalc) { | ||
357 | ret = clk->recalc(clk); | ||
358 | /* | ||
359 | * recalc will return error if clk out is not programmed | ||
360 | * In this case configure default rate. | ||
361 | */ | ||
362 | if (ret && clk->set_rate) | ||
363 | clk->set_rate(clk, 0); | ||
364 | } | ||
365 | propagate_rate(clk, on_init); | ||
366 | |||
367 | if (!on_init) | ||
368 | continue; | ||
247 | 369 | ||
248 | list_for_each_entry_safe(clkp, _temp, lhead, sibling) { | 370 | /* Enable clks enabled on init, in software view */ |
249 | if (clkp->recalc) | 371 | if (clk->flags & ENABLED_ON_INIT) |
250 | clkp->recalc(clkp); | 372 | do_clk_enable(clk); |
251 | propagate_rate(&clkp->children); | ||
252 | } | 373 | } |
253 | } | 374 | } |
254 | 375 | ||
255 | /* returns current programmed clocks clock info structure */ | 376 | /** |
256 | static struct pclk_info *pclk_info_get(struct clk *clk) | 377 | * round_rate_index - return closest programmable rate index in rate_config tbl |
378 | * @clk: ptr to clock structure | ||
379 | * @drate: desired rate | ||
380 | * @rate: final rate will be returned in this variable only. | ||
381 | * | ||
382 | * Finds index in rate_config for highest clk rate which is less than | ||
383 | * requested rate. If there is no clk rate lesser than requested rate then | ||
384 | * -EINVAL is returned. This routine assumes that rate_config is written | ||
385 | * in incrementing order of clk rates. | ||
386 | * If drate passed is zero then default rate is programmed. | ||
387 | */ | ||
388 | static int | ||
389 | round_rate_index(struct clk *clk, unsigned long drate, unsigned long *rate) | ||
257 | { | 390 | { |
258 | unsigned int mask, i; | 391 | unsigned long tmp = 0, prev_rate = 0; |
259 | unsigned long flags; | 392 | int index; |
260 | struct pclk_info *info = NULL; | ||
261 | 393 | ||
262 | spin_lock_irqsave(&clocks_lock, flags); | 394 | if (!clk->calc_rate) |
263 | mask = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift) | 395 | return -EFAULT; |
264 | & clk->pclk_sel->pclk_sel_mask; | ||
265 | 396 | ||
266 | for (i = 0; i < clk->pclk_sel->pclk_count; i++) { | 397 | if (!drate) |
267 | if (clk->pclk_sel->pclk_info[i].pclk_mask == mask) | 398 | return -EINVAL; |
268 | info = &clk->pclk_sel->pclk_info[i]; | 399 | |
400 | /* | ||
401 | * This loops ends on two conditions: | ||
402 | * - as soon as clk is found with rate greater than requested rate. | ||
403 | * - if all clks in rate_config are smaller than requested rate. | ||
404 | */ | ||
405 | for (index = 0; index < clk->rate_config.count; index++) { | ||
406 | prev_rate = tmp; | ||
407 | tmp = clk->calc_rate(clk, index); | ||
408 | if (drate < tmp) { | ||
409 | index--; | ||
410 | break; | ||
411 | } | ||
269 | } | 412 | } |
270 | spin_unlock_irqrestore(&clocks_lock, flags); | 413 | /* return if can't find suitable clock */ |
414 | if (index < 0) { | ||
415 | index = -EINVAL; | ||
416 | *rate = 0; | ||
417 | } else if (index == clk->rate_config.count) { | ||
418 | /* program with highest clk rate possible */ | ||
419 | index = clk->rate_config.count - 1; | ||
420 | *rate = tmp; | ||
421 | } else | ||
422 | *rate = prev_rate; | ||
271 | 423 | ||
272 | return info; | 424 | return index; |
273 | } | 425 | } |
274 | 426 | ||
275 | /* | 427 | /** |
276 | * Set pclk as cclk's parent and add clock sibling node to current parents | 428 | * clk_round_rate - adjust a rate to the exact rate a clock can provide |
277 | * children list | 429 | * @clk: clock source |
430 | * @rate: desired clock rate in Hz | ||
431 | * | ||
432 | * Returns rounded clock rate in Hz, or negative errno. | ||
278 | */ | 433 | */ |
279 | static void change_parent(struct clk *cclk, struct clk *pclk) | 434 | long clk_round_rate(struct clk *clk, unsigned long drate) |
280 | { | 435 | { |
281 | unsigned long flags; | 436 | long rate = 0; |
437 | int index; | ||
438 | |||
439 | /* | ||
440 | * propagate call to parent who supports calc_rate. Similar approach is | ||
441 | * used in clk_set_rate. | ||
442 | */ | ||
443 | if (!clk->calc_rate) { | ||
444 | u32 mult; | ||
445 | if (!clk->pclk) | ||
446 | return clk->rate; | ||
447 | |||
448 | mult = clk->div_factor ? clk->div_factor : 1; | ||
449 | return clk_round_rate(clk->pclk, mult * drate) / mult; | ||
450 | } | ||
282 | 451 | ||
283 | spin_lock_irqsave(&clocks_lock, flags); | 452 | index = round_rate_index(clk, drate, &rate); |
284 | list_del(&cclk->sibling); | 453 | if (index >= 0) |
285 | list_add(&cclk->sibling, &pclk->children); | 454 | return rate; |
455 | else | ||
456 | return index; | ||
457 | } | ||
458 | EXPORT_SYMBOL(clk_round_rate); | ||
286 | 459 | ||
287 | cclk->pclk = pclk; | 460 | /*All below functions are called with lock held */ |
288 | spin_unlock_irqrestore(&clocks_lock, flags); | 461 | |
462 | /* | ||
463 | * Calculates pll clk rate for specific value of mode, m, n and p | ||
464 | * | ||
465 | * In normal mode | ||
466 | * rate = (2 * M[15:8] * Fin)/(N * 2^P) | ||
467 | * | ||
468 | * In Dithered mode | ||
469 | * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P) | ||
470 | */ | ||
471 | unsigned long pll_calc_rate(struct clk *clk, int index) | ||
472 | { | ||
473 | unsigned long rate = clk->pclk->rate; | ||
474 | struct pll_rate_tbl *tbls = clk->rate_config.tbls; | ||
475 | unsigned int mode; | ||
476 | |||
477 | mode = tbls[index].mode ? 256 : 1; | ||
478 | return (((2 * rate / 10000) * tbls[index].m) / | ||
479 | (mode * tbls[index].n * (1 << tbls[index].p))) * 10000; | ||
289 | } | 480 | } |
290 | 481 | ||
291 | /* | 482 | /* |
@@ -297,13 +488,11 @@ static void change_parent(struct clk *cclk, struct clk *pclk) | |||
297 | * In Dithered mode | 488 | * In Dithered mode |
298 | * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P) | 489 | * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P) |
299 | */ | 490 | */ |
300 | void pll_clk_recalc(struct clk *clk) | 491 | int pll_clk_recalc(struct clk *clk) |
301 | { | 492 | { |
302 | struct pll_clk_config *config = clk->private_data; | 493 | struct pll_clk_config *config = clk->private_data; |
303 | unsigned int num = 2, den = 0, val, mode = 0; | 494 | unsigned int num = 2, den = 0, val, mode = 0; |
304 | unsigned long flags; | ||
305 | 495 | ||
306 | spin_lock_irqsave(&clocks_lock, flags); | ||
307 | mode = (readl(config->mode_reg) >> config->masks->mode_shift) & | 496 | mode = (readl(config->mode_reg) >> config->masks->mode_shift) & |
308 | config->masks->mode_mask; | 497 | config->masks->mode_mask; |
309 | 498 | ||
@@ -325,22 +514,120 @@ void pll_clk_recalc(struct clk *clk) | |||
325 | den *= 256; | 514 | den *= 256; |
326 | } | 515 | } |
327 | 516 | ||
517 | if (!den) | ||
518 | return -EINVAL; | ||
519 | |||
328 | clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000; | 520 | clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000; |
329 | spin_unlock_irqrestore(&clocks_lock, flags); | 521 | return 0; |
522 | } | ||
523 | |||
524 | /* | ||
525 | * Configures new clock rate of pll | ||
526 | */ | ||
527 | int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate) | ||
528 | { | ||
529 | struct pll_rate_tbl *tbls = clk->rate_config.tbls; | ||
530 | struct pll_clk_config *config = clk->private_data; | ||
531 | unsigned long val, rate; | ||
532 | int i; | ||
533 | |||
534 | i = round_rate_index(clk, desired_rate, &rate); | ||
535 | if (i < 0) | ||
536 | return i; | ||
537 | |||
538 | val = readl(config->mode_reg) & | ||
539 | ~(config->masks->mode_mask << config->masks->mode_shift); | ||
540 | val |= (tbls[i].mode & config->masks->mode_mask) << | ||
541 | config->masks->mode_shift; | ||
542 | writel(val, config->mode_reg); | ||
543 | |||
544 | val = readl(config->cfg_reg) & | ||
545 | ~(config->masks->div_p_mask << config->masks->div_p_shift); | ||
546 | val |= (tbls[i].p & config->masks->div_p_mask) << | ||
547 | config->masks->div_p_shift; | ||
548 | val &= ~(config->masks->div_n_mask << config->masks->div_n_shift); | ||
549 | val |= (tbls[i].n & config->masks->div_n_mask) << | ||
550 | config->masks->div_n_shift; | ||
551 | val &= ~(config->masks->dith_fdbk_m_mask << | ||
552 | config->masks->dith_fdbk_m_shift); | ||
553 | if (tbls[i].mode) | ||
554 | val |= (tbls[i].m & config->masks->dith_fdbk_m_mask) << | ||
555 | config->masks->dith_fdbk_m_shift; | ||
556 | else | ||
557 | val |= (tbls[i].m & config->masks->norm_fdbk_m_mask) << | ||
558 | config->masks->norm_fdbk_m_shift; | ||
559 | |||
560 | writel(val, config->cfg_reg); | ||
561 | |||
562 | clk->rate = rate; | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | /* | ||
568 | * Calculates ahb, apb clk rate for specific value of div | ||
569 | */ | ||
570 | unsigned long bus_calc_rate(struct clk *clk, int index) | ||
571 | { | ||
572 | unsigned long rate = clk->pclk->rate; | ||
573 | struct bus_rate_tbl *tbls = clk->rate_config.tbls; | ||
574 | |||
575 | return rate / (tbls[index].div + 1); | ||
330 | } | 576 | } |
331 | 577 | ||
332 | /* calculates current programmed rate of ahb or apb bus */ | 578 | /* calculates current programmed rate of ahb or apb bus */ |
333 | void bus_clk_recalc(struct clk *clk) | 579 | int bus_clk_recalc(struct clk *clk) |
334 | { | 580 | { |
335 | struct bus_clk_config *config = clk->private_data; | 581 | struct bus_clk_config *config = clk->private_data; |
336 | unsigned int div; | 582 | unsigned int div; |
337 | unsigned long flags; | ||
338 | 583 | ||
339 | spin_lock_irqsave(&clocks_lock, flags); | ||
340 | div = ((readl(config->reg) >> config->masks->shift) & | 584 | div = ((readl(config->reg) >> config->masks->shift) & |
341 | config->masks->mask) + 1; | 585 | config->masks->mask) + 1; |
586 | |||
587 | if (!div) | ||
588 | return -EINVAL; | ||
589 | |||
342 | clk->rate = (unsigned long)clk->pclk->rate / div; | 590 | clk->rate = (unsigned long)clk->pclk->rate / div; |
343 | spin_unlock_irqrestore(&clocks_lock, flags); | 591 | return 0; |
592 | } | ||
593 | |||
594 | /* Configures new clock rate of AHB OR APB bus */ | ||
595 | int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate) | ||
596 | { | ||
597 | struct bus_rate_tbl *tbls = clk->rate_config.tbls; | ||
598 | struct bus_clk_config *config = clk->private_data; | ||
599 | unsigned long val, rate; | ||
600 | int i; | ||
601 | |||
602 | i = round_rate_index(clk, desired_rate, &rate); | ||
603 | if (i < 0) | ||
604 | return i; | ||
605 | |||
606 | val = readl(config->reg) & | ||
607 | ~(config->masks->mask << config->masks->shift); | ||
608 | val |= (tbls[i].div & config->masks->mask) << config->masks->shift; | ||
609 | writel(val, config->reg); | ||
610 | |||
611 | clk->rate = rate; | ||
612 | |||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * gives rate for different values of eq, x and y | ||
618 | * | ||
619 | * Fout from synthesizer can be given from two equations: | ||
620 | * Fout1 = (Fin * X/Y)/2 EQ1 | ||
621 | * Fout2 = Fin * X/Y EQ2 | ||
622 | */ | ||
623 | unsigned long aux_calc_rate(struct clk *clk, int index) | ||
624 | { | ||
625 | unsigned long rate = clk->pclk->rate; | ||
626 | struct aux_rate_tbl *tbls = clk->rate_config.tbls; | ||
627 | u8 eq = tbls[index].eq ? 1 : 2; | ||
628 | |||
629 | return (((rate/10000) * tbls[index].xscale) / | ||
630 | (tbls[index].yscale * eq)) * 10000; | ||
344 | } | 631 | } |
345 | 632 | ||
346 | /* | 633 | /* |
@@ -353,47 +640,76 @@ void bus_clk_recalc(struct clk *clk) | |||
353 | * | 640 | * |
354 | * Selection of eqn 1 or 2 is programmed in register | 641 | * Selection of eqn 1 or 2 is programmed in register |
355 | */ | 642 | */ |
356 | void aux_clk_recalc(struct clk *clk) | 643 | int aux_clk_recalc(struct clk *clk) |
357 | { | 644 | { |
358 | struct aux_clk_config *config = clk->private_data; | 645 | struct aux_clk_config *config = clk->private_data; |
359 | struct pclk_info *pclk_info = NULL; | ||
360 | unsigned int num = 1, den = 1, val, eqn; | 646 | unsigned int num = 1, den = 1, val, eqn; |
361 | unsigned long flags; | ||
362 | 647 | ||
363 | /* get current programmed parent */ | 648 | val = readl(config->synth_reg); |
364 | pclk_info = pclk_info_get(clk); | ||
365 | if (!pclk_info) { | ||
366 | spin_lock_irqsave(&clocks_lock, flags); | ||
367 | clk->pclk = NULL; | ||
368 | clk->rate = 0; | ||
369 | spin_unlock_irqrestore(&clocks_lock, flags); | ||
370 | return; | ||
371 | } | ||
372 | 649 | ||
373 | change_parent(clk, pclk_info->pclk); | 650 | eqn = (val >> config->masks->eq_sel_shift) & |
651 | config->masks->eq_sel_mask; | ||
652 | if (eqn == config->masks->eq1_mask) | ||
653 | den *= 2; | ||
374 | 654 | ||
375 | spin_lock_irqsave(&clocks_lock, flags); | 655 | /* calculate numerator */ |
376 | if (pclk_info->scalable) { | 656 | num = (val >> config->masks->xscale_sel_shift) & |
377 | val = readl(config->synth_reg); | 657 | config->masks->xscale_sel_mask; |
378 | |||
379 | eqn = (val >> config->masks->eq_sel_shift) & | ||
380 | config->masks->eq_sel_mask; | ||
381 | if (eqn == config->masks->eq1_mask) | ||
382 | den *= 2; | ||
383 | |||
384 | /* calculate numerator */ | ||
385 | num = (val >> config->masks->xscale_sel_shift) & | ||
386 | config->masks->xscale_sel_mask; | ||
387 | |||
388 | /* calculate denominator */ | ||
389 | den *= (val >> config->masks->yscale_sel_shift) & | ||
390 | config->masks->yscale_sel_mask; | ||
391 | val = (((clk->pclk->rate/10000) * num) / den) * 10000; | ||
392 | } else | ||
393 | val = clk->pclk->rate; | ||
394 | 658 | ||
395 | clk->rate = val; | 659 | /* calculate denominator */ |
396 | spin_unlock_irqrestore(&clocks_lock, flags); | 660 | den *= (val >> config->masks->yscale_sel_shift) & |
661 | config->masks->yscale_sel_mask; | ||
662 | |||
663 | if (!den) | ||
664 | return -EINVAL; | ||
665 | |||
666 | clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000; | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | /* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/ | ||
671 | int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate) | ||
672 | { | ||
673 | struct aux_rate_tbl *tbls = clk->rate_config.tbls; | ||
674 | struct aux_clk_config *config = clk->private_data; | ||
675 | unsigned long val, rate; | ||
676 | int i; | ||
677 | |||
678 | i = round_rate_index(clk, desired_rate, &rate); | ||
679 | if (i < 0) | ||
680 | return i; | ||
681 | |||
682 | val = readl(config->synth_reg) & | ||
683 | ~(config->masks->eq_sel_mask << config->masks->eq_sel_shift); | ||
684 | val |= (tbls[i].eq & config->masks->eq_sel_mask) << | ||
685 | config->masks->eq_sel_shift; | ||
686 | val &= ~(config->masks->xscale_sel_mask << | ||
687 | config->masks->xscale_sel_shift); | ||
688 | val |= (tbls[i].xscale & config->masks->xscale_sel_mask) << | ||
689 | config->masks->xscale_sel_shift; | ||
690 | val &= ~(config->masks->yscale_sel_mask << | ||
691 | config->masks->yscale_sel_shift); | ||
692 | val |= (tbls[i].yscale & config->masks->yscale_sel_mask) << | ||
693 | config->masks->yscale_sel_shift; | ||
694 | writel(val, config->synth_reg); | ||
695 | |||
696 | clk->rate = rate; | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | /* | ||
702 | * Calculates gpt clk rate for different values of mscale and nscale | ||
703 | * | ||
704 | * Fout= Fin/((2 ^ (N+1)) * (M+1)) | ||
705 | */ | ||
706 | unsigned long gpt_calc_rate(struct clk *clk, int index) | ||
707 | { | ||
708 | unsigned long rate = clk->pclk->rate; | ||
709 | struct gpt_rate_tbl *tbls = clk->rate_config.tbls; | ||
710 | |||
711 | return rate / ((1 << (tbls[index].nscale + 1)) * | ||
712 | (tbls[index].mscale + 1)); | ||
397 | } | 713 | } |
398 | 714 | ||
399 | /* | 715 | /* |
@@ -401,49 +717,142 @@ void aux_clk_recalc(struct clk *clk) | |||
401 | * Fout from synthesizer can be given from below equations: | 717 | * Fout from synthesizer can be given from below equations: |
402 | * Fout= Fin/((2 ^ (N+1)) * (M+1)) | 718 | * Fout= Fin/((2 ^ (N+1)) * (M+1)) |
403 | */ | 719 | */ |
404 | void gpt_clk_recalc(struct clk *clk) | 720 | int gpt_clk_recalc(struct clk *clk) |
405 | { | 721 | { |
406 | struct gpt_clk_config *config = clk->private_data; | 722 | struct gpt_clk_config *config = clk->private_data; |
407 | struct pclk_info *pclk_info = NULL; | ||
408 | unsigned int div = 1, val; | 723 | unsigned int div = 1, val; |
409 | unsigned long flags; | ||
410 | 724 | ||
411 | pclk_info = pclk_info_get(clk); | 725 | val = readl(config->synth_reg); |
412 | if (!pclk_info) { | 726 | div += (val >> config->masks->mscale_sel_shift) & |
413 | spin_lock_irqsave(&clocks_lock, flags); | 727 | config->masks->mscale_sel_mask; |
414 | clk->pclk = NULL; | 728 | div *= 1 << (((val >> config->masks->nscale_sel_shift) & |
415 | clk->rate = 0; | 729 | config->masks->nscale_sel_mask) + 1); |
416 | spin_unlock_irqrestore(&clocks_lock, flags); | ||
417 | return; | ||
418 | } | ||
419 | 730 | ||
420 | change_parent(clk, pclk_info->pclk); | 731 | if (!div) |
421 | 732 | return -EINVAL; | |
422 | spin_lock_irqsave(&clocks_lock, flags); | ||
423 | if (pclk_info->scalable) { | ||
424 | val = readl(config->synth_reg); | ||
425 | div += (val >> config->masks->mscale_sel_shift) & | ||
426 | config->masks->mscale_sel_mask; | ||
427 | div *= 1 << (((val >> config->masks->nscale_sel_shift) & | ||
428 | config->masks->nscale_sel_mask) + 1); | ||
429 | } | ||
430 | 733 | ||
431 | clk->rate = (unsigned long)clk->pclk->rate / div; | 734 | clk->rate = (unsigned long)clk->pclk->rate / div; |
432 | spin_unlock_irqrestore(&clocks_lock, flags); | 735 | return 0; |
736 | } | ||
737 | |||
738 | /* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/ | ||
739 | int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate) | ||
740 | { | ||
741 | struct gpt_rate_tbl *tbls = clk->rate_config.tbls; | ||
742 | struct gpt_clk_config *config = clk->private_data; | ||
743 | unsigned long val, rate; | ||
744 | int i; | ||
745 | |||
746 | i = round_rate_index(clk, desired_rate, &rate); | ||
747 | if (i < 0) | ||
748 | return i; | ||
749 | |||
750 | val = readl(config->synth_reg) & ~(config->masks->mscale_sel_mask << | ||
751 | config->masks->mscale_sel_shift); | ||
752 | val |= (tbls[i].mscale & config->masks->mscale_sel_mask) << | ||
753 | config->masks->mscale_sel_shift; | ||
754 | val &= ~(config->masks->nscale_sel_mask << | ||
755 | config->masks->nscale_sel_shift); | ||
756 | val |= (tbls[i].nscale & config->masks->nscale_sel_mask) << | ||
757 | config->masks->nscale_sel_shift; | ||
758 | writel(val, config->synth_reg); | ||
759 | |||
760 | clk->rate = rate; | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | /* | ||
766 | * Calculates clcd clk rate for different values of div | ||
767 | * | ||
768 | * Fout from synthesizer can be given from below equation: | ||
769 | * Fout= Fin/2*div (division factor) | ||
770 | * div is 17 bits:- | ||
771 | * 0-13 (fractional part) | ||
772 | * 14-16 (integer part) | ||
773 | * To calculate Fout we left shift val by 14 bits and divide Fin by | ||
774 | * complete div (including fractional part) and then right shift the | ||
775 | * result by 14 places. | ||
776 | */ | ||
777 | unsigned long clcd_calc_rate(struct clk *clk, int index) | ||
778 | { | ||
779 | unsigned long rate = clk->pclk->rate; | ||
780 | struct clcd_rate_tbl *tbls = clk->rate_config.tbls; | ||
781 | |||
782 | rate /= 1000; | ||
783 | rate <<= 12; | ||
784 | rate /= (2 * tbls[index].div); | ||
785 | rate >>= 12; | ||
786 | rate *= 1000; | ||
787 | |||
788 | return rate; | ||
789 | } | ||
790 | |||
791 | /* | ||
792 | * calculates current programmed rate of clcd synthesizer | ||
793 | * Fout from synthesizer can be given from below equation: | ||
794 | * Fout= Fin/2*div (division factor) | ||
795 | * div is 17 bits:- | ||
796 | * 0-13 (fractional part) | ||
797 | * 14-16 (integer part) | ||
798 | * To calculate Fout we left shift val by 14 bits and divide Fin by | ||
799 | * complete div (including fractional part) and then right shift the | ||
800 | * result by 14 places. | ||
801 | */ | ||
802 | int clcd_clk_recalc(struct clk *clk) | ||
803 | { | ||
804 | struct clcd_clk_config *config = clk->private_data; | ||
805 | unsigned int div = 1; | ||
806 | unsigned long prate; | ||
807 | unsigned int val; | ||
808 | |||
809 | val = readl(config->synth_reg); | ||
810 | div = (val >> config->masks->div_factor_shift) & | ||
811 | config->masks->div_factor_mask; | ||
812 | |||
813 | if (!div) | ||
814 | return -EINVAL; | ||
815 | |||
816 | prate = clk->pclk->rate / 1000; /* first level division, make it KHz */ | ||
817 | |||
818 | clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12; | ||
819 | clk->rate *= 1000; | ||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | /* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/ | ||
824 | int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate) | ||
825 | { | ||
826 | struct clcd_rate_tbl *tbls = clk->rate_config.tbls; | ||
827 | struct clcd_clk_config *config = clk->private_data; | ||
828 | unsigned long val, rate; | ||
829 | int i; | ||
830 | |||
831 | i = round_rate_index(clk, desired_rate, &rate); | ||
832 | if (i < 0) | ||
833 | return i; | ||
834 | |||
835 | val = readl(config->synth_reg) & ~(config->masks->div_factor_mask << | ||
836 | config->masks->div_factor_shift); | ||
837 | val |= (tbls[i].div & config->masks->div_factor_mask) << | ||
838 | config->masks->div_factor_shift; | ||
839 | writel(val, config->synth_reg); | ||
840 | |||
841 | clk->rate = rate; | ||
842 | |||
843 | return 0; | ||
433 | } | 844 | } |
434 | 845 | ||
435 | /* | 846 | /* |
436 | * Used for clocks that always have value as the parent clock divided by a | 847 | * Used for clocks that always have value as the parent clock divided by a |
437 | * fixed divisor | 848 | * fixed divisor |
438 | */ | 849 | */ |
439 | void follow_parent(struct clk *clk) | 850 | int follow_parent(struct clk *clk) |
440 | { | 851 | { |
441 | unsigned long flags; | ||
442 | unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor; | 852 | unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor; |
443 | 853 | ||
444 | spin_lock_irqsave(&clocks_lock, flags); | ||
445 | clk->rate = clk->pclk->rate/div_factor; | 854 | clk->rate = clk->pclk->rate/div_factor; |
446 | spin_unlock_irqrestore(&clocks_lock, flags); | 855 | return 0; |
447 | } | 856 | } |
448 | 857 | ||
449 | /** | 858 | /** |
@@ -454,5 +863,25 @@ void follow_parent(struct clk *clk) | |||
454 | */ | 863 | */ |
455 | void recalc_root_clocks(void) | 864 | void recalc_root_clocks(void) |
456 | { | 865 | { |
457 | propagate_rate(&root_clks); | 866 | struct clk *pclk; |
867 | unsigned long flags; | ||
868 | int ret = 0; | ||
869 | |||
870 | spin_lock_irqsave(&clocks_lock, flags); | ||
871 | list_for_each_entry(pclk, &root_clks, sibling) { | ||
872 | if (pclk->recalc) { | ||
873 | ret = pclk->recalc(pclk); | ||
874 | /* | ||
875 | * recalc will return error if clk out is not programmed | ||
876 | * In this case configure default clock. | ||
877 | */ | ||
878 | if (ret && pclk->set_rate) | ||
879 | pclk->set_rate(pclk, 0); | ||
880 | } | ||
881 | propagate_rate(pclk, 1); | ||
882 | /* Enable clks enabled on init, in software view */ | ||
883 | if (pclk->flags & ENABLED_ON_INIT) | ||
884 | do_clk_enable(pclk); | ||
885 | } | ||
886 | spin_unlock_irqrestore(&clocks_lock, flags); | ||
458 | } | 887 | } |
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h index 863d9e983927..5a601d830971 100644 --- a/arch/arm/plat-spear/include/plat/clock.h +++ b/arch/arm/plat-spear/include/plat/clock.h | |||
@@ -21,6 +21,7 @@ | |||
21 | /* clk structure flags */ | 21 | /* clk structure flags */ |
22 | #define ALWAYS_ENABLED (1 << 0) /* clock always enabled */ | 22 | #define ALWAYS_ENABLED (1 << 0) /* clock always enabled */ |
23 | #define RESET_TO_ENABLE (1 << 1) /* reset register bit to enable clk */ | 23 | #define RESET_TO_ENABLE (1 << 1) /* reset register bit to enable clk */ |
24 | #define ENABLED_ON_INIT (1 << 2) /* clocks enabled at init */ | ||
24 | 25 | ||
25 | /** | 26 | /** |
26 | * struct clkops - clock operations | 27 | * struct clkops - clock operations |
@@ -35,13 +36,11 @@ struct clkops { | |||
35 | /** | 36 | /** |
36 | * struct pclk_info - parents info | 37 | * struct pclk_info - parents info |
37 | * @pclk: pointer to parent clk | 38 | * @pclk: pointer to parent clk |
38 | * @pclk_mask: value to be written for selecting this parent | 39 | * @pclk_val: value to be written for selecting this parent |
39 | * @scalable: Is parent scalable (1 - YES, 0 - NO) | ||
40 | */ | 40 | */ |
41 | struct pclk_info { | 41 | struct pclk_info { |
42 | struct clk *pclk; | 42 | struct clk *pclk; |
43 | u8 pclk_mask; | 43 | u8 pclk_val; |
44 | u8 scalable; | ||
45 | }; | 44 | }; |
46 | 45 | ||
47 | /** | 46 | /** |
@@ -59,6 +58,18 @@ struct pclk_sel { | |||
59 | }; | 58 | }; |
60 | 59 | ||
61 | /** | 60 | /** |
61 | * struct rate_config - clk rate configurations | ||
62 | * @tbls: array of device specific clk rate tables, in ascending order of rates | ||
63 | * @count: size of tbls array | ||
64 | * @default_index: default setting when originally disabled | ||
65 | */ | ||
66 | struct rate_config { | ||
67 | void *tbls; | ||
68 | u8 count; | ||
69 | u8 default_index; | ||
70 | }; | ||
71 | |||
72 | /** | ||
62 | * struct clk - clock structure | 73 | * struct clk - clock structure |
63 | * @usage_count: num of users who enabled this clock | 74 | * @usage_count: num of users who enabled this clock |
64 | * @flags: flags for clock properties | 75 | * @flags: flags for clock properties |
@@ -67,7 +78,10 @@ struct pclk_sel { | |||
67 | * @en_reg_bit: clk enable/disable bit | 78 | * @en_reg_bit: clk enable/disable bit |
68 | * @ops: clk enable/disable ops - generic_clkops selected if NULL | 79 | * @ops: clk enable/disable ops - generic_clkops selected if NULL |
69 | * @recalc: pointer to clock rate recalculate function | 80 | * @recalc: pointer to clock rate recalculate function |
70 | * @div_factor: division factor to parent clock. Only for recalc = follow_parent | 81 | * @set_rate: pointer to clock set rate function |
82 | * @calc_rate: pointer to clock get rate function for index | ||
83 | * @rate_config: rate configuration information, used by set_rate | ||
84 | * @div_factor: division factor to parent clock. | ||
71 | * @pclk: current parent clk | 85 | * @pclk: current parent clk |
72 | * @pclk_sel: pointer to parent selection structure | 86 | * @pclk_sel: pointer to parent selection structure |
73 | * @pclk_sel_shift: register shift for selecting parent of this clock | 87 | * @pclk_sel_shift: register shift for selecting parent of this clock |
@@ -82,7 +96,10 @@ struct clk { | |||
82 | void __iomem *en_reg; | 96 | void __iomem *en_reg; |
83 | u8 en_reg_bit; | 97 | u8 en_reg_bit; |
84 | const struct clkops *ops; | 98 | const struct clkops *ops; |
85 | void (*recalc) (struct clk *); | 99 | int (*recalc) (struct clk *); |
100 | int (*set_rate) (struct clk *, unsigned long rate); | ||
101 | unsigned long (*calc_rate)(struct clk *, int index); | ||
102 | struct rate_config rate_config; | ||
86 | unsigned int div_factor; | 103 | unsigned int div_factor; |
87 | 104 | ||
88 | struct clk *pclk; | 105 | struct clk *pclk; |
@@ -115,6 +132,14 @@ struct pll_clk_config { | |||
115 | struct pll_clk_masks *masks; | 132 | struct pll_clk_masks *masks; |
116 | }; | 133 | }; |
117 | 134 | ||
135 | /* pll clk rate config structure */ | ||
136 | struct pll_rate_tbl { | ||
137 | u8 mode; | ||
138 | u16 m; | ||
139 | u8 n; | ||
140 | u8 p; | ||
141 | }; | ||
142 | |||
118 | /* ahb and apb bus configuration structure */ | 143 | /* ahb and apb bus configuration structure */ |
119 | struct bus_clk_masks { | 144 | struct bus_clk_masks { |
120 | u32 mask; | 145 | u32 mask; |
@@ -126,6 +151,11 @@ struct bus_clk_config { | |||
126 | struct bus_clk_masks *masks; | 151 | struct bus_clk_masks *masks; |
127 | }; | 152 | }; |
128 | 153 | ||
154 | /* ahb and apb clk bus rate config structure */ | ||
155 | struct bus_rate_tbl { | ||
156 | u8 div; | ||
157 | }; | ||
158 | |||
129 | /* Aux clk configuration structure: applicable to UART and FIRDA */ | 159 | /* Aux clk configuration structure: applicable to UART and FIRDA */ |
130 | struct aux_clk_masks { | 160 | struct aux_clk_masks { |
131 | u32 eq_sel_mask; | 161 | u32 eq_sel_mask; |
@@ -143,6 +173,13 @@ struct aux_clk_config { | |||
143 | struct aux_clk_masks *masks; | 173 | struct aux_clk_masks *masks; |
144 | }; | 174 | }; |
145 | 175 | ||
176 | /* aux clk rate config structure */ | ||
177 | struct aux_rate_tbl { | ||
178 | u16 xscale; | ||
179 | u16 yscale; | ||
180 | u8 eq; | ||
181 | }; | ||
182 | |||
146 | /* GPT clk configuration structure */ | 183 | /* GPT clk configuration structure */ |
147 | struct gpt_clk_masks { | 184 | struct gpt_clk_masks { |
148 | u32 mscale_sel_mask; | 185 | u32 mscale_sel_mask; |
@@ -156,15 +193,48 @@ struct gpt_clk_config { | |||
156 | struct gpt_clk_masks *masks; | 193 | struct gpt_clk_masks *masks; |
157 | }; | 194 | }; |
158 | 195 | ||
196 | /* gpt clk rate config structure */ | ||
197 | struct gpt_rate_tbl { | ||
198 | u16 mscale; | ||
199 | u16 nscale; | ||
200 | }; | ||
201 | |||
202 | /* clcd clk configuration structure */ | ||
203 | struct clcd_synth_masks { | ||
204 | u32 div_factor_mask; | ||
205 | u32 div_factor_shift; | ||
206 | }; | ||
207 | |||
208 | struct clcd_clk_config { | ||
209 | void __iomem *synth_reg; | ||
210 | struct clcd_synth_masks *masks; | ||
211 | }; | ||
212 | |||
213 | /* clcd clk rate config structure */ | ||
214 | struct clcd_rate_tbl { | ||
215 | u16 div; | ||
216 | }; | ||
217 | |||
159 | /* platform specific clock functions */ | 218 | /* platform specific clock functions */ |
160 | void clk_register(struct clk_lookup *cl); | 219 | void clk_register(struct clk_lookup *cl); |
161 | void recalc_root_clocks(void); | 220 | void recalc_root_clocks(void); |
162 | 221 | ||
163 | /* clock recalc functions */ | 222 | /* clock recalc & set rate functions */ |
164 | void follow_parent(struct clk *clk); | 223 | int follow_parent(struct clk *clk); |
165 | void pll_clk_recalc(struct clk *clk); | 224 | unsigned long pll_calc_rate(struct clk *clk, int index); |
166 | void bus_clk_recalc(struct clk *clk); | 225 | int pll_clk_recalc(struct clk *clk); |
167 | void gpt_clk_recalc(struct clk *clk); | 226 | int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate); |
168 | void aux_clk_recalc(struct clk *clk); | 227 | unsigned long bus_calc_rate(struct clk *clk, int index); |
228 | int bus_clk_recalc(struct clk *clk); | ||
229 | int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate); | ||
230 | unsigned long gpt_calc_rate(struct clk *clk, int index); | ||
231 | int gpt_clk_recalc(struct clk *clk); | ||
232 | int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate); | ||
233 | unsigned long aux_calc_rate(struct clk *clk, int index); | ||
234 | int aux_clk_recalc(struct clk *clk); | ||
235 | int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate); | ||
236 | unsigned long clcd_calc_rate(struct clk *clk, int index); | ||
237 | int clcd_clk_recalc(struct clk *clk); | ||
238 | int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate); | ||
169 | 239 | ||
170 | #endif /* __PLAT_CLOCK_H */ | 240 | #endif /* __PLAT_CLOCK_H */ |