clk-fixed-factor.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
  4. */
  5. #include "ccu.h"
  6. /*
  7. * DOC: basic fixed multiplier and divider clock that cannot gate
  8. *
  9. * Traits of this clock:
  10. * prepare - clk_prepare only ensures that parents are prepared
  11. * enable - clk_enable only ensures that parents are enabled
  12. * rate - rate is fixed. clk->rate = parent->rate / div * mult
  13. * parent - fixed parent. No clk_set_parent support
  14. */
  15. static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
  16. unsigned long parent_rate)
  17. {
  18. struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
  19. unsigned long long int rate;
  20. rate = (unsigned long long int)parent_rate * fix->mult;
  21. rate /= fix->div;
  22. return (unsigned long)rate;
  23. }
  24. static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
  25. unsigned long *prate)
  26. {
  27. struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
  28. if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)
  29. {
  30. unsigned long best_parent;
  31. best_parent = (rate / fix->mult) * fix->div;
  32. *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
  33. }
  34. return (*prate / fix->div) * fix->mult;
  35. }
  36. static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
  37. unsigned long parent_rate)
  38. {
  39. struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
  40. /*
  41. * We must report success but we can do so unconditionally because
  42. * clk_factor_round_rate returns values that ensure this call is a
  43. * nop.
  44. */
  45. if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)
  46. {
  47. unsigned long p_rate;
  48. p_rate = (rate / fix->mult) * fix->div;
  49. return clk_hw_set_rate(clk_hw_get_parent(hw), p_rate);
  50. }
  51. return 0;
  52. }
  53. const struct clk_ops clk_fixed_factor_ops =
  54. {
  55. .round_rate = clk_factor_round_rate,
  56. .set_rate = clk_factor_set_rate,
  57. .recalc_rate = clk_factor_recalc_rate,
  58. };