clk.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2014 Google, Inc.
  4. */
  5. #include <linux/clk.h>
  6. #include <linux/clk-provider.h>
  7. #include <linux/kernel.h>
  8. #include <linux/of.h>
  9. #include <linux/of_address.h>
  10. #include <linux/slab.h>
  11. #include "clk.h"
  12. struct pistachio_clk_provider *
  13. pistachio_clk_alloc_provider(struct device_node *node, unsigned int num_clks)
  14. {
  15. struct pistachio_clk_provider *p;
  16. p = kzalloc(sizeof(*p), GFP_KERNEL);
  17. if (!p)
  18. return p;
  19. p->clk_data.clks = kcalloc(num_clks, sizeof(struct clk *), GFP_KERNEL);
  20. if (!p->clk_data.clks)
  21. goto free_provider;
  22. p->clk_data.clk_num = num_clks;
  23. p->node = node;
  24. p->base = of_iomap(node, 0);
  25. if (!p->base) {
  26. pr_err("Failed to map clock provider registers\n");
  27. goto free_clks;
  28. }
  29. return p;
  30. free_clks:
  31. kfree(p->clk_data.clks);
  32. free_provider:
  33. kfree(p);
  34. return NULL;
  35. }
  36. void pistachio_clk_register_provider(struct pistachio_clk_provider *p)
  37. {
  38. unsigned int i;
  39. for (i = 0; i < p->clk_data.clk_num; i++) {
  40. if (IS_ERR(p->clk_data.clks[i]))
  41. pr_warn("Failed to register clock %d: %ld\n", i,
  42. PTR_ERR(p->clk_data.clks[i]));
  43. }
  44. of_clk_add_provider(p->node, of_clk_src_onecell_get, &p->clk_data);
  45. }
  46. void pistachio_clk_register_gate(struct pistachio_clk_provider *p,
  47. struct pistachio_gate *gate,
  48. unsigned int num)
  49. {
  50. struct clk *clk;
  51. unsigned int i;
  52. for (i = 0; i < num; i++) {
  53. clk = clk_register_gate(NULL, gate[i].name, gate[i].parent,
  54. CLK_SET_RATE_PARENT,
  55. p->base + gate[i].reg, gate[i].shift,
  56. 0, NULL);
  57. p->clk_data.clks[gate[i].id] = clk;
  58. }
  59. }
  60. void pistachio_clk_register_mux(struct pistachio_clk_provider *p,
  61. struct pistachio_mux *mux,
  62. unsigned int num)
  63. {
  64. struct clk *clk;
  65. unsigned int i;
  66. for (i = 0; i < num; i++) {
  67. clk = clk_register_mux(NULL, mux[i].name, mux[i].parents,
  68. mux[i].num_parents,
  69. CLK_SET_RATE_NO_REPARENT,
  70. p->base + mux[i].reg, mux[i].shift,
  71. get_count_order(mux[i].num_parents),
  72. 0, NULL);
  73. p->clk_data.clks[mux[i].id] = clk;
  74. }
  75. }
  76. void pistachio_clk_register_div(struct pistachio_clk_provider *p,
  77. struct pistachio_div *div,
  78. unsigned int num)
  79. {
  80. struct clk *clk;
  81. unsigned int i;
  82. for (i = 0; i < num; i++) {
  83. clk = clk_register_divider(NULL, div[i].name, div[i].parent,
  84. 0, p->base + div[i].reg, 0,
  85. div[i].width, div[i].div_flags,
  86. NULL);
  87. p->clk_data.clks[div[i].id] = clk;
  88. }
  89. }
  90. void pistachio_clk_register_fixed_factor(struct pistachio_clk_provider *p,
  91. struct pistachio_fixed_factor *ff,
  92. unsigned int num)
  93. {
  94. struct clk *clk;
  95. unsigned int i;
  96. for (i = 0; i < num; i++) {
  97. clk = clk_register_fixed_factor(NULL, ff[i].name, ff[i].parent,
  98. 0, 1, ff[i].div);
  99. p->clk_data.clks[ff[i].id] = clk;
  100. }
  101. }
  102. void pistachio_clk_force_enable(struct pistachio_clk_provider *p,
  103. unsigned int *clk_ids, unsigned int num)
  104. {
  105. unsigned int i;
  106. int err;
  107. for (i = 0; i < num; i++) {
  108. struct clk *clk = p->clk_data.clks[clk_ids[i]];
  109. if (IS_ERR(clk))
  110. continue;
  111. err = clk_prepare_enable(clk);
  112. if (err)
  113. pr_err("Failed to enable clock %s: %d\n",
  114. __clk_get_name(clk), err);
  115. }
  116. }