Lines Matching +full:fixed +full:- +full:factor +full:- +full:clock
2 * arch/arm/plat-spear/clock.c
4 * Clock framework for SPEAr platform
22 #include <plat/clock.h>
39 if (!clk->en_reg) in generic_clk_enable()
40 return -EFAULT; in generic_clk_enable()
42 val = readl(clk->en_reg); in generic_clk_enable()
43 if (unlikely(clk->flags & RESET_TO_ENABLE)) in generic_clk_enable()
44 val &= ~(1 << clk->en_reg_bit); in generic_clk_enable()
46 val |= 1 << clk->en_reg_bit; in generic_clk_enable()
48 writel(val, clk->en_reg); in generic_clk_enable()
57 if (!clk->en_reg) in generic_clk_disable()
60 val = readl(clk->en_reg); in generic_clk_disable()
61 if (unlikely(clk->flags & RESET_TO_ENABLE)) in generic_clk_disable()
62 val |= 1 << clk->en_reg_bit; in generic_clk_disable()
64 val &= ~(1 << clk->en_reg_bit); in generic_clk_disable()
66 writel(val, clk->en_reg); in generic_clk_disable()
75 /* returns current programmed clocks clock info structure */
81 val = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift) in pclk_info_get()
82 & clk->pclk_sel->pclk_sel_mask; in pclk_info_get()
84 for (i = 0; i < clk->pclk_sel->pclk_count; i++) { in pclk_info_get()
85 if (clk->pclk_sel->pclk_info[i].pclk_val == val) in pclk_info_get()
86 info = &clk->pclk_sel->pclk_info[i]; in pclk_info_get()
93 * Set Update pclk, and pclk_info of clk and add clock sibling node to current
101 list_del(&clk->sibling); in clk_reparent()
102 list_add(&clk->sibling, &pclk_info->pclk->children); in clk_reparent()
104 clk->pclk = pclk_info->pclk; in clk_reparent()
117 if (!clk->usage_count) { in do_clk_disable()
122 clk->usage_count--; in do_clk_disable()
124 if (clk->usage_count == 0) { in do_clk_disable()
127 * of this clock in do_clk_disable()
129 if (clk->pclk) in do_clk_disable()
130 do_clk_disable(clk->pclk); in do_clk_disable()
132 if (clk->ops && clk->ops->disable) in do_clk_disable()
133 clk->ops->disable(clk); in do_clk_disable()
142 return -EFAULT; in do_clk_enable()
144 if (clk->usage_count == 0) { in do_clk_enable()
145 if (clk->pclk) { in do_clk_enable()
146 ret = do_clk_enable(clk->pclk); in do_clk_enable()
150 if (clk->ops && clk->ops->enable) { in do_clk_enable()
151 ret = clk->ops->enable(clk); in do_clk_enable()
153 if (clk->pclk) in do_clk_enable()
154 do_clk_disable(clk->pclk); in do_clk_enable()
159 * Since the clock is going to be used for the first in do_clk_enable()
162 if (clk->recalc) { in do_clk_enable()
163 ret = clk->recalc(clk); in do_clk_enable()
168 clk->usage_count++; in do_clk_enable()
174 * clk_enable - inform the system when the clock source should be running.
175 * @clk: clock source
177 * If the clock can not be enabled/disabled, this should return success.
194 * clk_disable - inform the system when the clock source is no longer required.
195 * @clk: clock source
197 * Inform the system that a clock source is no longer required by
200 * Implementation detail: if the clock source is shared between
202 * same number of clk_disable() calls for the clock source to be
216 * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
217 * This is only valid once the clock source has been enabled.
218 * @clk: clock source
225 rate = clk->rate; in clk_get_rate()
233 * clk_set_parent - set the parent clock source for this clock
234 * @clk: clock source
235 * @parent: parent clock source
245 return -EFAULT; in clk_set_parent()
246 if (clk->pclk == parent) in clk_set_parent()
248 if (!clk->pclk_sel) in clk_set_parent()
249 return -EPERM; in clk_set_parent()
252 for (i = 0; i < clk->pclk_sel->pclk_count; i++) { in clk_set_parent()
253 if (clk->pclk_sel->pclk_info[i].pclk == parent) { in clk_set_parent()
260 return -EINVAL; in clk_set_parent()
264 val = readl(clk->pclk_sel->pclk_sel_reg); in clk_set_parent()
265 val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift); in clk_set_parent()
266 val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift; in clk_set_parent()
267 writel(val, clk->pclk_sel->pclk_sel_reg); in clk_set_parent()
271 clk_reparent(clk, &clk->pclk_sel->pclk_info[i]); in clk_set_parent()
279 * clk_set_rate - set the clock rate for a clock source
280 * @clk: clock source
281 * @rate: desired clock rate in Hz
288 int ret = -EINVAL; in clk_set_rate()
291 return -EFAULT; in clk_set_rate()
293 if (clk->set_rate) { in clk_set_rate()
295 ret = clk->set_rate(clk, rate); in clk_set_rate()
297 /* if successful -> propagate */ in clk_set_rate()
300 } else if (clk->pclk) { in clk_set_rate()
301 u32 mult = clk->div_factor ? clk->div_factor : 1; in clk_set_rate()
302 ret = clk_set_rate(clk->pclk, mult * rate); in clk_set_rate()
309 /* registers clock in platform clock framework */
315 if (!cl || !cl->clk) in clk_register()
317 clk = cl->clk; in clk_register()
321 INIT_LIST_HEAD(&clk->children); in clk_register()
322 if (clk->flags & ALWAYS_ENABLED) in clk_register()
323 clk->ops = NULL; in clk_register()
324 else if (!clk->ops) in clk_register()
325 clk->ops = &generic_clkops; in clk_register()
327 /* root clock don't have any parents */ in clk_register()
328 if (!clk->pclk && !clk->pclk_sel) { in clk_register()
329 list_add(&clk->sibling, &root_clks); in clk_register()
330 } else if (clk->pclk && !clk->pclk_sel) { in clk_register()
332 list_add(&clk->sibling, &clk->pclk->children); in clk_register()
341 cl->dev_id, cl->con_id); in clk_register()
343 clk->pclk = pclk_info->pclk; in clk_register()
344 list_add(&clk->sibling, &pclk_info->pclk->children); in clk_register()
352 list_add(&clk->node, &clocks); in clk_register()
353 clk->cl = cl; in clk_register()
356 /* add clock to arm clockdev framework */ in clk_register()
361 * propagate_rate - recalculate and propagate all clocks to children
362 * @pclk: parent clock required to be propogated
372 list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) { in propagate_rate()
373 if (clk->recalc) { in propagate_rate()
374 ret = clk->recalc(clk); in propagate_rate()
379 if (ret && clk->set_rate) in propagate_rate()
380 clk->set_rate(clk, 0); in propagate_rate()
388 if (clk->flags & ENABLED_ON_INIT) in propagate_rate()
394 * round_rate_index - return closest programmable rate index in rate_config tbl
395 * @clk: ptr to clock structure
401 * -EINVAL is returned. This routine assumes that rate_config is written
411 if (!clk->calc_rate) in round_rate_index()
412 return -EFAULT; in round_rate_index()
415 return -EINVAL; in round_rate_index()
419 * - as soon as clk is found with rate greater than requested rate. in round_rate_index()
420 * - if all clks in rate_config are smaller than requested rate. in round_rate_index()
422 for (index = 0; index < clk->rate_config.count; index++) { in round_rate_index()
424 tmp = clk->calc_rate(clk, index); in round_rate_index()
426 index--; in round_rate_index()
430 /* return if can't find suitable clock */ in round_rate_index()
432 index = -EINVAL; in round_rate_index()
434 } else if (index == clk->rate_config.count) { in round_rate_index()
436 index = clk->rate_config.count - 1; in round_rate_index()
445 * clk_round_rate - adjust a rate to the exact rate a clock can provide
446 * @clk: clock source
447 * @rate: desired clock rate in Hz
449 * Returns rounded clock rate in Hz, or negative errno.
460 if (!clk->calc_rate) { in clk_round_rate()
462 if (!clk->pclk) in clk_round_rate()
463 return clk->rate; in clk_round_rate()
465 mult = clk->div_factor ? clk->div_factor : 1; in clk_round_rate()
466 return clk_round_rate(clk->pclk, mult * drate) / mult; in clk_round_rate()
490 unsigned long rate = clk->pclk->rate; in pll_calc_rate()
491 struct pll_rate_tbl *tbls = clk->rate_config.tbls; in pll_calc_rate()
510 struct pll_clk_config *config = clk->private_data; in pll_clk_recalc()
513 mode = (readl(config->mode_reg) >> config->masks->mode_shift) & in pll_clk_recalc()
514 config->masks->mode_mask; in pll_clk_recalc()
516 val = readl(config->cfg_reg); in pll_clk_recalc()
518 den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask; in pll_clk_recalc()
520 den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask; in pll_clk_recalc()
525 num *= (val >> config->masks->norm_fdbk_m_shift) & in pll_clk_recalc()
526 config->masks->norm_fdbk_m_mask; in pll_clk_recalc()
529 num *= (val >> config->masks->dith_fdbk_m_shift) & in pll_clk_recalc()
530 config->masks->dith_fdbk_m_mask; in pll_clk_recalc()
535 return -EINVAL; in pll_clk_recalc()
537 clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000; in pll_clk_recalc()
542 * Configures new clock rate of pll
546 struct pll_rate_tbl *tbls = clk->rate_config.tbls; in pll_clk_set_rate()
547 struct pll_clk_config *config = clk->private_data; in pll_clk_set_rate()
555 val = readl(config->mode_reg) & in pll_clk_set_rate()
556 ~(config->masks->mode_mask << config->masks->mode_shift); in pll_clk_set_rate()
557 val |= (tbls[i].mode & config->masks->mode_mask) << in pll_clk_set_rate()
558 config->masks->mode_shift; in pll_clk_set_rate()
559 writel(val, config->mode_reg); in pll_clk_set_rate()
561 val = readl(config->cfg_reg) & in pll_clk_set_rate()
562 ~(config->masks->div_p_mask << config->masks->div_p_shift); in pll_clk_set_rate()
563 val |= (tbls[i].p & config->masks->div_p_mask) << in pll_clk_set_rate()
564 config->masks->div_p_shift; in pll_clk_set_rate()
565 val &= ~(config->masks->div_n_mask << config->masks->div_n_shift); in pll_clk_set_rate()
566 val |= (tbls[i].n & config->masks->div_n_mask) << in pll_clk_set_rate()
567 config->masks->div_n_shift; in pll_clk_set_rate()
568 val &= ~(config->masks->dith_fdbk_m_mask << in pll_clk_set_rate()
569 config->masks->dith_fdbk_m_shift); in pll_clk_set_rate()
571 val |= (tbls[i].m & config->masks->dith_fdbk_m_mask) << in pll_clk_set_rate()
572 config->masks->dith_fdbk_m_shift; in pll_clk_set_rate()
574 val |= (tbls[i].m & config->masks->norm_fdbk_m_mask) << in pll_clk_set_rate()
575 config->masks->norm_fdbk_m_shift; in pll_clk_set_rate()
577 writel(val, config->cfg_reg); in pll_clk_set_rate()
579 clk->rate = rate; in pll_clk_set_rate()
589 unsigned long rate = clk->pclk->rate; in bus_calc_rate()
590 struct bus_rate_tbl *tbls = clk->rate_config.tbls; in bus_calc_rate()
598 struct bus_clk_config *config = clk->private_data; in bus_clk_recalc()
601 div = ((readl(config->reg) >> config->masks->shift) & in bus_clk_recalc()
602 config->masks->mask) + 1; in bus_clk_recalc()
605 return -EINVAL; in bus_clk_recalc()
607 clk->rate = (unsigned long)clk->pclk->rate / div; in bus_clk_recalc()
611 /* Configures new clock rate of AHB OR APB bus */
614 struct bus_rate_tbl *tbls = clk->rate_config.tbls; in bus_clk_set_rate()
615 struct bus_clk_config *config = clk->private_data; in bus_clk_set_rate()
623 val = readl(config->reg) & in bus_clk_set_rate()
624 ~(config->masks->mask << config->masks->shift); in bus_clk_set_rate()
625 val |= (tbls[i].div & config->masks->mask) << config->masks->shift; in bus_clk_set_rate()
626 writel(val, config->reg); in bus_clk_set_rate()
628 clk->rate = rate; in bus_clk_set_rate()
642 unsigned long rate = clk->pclk->rate; in aux_calc_rate()
643 struct aux_rate_tbl *tbls = clk->rate_config.tbls; in aux_calc_rate()
662 struct aux_clk_config *config = clk->private_data; in aux_clk_recalc()
665 val = readl(config->synth_reg); in aux_clk_recalc()
667 eqn = (val >> config->masks->eq_sel_shift) & in aux_clk_recalc()
668 config->masks->eq_sel_mask; in aux_clk_recalc()
669 if (eqn == config->masks->eq1_mask) in aux_clk_recalc()
673 num = (val >> config->masks->xscale_sel_shift) & in aux_clk_recalc()
674 config->masks->xscale_sel_mask; in aux_clk_recalc()
677 den *= (val >> config->masks->yscale_sel_shift) & in aux_clk_recalc()
678 config->masks->yscale_sel_mask; in aux_clk_recalc()
681 return -EINVAL; in aux_clk_recalc()
683 clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000; in aux_clk_recalc()
687 /* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
690 struct aux_rate_tbl *tbls = clk->rate_config.tbls; in aux_clk_set_rate()
691 struct aux_clk_config *config = clk->private_data; in aux_clk_set_rate()
699 val = readl(config->synth_reg) & in aux_clk_set_rate()
700 ~(config->masks->eq_sel_mask << config->masks->eq_sel_shift); in aux_clk_set_rate()
701 val |= (tbls[i].eq & config->masks->eq_sel_mask) << in aux_clk_set_rate()
702 config->masks->eq_sel_shift; in aux_clk_set_rate()
703 val &= ~(config->masks->xscale_sel_mask << in aux_clk_set_rate()
704 config->masks->xscale_sel_shift); in aux_clk_set_rate()
705 val |= (tbls[i].xscale & config->masks->xscale_sel_mask) << in aux_clk_set_rate()
706 config->masks->xscale_sel_shift; in aux_clk_set_rate()
707 val &= ~(config->masks->yscale_sel_mask << in aux_clk_set_rate()
708 config->masks->yscale_sel_shift); in aux_clk_set_rate()
709 val |= (tbls[i].yscale & config->masks->yscale_sel_mask) << in aux_clk_set_rate()
710 config->masks->yscale_sel_shift; in aux_clk_set_rate()
711 writel(val, config->synth_reg); in aux_clk_set_rate()
713 clk->rate = rate; in aux_clk_set_rate()
725 unsigned long rate = clk->pclk->rate; in gpt_calc_rate()
726 struct gpt_rate_tbl *tbls = clk->rate_config.tbls; in gpt_calc_rate()
739 struct gpt_clk_config *config = clk->private_data; in gpt_clk_recalc()
742 val = readl(config->synth_reg); in gpt_clk_recalc()
743 div += (val >> config->masks->mscale_sel_shift) & in gpt_clk_recalc()
744 config->masks->mscale_sel_mask; in gpt_clk_recalc()
745 div *= 1 << (((val >> config->masks->nscale_sel_shift) & in gpt_clk_recalc()
746 config->masks->nscale_sel_mask) + 1); in gpt_clk_recalc()
749 return -EINVAL; in gpt_clk_recalc()
751 clk->rate = (unsigned long)clk->pclk->rate / div; in gpt_clk_recalc()
755 /* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/
758 struct gpt_rate_tbl *tbls = clk->rate_config.tbls; in gpt_clk_set_rate()
759 struct gpt_clk_config *config = clk->private_data; in gpt_clk_set_rate()
767 val = readl(config->synth_reg) & ~(config->masks->mscale_sel_mask << in gpt_clk_set_rate()
768 config->masks->mscale_sel_shift); in gpt_clk_set_rate()
769 val |= (tbls[i].mscale & config->masks->mscale_sel_mask) << in gpt_clk_set_rate()
770 config->masks->mscale_sel_shift; in gpt_clk_set_rate()
771 val &= ~(config->masks->nscale_sel_mask << in gpt_clk_set_rate()
772 config->masks->nscale_sel_shift); in gpt_clk_set_rate()
773 val |= (tbls[i].nscale & config->masks->nscale_sel_mask) << in gpt_clk_set_rate()
774 config->masks->nscale_sel_shift; in gpt_clk_set_rate()
775 writel(val, config->synth_reg); in gpt_clk_set_rate()
777 clk->rate = rate; in gpt_clk_set_rate()
786 * Fout= Fin/2*div (division factor)
787 * div is 17 bits:-
788 * 0-13 (fractional part)
789 * 14-16 (integer part)
796 unsigned long rate = clk->pclk->rate; in clcd_calc_rate()
797 struct clcd_rate_tbl *tbls = clk->rate_config.tbls; in clcd_calc_rate()
811 * Fout= Fin/2*div (division factor)
812 * div is 17 bits:-
813 * 0-13 (fractional part)
814 * 14-16 (integer part)
821 struct clcd_clk_config *config = clk->private_data; in clcd_clk_recalc()
826 val = readl(config->synth_reg); in clcd_clk_recalc()
827 div = (val >> config->masks->div_factor_shift) & in clcd_clk_recalc()
828 config->masks->div_factor_mask; in clcd_clk_recalc()
831 return -EINVAL; in clcd_clk_recalc()
833 prate = clk->pclk->rate / 1000; /* first level division, make it KHz */ in clcd_clk_recalc()
835 clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12; in clcd_clk_recalc()
836 clk->rate *= 1000; in clcd_clk_recalc()
840 /* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
843 struct clcd_rate_tbl *tbls = clk->rate_config.tbls; in clcd_clk_set_rate()
844 struct clcd_clk_config *config = clk->private_data; in clcd_clk_set_rate()
852 val = readl(config->synth_reg) & ~(config->masks->div_factor_mask << in clcd_clk_set_rate()
853 config->masks->div_factor_shift); in clcd_clk_set_rate()
854 val |= (tbls[i].div & config->masks->div_factor_mask) << in clcd_clk_set_rate()
855 config->masks->div_factor_shift; in clcd_clk_set_rate()
856 writel(val, config->synth_reg); in clcd_clk_set_rate()
858 clk->rate = rate; in clcd_clk_set_rate()
864 * Used for clocks that always have value as the parent clock divided by a
865 * fixed divisor
869 unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor; in follow_parent()
871 clk->rate = clk->pclk->rate/div_factor; in follow_parent()
876 * recalc_root_clocks - recalculate and propagate all root clocks
879 * clock's .recalc is set correctly, should also propagate their rates.
889 if (pclk->recalc) { in recalc_root_clocks()
890 ret = pclk->recalc(pclk); in recalc_root_clocks()
893 * In this case configure default clock. in recalc_root_clocks()
895 if (ret && pclk->set_rate) in recalc_root_clocks()
896 pclk->set_rate(pclk, 0); in recalc_root_clocks()
900 if (pclk->flags & ENABLED_ON_INIT) in recalc_root_clocks()
913 * debugfs support to trace clock tree hierarchy and attributes
920 struct clk *pa = c->pclk; in clk_debugfs_register_one()
925 if (c->cl->con_id) in clk_debugfs_register_one()
926 p += sprintf(p, "%s", c->cl->con_id); in clk_debugfs_register_one()
927 if (c->cl->dev_id) in clk_debugfs_register_one()
928 p += sprintf(p, "%s", c->cl->dev_id); in clk_debugfs_register_one()
930 d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root); in clk_debugfs_register_one()
932 return -ENOMEM; in clk_debugfs_register_one()
933 c->dent = d; in clk_debugfs_register_one()
935 d = debugfs_create_u32("usage_count", S_IRUGO, c->dent, in clk_debugfs_register_one()
936 (u32 *)&c->usage_count); in clk_debugfs_register_one()
938 err = -ENOMEM; in clk_debugfs_register_one()
941 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); in clk_debugfs_register_one()
943 err = -ENOMEM; in clk_debugfs_register_one()
946 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags); in clk_debugfs_register_one()
948 err = -ENOMEM; in clk_debugfs_register_one()
954 debugfs_remove_recursive(c->dent); in clk_debugfs_register_one()
961 struct clk *pa = c->pclk; in clk_debugfs_register()
963 if (pa && !pa->dent) { in clk_debugfs_register()
969 if (!c->dent) { in clk_debugfs_register()
983 d = debugfs_create_dir("clock", NULL); in clk_debugfs_init()
985 return -ENOMEM; in clk_debugfs_init()
1002 debugfs_remove(c->dent); in clk_debugfs_reparent()