clk-moxart.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * MOXA ART SoCs clock driver.
  4. *
  5. * Copyright (C) 2013 Jonas Jensen
  6. *
  7. * Jonas Jensen <[email protected]>
  8. */
  9. #include <linux/clk.h>
  10. #include <linux/clk-provider.h>
  11. #include <linux/io.h>
  12. #include <linux/of_address.h>
  13. #include <linux/clkdev.h>
  14. static void __init moxart_of_pll_clk_init(struct device_node *node)
  15. {
  16. void __iomem *base;
  17. struct clk_hw *hw;
  18. struct clk *ref_clk;
  19. unsigned int mul;
  20. const char *name = node->name;
  21. const char *parent_name;
  22. of_property_read_string(node, "clock-output-names", &name);
  23. parent_name = of_clk_get_parent_name(node, 0);
  24. base = of_iomap(node, 0);
  25. if (!base) {
  26. pr_err("%pOF: of_iomap failed\n", node);
  27. return;
  28. }
  29. mul = readl(base + 0x30) >> 3 & 0x3f;
  30. iounmap(base);
  31. ref_clk = of_clk_get(node, 0);
  32. if (IS_ERR(ref_clk)) {
  33. pr_err("%pOF: of_clk_get failed\n", node);
  34. return;
  35. }
  36. hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
  37. if (IS_ERR(hw)) {
  38. pr_err("%pOF: failed to register clock\n", node);
  39. return;
  40. }
  41. clk_hw_register_clkdev(hw, NULL, name);
  42. of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
  43. }
  44. CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
  45. moxart_of_pll_clk_init);
  46. static void __init moxart_of_apb_clk_init(struct device_node *node)
  47. {
  48. void __iomem *base;
  49. struct clk_hw *hw;
  50. struct clk *pll_clk;
  51. unsigned int div, val;
  52. unsigned int div_idx[] = { 2, 3, 4, 6, 8};
  53. const char *name = node->name;
  54. const char *parent_name;
  55. of_property_read_string(node, "clock-output-names", &name);
  56. parent_name = of_clk_get_parent_name(node, 0);
  57. base = of_iomap(node, 0);
  58. if (!base) {
  59. pr_err("%pOF: of_iomap failed\n", node);
  60. return;
  61. }
  62. val = readl(base + 0xc) >> 4 & 0x7;
  63. iounmap(base);
  64. if (val > 4)
  65. val = 0;
  66. div = div_idx[val] * 2;
  67. pll_clk = of_clk_get(node, 0);
  68. if (IS_ERR(pll_clk)) {
  69. pr_err("%pOF: of_clk_get failed\n", node);
  70. return;
  71. }
  72. hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
  73. if (IS_ERR(hw)) {
  74. pr_err("%pOF: failed to register clock\n", node);
  75. return;
  76. }
  77. clk_hw_register_clkdev(hw, NULL, name);
  78. of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
  79. }
  80. CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
  81. moxart_of_apb_clk_init);