clock.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. *
  3. * Copyright (C) 2010 Google, Inc.
  4. * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
  5. *
  6. * Author:
  7. * Colin Cross <ccross@google.com>
  8. *
  9. * This software is licensed under the terms of the GNU General Public
  10. * License version 2, as published by the Free Software Foundation, and
  11. * may be copied, distributed, and modified under those terms.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. */
  19. #include <linux/kernel.h>
  20. #include <linux/clk.h>
  21. #include <linux/clkdev.h>
  22. #include <linux/init.h>
  23. #include <linux/list.h>
  24. #include <linux/module.h>
  25. #include <linux/sched.h>
  26. #include <linux/seq_file.h>
  27. #include <linux/slab.h>
  28. #include "board.h"
  29. #include "clock.h"
  30. #include "tegra_cpu_car.h"
  31. /* Global data of Tegra CPU CAR ops */
  32. struct tegra_cpu_car_ops *tegra_cpu_car_ops;
  33. /*
  34. * Locking:
  35. *
  36. * An additional mutex, clock_list_lock, is used to protect the list of all
  37. * clocks.
  38. *
  39. */
  40. static DEFINE_MUTEX(clock_list_lock);
  41. static LIST_HEAD(clocks);
  42. void tegra_clk_add(struct clk *clk)
  43. {
  44. struct clk_tegra *c = to_clk_tegra(__clk_get_hw(clk));
  45. mutex_lock(&clock_list_lock);
  46. list_add(&c->node, &clocks);
  47. mutex_unlock(&clock_list_lock);
  48. }
  49. struct clk *tegra_get_clock_by_name(const char *name)
  50. {
  51. struct clk_tegra *c;
  52. struct clk *ret = NULL;
  53. mutex_lock(&clock_list_lock);
  54. list_for_each_entry(c, &clocks, node) {
  55. if (strcmp(__clk_get_name(c->hw.clk), name) == 0) {
  56. ret = c->hw.clk;
  57. break;
  58. }
  59. }
  60. mutex_unlock(&clock_list_lock);
  61. return ret;
  62. }
  63. static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
  64. {
  65. struct clk *c;
  66. struct clk *p;
  67. struct clk *parent;
  68. int ret = 0;
  69. c = tegra_get_clock_by_name(table->name);
  70. if (!c) {
  71. pr_warn("Unable to initialize clock %s\n",
  72. table->name);
  73. return -ENODEV;
  74. }
  75. parent = clk_get_parent(c);
  76. if (table->parent) {
  77. p = tegra_get_clock_by_name(table->parent);
  78. if (!p) {
  79. pr_warn("Unable to find parent %s of clock %s\n",
  80. table->parent, table->name);
  81. return -ENODEV;
  82. }
  83. if (parent != p) {
  84. ret = clk_set_parent(c, p);
  85. if (ret) {
  86. pr_warn("Unable to set parent %s of clock %s: %d\n",
  87. table->parent, table->name, ret);
  88. return -EINVAL;
  89. }
  90. }
  91. }
  92. if (table->rate && table->rate != clk_get_rate(c)) {
  93. ret = clk_set_rate(c, table->rate);
  94. if (ret) {
  95. pr_warn("Unable to set clock %s to rate %lu: %d\n",
  96. table->name, table->rate, ret);
  97. return -EINVAL;
  98. }
  99. }
  100. if (table->enabled) {
  101. ret = clk_prepare_enable(c);
  102. if (ret) {
  103. pr_warn("Unable to enable clock %s: %d\n",
  104. table->name, ret);
  105. return -EINVAL;
  106. }
  107. }
  108. return 0;
  109. }
  110. void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
  111. {
  112. for (; table->name; table++)
  113. tegra_clk_init_one_from_table(table);
  114. }
  115. void tegra_periph_reset_deassert(struct clk *c)
  116. {
  117. struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
  118. BUG_ON(!clk->reset);
  119. clk->reset(__clk_get_hw(c), false);
  120. }
  121. EXPORT_SYMBOL(tegra_periph_reset_deassert);
  122. void tegra_periph_reset_assert(struct clk *c)
  123. {
  124. struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
  125. BUG_ON(!clk->reset);
  126. clk->reset(__clk_get_hw(c), true);
  127. }
  128. EXPORT_SYMBOL(tegra_periph_reset_assert);
  129. /* Several extended clock configuration bits (e.g., clock routing, clock
  130. * phase control) are included in PLL and peripheral clock source
  131. * registers. */
  132. int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
  133. {
  134. int ret = 0;
  135. struct clk_tegra *clk = to_clk_tegra(__clk_get_hw(c));
  136. if (!clk->clk_cfg_ex) {
  137. ret = -ENOSYS;
  138. goto out;
  139. }
  140. ret = clk->clk_cfg_ex(__clk_get_hw(c), p, setting);
  141. out:
  142. return ret;
  143. }