clk.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Hisilicon clock driver
  3. *
  4. * Copyright (c) 2012-2013 Hisilicon Limited.
  5. * Copyright (c) 2012-2013 Linaro Limited.
  6. *
  7. * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
  8. * Xin Li <li.xin@linaro.org>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License along
  21. * with this program; if not, write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  23. *
  24. */
  25. #include <linux/kernel.h>
  26. #include <linux/clk-provider.h>
  27. #include <linux/clkdev.h>
  28. #include <linux/delay.h>
  29. #include <linux/io.h>
  30. #include <linux/of.h>
  31. #include <linux/of_address.h>
  32. #include <linux/of_device.h>
  33. #include <linux/slab.h>
  34. #include <linux/clk.h>
  35. #include "clk.h"
  36. static DEFINE_SPINLOCK(hisi_clk_lock);
  37. static struct clk **clk_table;
  38. static struct clk_onecell_data clk_data;
  39. void __init hisi_clk_init(struct device_node *np, int nr_clks)
  40. {
  41. clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
  42. if (!clk_table) {
  43. pr_err("%s: could not allocate clock lookup table\n", __func__);
  44. return;
  45. }
  46. clk_data.clks = clk_table;
  47. clk_data.clk_num = nr_clks;
  48. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  49. }
  50. void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks,
  51. int nums, void __iomem *base)
  52. {
  53. struct clk *clk;
  54. int i;
  55. for (i = 0; i < nums; i++) {
  56. clk = clk_register_fixed_rate(NULL, clks[i].name,
  57. clks[i].parent_name,
  58. clks[i].flags,
  59. clks[i].fixed_rate);
  60. if (IS_ERR(clk)) {
  61. pr_err("%s: failed to register clock %s\n",
  62. __func__, clks[i].name);
  63. continue;
  64. }
  65. }
  66. }
  67. void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks,
  68. int nums, void __iomem *base)
  69. {
  70. struct clk *clk;
  71. int i;
  72. for (i = 0; i < nums; i++) {
  73. clk = clk_register_fixed_factor(NULL, clks[i].name,
  74. clks[i].parent_name,
  75. clks[i].flags, clks[i].mult,
  76. clks[i].div);
  77. if (IS_ERR(clk)) {
  78. pr_err("%s: failed to register clock %s\n",
  79. __func__, clks[i].name);
  80. continue;
  81. }
  82. }
  83. }
  84. void __init hisi_clk_register_mux(struct hisi_mux_clock *clks,
  85. int nums, void __iomem *base)
  86. {
  87. struct clk *clk;
  88. int i;
  89. for (i = 0; i < nums; i++) {
  90. clk = clk_register_mux(NULL, clks[i].name, clks[i].parent_names,
  91. clks[i].num_parents, clks[i].flags,
  92. base + clks[i].offset, clks[i].shift,
  93. clks[i].width, clks[i].mux_flags,
  94. &hisi_clk_lock);
  95. if (IS_ERR(clk)) {
  96. pr_err("%s: failed to register clock %s\n",
  97. __func__, clks[i].name);
  98. continue;
  99. }
  100. if (clks[i].alias)
  101. clk_register_clkdev(clk, clks[i].alias, NULL);
  102. clk_table[clks[i].id] = clk;
  103. }
  104. }
  105. void __init hisi_clk_register_divider(struct hisi_divider_clock *clks,
  106. int nums, void __iomem *base)
  107. {
  108. struct clk *clk;
  109. int i;
  110. for (i = 0; i < nums; i++) {
  111. clk = clk_register_divider_table(NULL, clks[i].name,
  112. clks[i].parent_name,
  113. clks[i].flags,
  114. base + clks[i].offset,
  115. clks[i].shift, clks[i].width,
  116. clks[i].div_flags,
  117. clks[i].table,
  118. &hisi_clk_lock);
  119. if (IS_ERR(clk)) {
  120. pr_err("%s: failed to register clock %s\n",
  121. __func__, clks[i].name);
  122. continue;
  123. }
  124. if (clks[i].alias)
  125. clk_register_clkdev(clk, clks[i].alias, NULL);
  126. clk_table[clks[i].id] = clk;
  127. }
  128. }
  129. void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
  130. int nums, void __iomem *base)
  131. {
  132. struct clk *clk;
  133. int i;
  134. for (i = 0; i < nums; i++) {
  135. clk = hisi_register_clkgate_sep(NULL, clks[i].name,
  136. clks[i].parent_name,
  137. clks[i].flags,
  138. base + clks[i].offset,
  139. clks[i].bit_idx,
  140. clks[i].gate_flags,
  141. &hisi_clk_lock);
  142. if (IS_ERR(clk)) {
  143. pr_err("%s: failed to register clock %s\n",
  144. __func__, clks[i].name);
  145. continue;
  146. }
  147. if (clks[i].alias)
  148. clk_register_clkdev(clk, clks[i].alias, NULL);
  149. clk_table[clks[i].id] = clk;
  150. }
  151. }