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 = to_clk_fixed_factor(clk);
  22. unsigned long parent_rate = clk_get_parent_rate(clk);
  23. unsigned long long int rate;
  24. rate = (unsigned long long int)parent_rate * fix->mult;
  25. do_div(rate, fix->div);
  26. return (ulong)rate;
  27. }
  28. const struct clk_ops ccf_clk_fixed_factor_ops = {
  29. .get_rate = clk_factor_recalc_rate,
  30. };
  31. struct clk *clk_hw_register_fixed_factor(struct device *dev,
  32. const char *name, const char *parent_name, unsigned long flags,
  33. unsigned int mult, unsigned int div)
  34. {
  35. struct clk_fixed_factor *fix;
  36. struct clk *clk;
  37. int ret;
  38. fix = kzalloc(sizeof(*fix), GFP_KERNEL);
  39. if (!fix)
  40. return ERR_PTR(-ENOMEM);
  41. /* struct clk_fixed_factor assignments */
  42. fix->mult = mult;
  43. fix->div = div;
  44. clk = &fix->clk;
  45. clk->flags = flags;
  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. };