clk.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms and conditions of the GNU General Public License,
  6. * version 2, as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <linux/clk.h>
  17. #include <linux/clk-provider.h>
  18. #include <linux/of.h>
  19. #include <linux/clk/tegra.h>
  20. #include "clk.h"
  21. /* Global data of Tegra CPU CAR ops */
  22. static struct tegra_cpu_car_ops dummy_car_ops;
  23. struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
  24. void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
  25. struct clk *clks[], int clk_max)
  26. {
  27. struct clk *clk;
  28. for (; dup_list->clk_id < clk_max; dup_list++) {
  29. clk = clks[dup_list->clk_id];
  30. dup_list->lookup.clk = clk;
  31. clkdev_add(&dup_list->lookup);
  32. }
  33. }
  34. void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
  35. struct clk *clks[], int clk_max)
  36. {
  37. struct clk *clk;
  38. for (; tbl->clk_id < clk_max; tbl++) {
  39. clk = clks[tbl->clk_id];
  40. if (IS_ERR_OR_NULL(clk))
  41. return;
  42. if (tbl->parent_id < clk_max) {
  43. struct clk *parent = clks[tbl->parent_id];
  44. if (clk_set_parent(clk, parent)) {
  45. pr_err("%s: Failed to set parent %s of %s\n",
  46. __func__, __clk_get_name(parent),
  47. __clk_get_name(clk));
  48. WARN_ON(1);
  49. }
  50. }
  51. if (tbl->rate)
  52. if (clk_set_rate(clk, tbl->rate)) {
  53. pr_err("%s: Failed to set rate %lu of %s\n",
  54. __func__, tbl->rate,
  55. __clk_get_name(clk));
  56. WARN_ON(1);
  57. }
  58. if (tbl->state)
  59. if (clk_prepare_enable(clk)) {
  60. pr_err("%s: Failed to enable %s\n", __func__,
  61. __clk_get_name(clk));
  62. WARN_ON(1);
  63. }
  64. }
  65. }
  66. static const struct of_device_id tegra_dt_clk_match[] = {
  67. { .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init },
  68. { .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init },
  69. { }
  70. };
  71. void __init tegra_clocks_init(void)
  72. {
  73. of_clk_init(tegra_dt_clk_match);
  74. }
  75. tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
  76. void __init tegra_clocks_apply_init_table(void)
  77. {
  78. if (!tegra_clk_apply_init_table)
  79. return;
  80. tegra_clk_apply_init_table();
  81. }