clk-moxart.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * MOXA ART SoCs clock driver.
  3. *
  4. * Copyright (C) 2013 Jonas Jensen
  5. *
  6. * Jonas Jensen <jonas.jensen@gmail.com>
  7. *
  8. * This file is licensed under the terms of the GNU General Public
  9. * License version 2. This program is licensed "as is" without any
  10. * warranty of any kind, whether express or implied.
  11. */
  12. #include <linux/clk-provider.h>
  13. #include <linux/io.h>
  14. #include <linux/of_address.h>
  15. #include <linux/clkdev.h>
  16. void __init moxart_of_pll_clk_init(struct device_node *node)
  17. {
  18. static void __iomem *base;
  19. struct clk *clk, *ref_clk;
  20. unsigned int mul;
  21. const char *name = node->name;
  22. const char *parent_name;
  23. of_property_read_string(node, "clock-output-names", &name);
  24. parent_name = of_clk_get_parent_name(node, 0);
  25. base = of_iomap(node, 0);
  26. if (!base) {
  27. pr_err("%s: of_iomap failed\n", node->full_name);
  28. return;
  29. }
  30. mul = readl(base + 0x30) >> 3 & 0x3f;
  31. iounmap(base);
  32. ref_clk = of_clk_get(node, 0);
  33. if (IS_ERR(ref_clk)) {
  34. pr_err("%s: of_clk_get failed\n", node->full_name);
  35. return;
  36. }
  37. clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
  38. if (IS_ERR(clk)) {
  39. pr_err("%s: failed to register clock\n", node->full_name);
  40. return;
  41. }
  42. clk_register_clkdev(clk, NULL, name);
  43. of_clk_add_provider(node, of_clk_src_simple_get, clk);
  44. }
  45. CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
  46. moxart_of_pll_clk_init);
  47. void __init moxart_of_apb_clk_init(struct device_node *node)
  48. {
  49. static void __iomem *base;
  50. struct clk *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("%s: of_iomap failed\n", node->full_name);
  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("%s: of_clk_get failed\n", node->full_name);
  70. return;
  71. }
  72. clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
  73. if (IS_ERR(clk)) {
  74. pr_err("%s: failed to register clock\n", node->full_name);
  75. return;
  76. }
  77. clk_register_clkdev(clk, NULL, name);
  78. of_clk_add_provider(node, of_clk_src_simple_get, clk);
  79. }
  80. CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
  81. moxart_of_apb_clk_init);