aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-spear/clock.c
diff options
context:
space:
mode:
authorviresh kumar <viresh.kumar@st.com>2011-02-16 01:40:31 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-03-09 04:49:45 -0500
commitcf285434ac0880f94bf4afdd90b06a4655f56570 (patch)
tree6b7b0f6716c17147e45cca39d01f88570d368eb5 /arch/arm/plat-spear/clock.c
parent5c881d9ae9480171f01921585e1893863d7ab421 (diff)
ARM: 6679/1: SPEAr: make clk API functions more generic
- Add a dummy clk_set_rate() function. This is required for compilation of a few drivers. - Make functions in plat-spear/clock.c more generic over all SPEAr platforms. - Add div_factor in struct clk for clks with .recalc = follow_parent - Change type of register pointers to void __iomem * Reviewed-by: Stanley Miao <stanley.miao@windriver.com> Signed-off-by: Viresh Kumar <viresh.kumar@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/plat-spear/clock.c')
-rw-r--r--arch/arm/plat-spear/clock.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
index ee4f90e534d8..f1cf832e4e3b 100644
--- a/arch/arm/plat-spear/clock.c
+++ b/arch/arm/plat-spear/clock.c
@@ -17,7 +17,6 @@
17#include <linux/list.h> 17#include <linux/list.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <mach/misc_regs.h>
21#include <plat/clock.h> 20#include <plat/clock.h>
22 21
23static DEFINE_SPINLOCK(clocks_lock); 22static DEFINE_SPINLOCK(clocks_lock);
@@ -187,6 +186,20 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
187} 186}
188EXPORT_SYMBOL(clk_set_parent); 187EXPORT_SYMBOL(clk_set_parent);
189 188
189/**
190 * clk_set_rate - set the clock rate for a clock source
191 * @clk: clock source
192 * @rate: desired clock rate in Hz
193 *
194 * Returns success (0) or negative errno.
195 */
196int clk_set_rate(struct clk *clk, unsigned long rate)
197{
198 /* TODO */
199 return -EINVAL;
200}
201EXPORT_SYMBOL(clk_set_rate);
202
190/* registers clock in platform clock framework */ 203/* registers clock in platform clock framework */
191void clk_register(struct clk_lookup *cl) 204void clk_register(struct clk_lookup *cl)
192{ 205{
@@ -212,6 +225,7 @@ void clk_register(struct clk_lookup *cl)
212 list_add(&clk->sibling, &clk->pclk->children); 225 list_add(&clk->sibling, &clk->pclk->children);
213 } else { 226 } else {
214 /* add clocks with > 1 parent to 1st parent's children list */ 227 /* add clocks with > 1 parent to 1st parent's children list */
228 clk->pclk = clk->pclk_sel->pclk_info[0].pclk;
215 list_add(&clk->sibling, 229 list_add(&clk->sibling,
216 &clk->pclk_sel->pclk_info[0].pclk->children); 230 &clk->pclk_sel->pclk_info[0].pclk->children);
217 } 231 }
@@ -283,29 +297,31 @@ static void change_parent(struct clk *cclk, struct clk *pclk)
283 * In Dithered mode 297 * In Dithered mode
284 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P) 298 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
285 */ 299 */
286void pll1_clk_recalc(struct clk *clk) 300void pll_clk_recalc(struct clk *clk)
287{ 301{
288 struct pll_clk_config *config = clk->private_data; 302 struct pll_clk_config *config = clk->private_data;
289 unsigned int num = 2, den = 0, val, mode = 0; 303 unsigned int num = 2, den = 0, val, mode = 0;
290 unsigned long flags; 304 unsigned long flags;
291 305
292 spin_lock_irqsave(&clocks_lock, flags); 306 spin_lock_irqsave(&clocks_lock, flags);
293 mode = (readl(config->mode_reg) >> PLL_MODE_SHIFT) & 307 mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
294 PLL_MODE_MASK; 308 config->masks->mode_mask;
295 309
296 val = readl(config->cfg_reg); 310 val = readl(config->cfg_reg);
297 /* calculate denominator */ 311 /* calculate denominator */
298 den = (val >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK; 312 den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
299 den = 1 << den; 313 den = 1 << den;
300 den *= (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK; 314 den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
301 315
302 /* calculate numerator & denominator */ 316 /* calculate numerator & denominator */
303 if (!mode) { 317 if (!mode) {
304 /* Normal mode */ 318 /* Normal mode */
305 num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK; 319 num *= (val >> config->masks->norm_fdbk_m_shift) &
320 config->masks->norm_fdbk_m_mask;
306 } else { 321 } else {
307 /* Dithered mode */ 322 /* Dithered mode */
308 num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK; 323 num *= (val >> config->masks->dith_fdbk_m_shift) &
324 config->masks->dith_fdbk_m_mask;
309 den *= 256; 325 den *= 256;
310 } 326 }
311 327
@@ -321,7 +337,8 @@ void bus_clk_recalc(struct clk *clk)
321 unsigned long flags; 337 unsigned long flags;
322 338
323 spin_lock_irqsave(&clocks_lock, flags); 339 spin_lock_irqsave(&clocks_lock, flags);
324 div = ((readl(config->reg) >> config->shift) & config->mask) + 1; 340 div = ((readl(config->reg) >> config->masks->shift) &
341 config->masks->mask) + 1;
325 clk->rate = (unsigned long)clk->pclk->rate / div; 342 clk->rate = (unsigned long)clk->pclk->rate / div;
326 spin_unlock_irqrestore(&clocks_lock, flags); 343 spin_unlock_irqrestore(&clocks_lock, flags);
327} 344}
@@ -359,15 +376,18 @@ void aux_clk_recalc(struct clk *clk)
359 if (pclk_info->scalable) { 376 if (pclk_info->scalable) {
360 val = readl(config->synth_reg); 377 val = readl(config->synth_reg);
361 378
362 eqn = (val >> AUX_EQ_SEL_SHIFT) & AUX_EQ_SEL_MASK; 379 eqn = (val >> config->masks->eq_sel_shift) &
363 if (eqn == AUX_EQ1_SEL) 380 config->masks->eq_sel_mask;
381 if (eqn == config->masks->eq1_mask)
364 den *= 2; 382 den *= 2;
365 383
366 /* calculate numerator */ 384 /* calculate numerator */
367 num = (val >> AUX_XSCALE_SHIFT) & AUX_XSCALE_MASK; 385 num = (val >> config->masks->xscale_sel_shift) &
386 config->masks->xscale_sel_mask;
368 387
369 /* calculate denominator */ 388 /* calculate denominator */
370 den *= (val >> AUX_YSCALE_SHIFT) & AUX_YSCALE_MASK; 389 den *= (val >> config->masks->yscale_sel_shift) &
390 config->masks->yscale_sel_mask;
371 val = (((clk->pclk->rate/10000) * num) / den) * 10000; 391 val = (((clk->pclk->rate/10000) * num) / den) * 10000;
372 } else 392 } else
373 val = clk->pclk->rate; 393 val = clk->pclk->rate;
@@ -383,7 +403,7 @@ void aux_clk_recalc(struct clk *clk)
383 */ 403 */
384void gpt_clk_recalc(struct clk *clk) 404void gpt_clk_recalc(struct clk *clk)
385{ 405{
386 struct aux_clk_config *config = clk->private_data; 406 struct gpt_clk_config *config = clk->private_data;
387 struct pclk_info *pclk_info = NULL; 407 struct pclk_info *pclk_info = NULL;
388 unsigned int div = 1, val; 408 unsigned int div = 1, val;
389 unsigned long flags; 409 unsigned long flags;
@@ -402,8 +422,10 @@ void gpt_clk_recalc(struct clk *clk)
402 spin_lock_irqsave(&clocks_lock, flags); 422 spin_lock_irqsave(&clocks_lock, flags);
403 if (pclk_info->scalable) { 423 if (pclk_info->scalable) {
404 val = readl(config->synth_reg); 424 val = readl(config->synth_reg);
405 div += (val >> GPT_MSCALE_SHIFT) & GPT_MSCALE_MASK; 425 div += (val >> config->masks->mscale_sel_shift) &
406 div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1); 426 config->masks->mscale_sel_mask;
427 div *= 1 << (((val >> config->masks->nscale_sel_shift) &
428 config->masks->nscale_sel_mask) + 1);
407 } 429 }
408 430
409 clk->rate = (unsigned long)clk->pclk->rate / div; 431 clk->rate = (unsigned long)clk->pclk->rate / div;
@@ -411,15 +433,16 @@ void gpt_clk_recalc(struct clk *clk)
411} 433}
412 434
413/* 435/*
414 * Used for clocks that always have same value as the parent clock divided by a 436 * Used for clocks that always have value as the parent clock divided by a
415 * fixed divisor 437 * fixed divisor
416 */ 438 */
417void follow_parent(struct clk *clk) 439void follow_parent(struct clk *clk)
418{ 440{
419 unsigned long flags; 441 unsigned long flags;
442 unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
420 443
421 spin_lock_irqsave(&clocks_lock, flags); 444 spin_lock_irqsave(&clocks_lock, flags);
422 clk->rate = clk->pclk->rate; 445 clk->rate = clk->pclk->rate/div_factor;
423 spin_unlock_irqrestore(&clocks_lock, flags); 446 spin_unlock_irqrestore(&clocks_lock, flags);
424} 447}
425 448