clk-fixed-factor.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2019 DENX Software Engineering
  4. * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
  5. *
  6. * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
  7. */
  8. #include <common.h>
  9. #include <malloc.h>
  10. #include <clk-uclass.h>
  11. #include <dm/device.h>
  12. #include <dm/devres.h>
  13. #include <linux/clk-provider.h>
  14. #include <div64.h>
  15. #include <clk.h>
  16. #include "clk.h"
  17. #include <linux/err.h>
  18. #define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
  19. static ulong clk_factor_recalc_rate(struct clk *clk)
  20. {
  21. struct clk_fixed_factor *fix =
  22. to_clk_fixed_factor(dev_get_clk_ptr(clk->dev));
  23. unsigned long parent_rate = clk_get_parent_rate(clk);
  24. unsigned long long int rate;
  25. rate = (unsigned long long int)parent_rate * fix->mult;
  26. do_div(rate, fix->div);
  27. return (ulong)rate;
  28. }
  29. const struct clk_ops ccf_clk_fixed_factor_ops = {
  30. .get_rate = clk_factor_recalc_rate,
  31. };
  32. struct clk *clk_hw_register_fixed_factor(struct device *dev,
  33. const char *name, const char *parent_name, unsigned long flags,
  34. unsigned int mult, unsigned int div)
  35. {
  36. struct clk_fixed_factor *fix;
  37. struct clk *clk;
  38. int ret;
  39. fix = kzalloc(sizeof(*fix), GFP_KERNEL);
  40. if (!fix)
  41. return ERR_PTR(-ENOMEM);
  42. /* struct clk_fixed_factor assignments */
  43. fix->mult = mult;
  44. fix->div = div;
  45. clk = &fix->clk;
  46. ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, name,
  47. parent_name);
  48. if (ret) {
  49. kfree(fix);
  50. return ERR_PTR(ret);
  51. }
  52. return clk;
  53. }
  54. struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
  55. const char *parent_name, unsigned long flags,
  56. unsigned int mult, unsigned int div)
  57. {
  58. struct clk *clk;
  59. clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
  60. div);
  61. if (IS_ERR(clk))
  62. return ERR_CAST(clk);
  63. return clk;
  64. }
  65. U_BOOT_DRIVER(imx_clk_fixed_factor) = {
  66. .name = UBOOT_DM_CLK_IMX_FIXED_FACTOR,
  67. .id = UCLASS_CLK,
  68. .ops = &ccf_clk_fixed_factor_ops,
  69. .flags = DM_FLAG_PRE_RELOC,
  70. };