clk.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * This program is free software; you can redistribute it and/or modify it
  3. * under the terms of the GNU General Public License version 2 as published
  4. * by the Free Software Foundation.
  5. *
  6. * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
  7. * Copyright (C) 2010 John Crispin <john@phrozen.org>
  8. */
  9. #include <linux/io.h>
  10. #include <linux/export.h>
  11. #include <linux/init.h>
  12. #include <linux/kernel.h>
  13. #include <linux/types.h>
  14. #include <linux/clk.h>
  15. #include <linux/clkdev.h>
  16. #include <linux/err.h>
  17. #include <linux/list.h>
  18. #include <asm/time.h>
  19. #include <asm/irq.h>
  20. #include <asm/div64.h>
  21. #include <lantiq_soc.h>
  22. #include "clk.h"
  23. #include "prom.h"
  24. /* lantiq socs have 3 static clocks */
  25. static struct clk cpu_clk_generic[4];
  26. void clkdev_add_static(unsigned long cpu, unsigned long fpi,
  27. unsigned long io, unsigned long ppe)
  28. {
  29. cpu_clk_generic[0].rate = cpu;
  30. cpu_clk_generic[1].rate = fpi;
  31. cpu_clk_generic[2].rate = io;
  32. cpu_clk_generic[3].rate = ppe;
  33. }
  34. struct clk *clk_get_cpu(void)
  35. {
  36. return &cpu_clk_generic[0];
  37. }
  38. struct clk *clk_get_fpi(void)
  39. {
  40. return &cpu_clk_generic[1];
  41. }
  42. EXPORT_SYMBOL_GPL(clk_get_fpi);
  43. struct clk *clk_get_io(void)
  44. {
  45. return &cpu_clk_generic[2];
  46. }
  47. struct clk *clk_get_ppe(void)
  48. {
  49. return &cpu_clk_generic[3];
  50. }
  51. EXPORT_SYMBOL_GPL(clk_get_ppe);
  52. static inline int clk_good(struct clk *clk)
  53. {
  54. return clk && !IS_ERR(clk);
  55. }
  56. unsigned long clk_get_rate(struct clk *clk)
  57. {
  58. if (unlikely(!clk_good(clk)))
  59. return 0;
  60. if (clk->rate != 0)
  61. return clk->rate;
  62. if (clk->get_rate != NULL)
  63. return clk->get_rate();
  64. return 0;
  65. }
  66. EXPORT_SYMBOL(clk_get_rate);
  67. int clk_set_rate(struct clk *clk, unsigned long rate)
  68. {
  69. if (unlikely(!clk_good(clk)))
  70. return 0;
  71. if (clk->rates && *clk->rates) {
  72. unsigned long *r = clk->rates;
  73. while (*r && (*r != rate))
  74. r++;
  75. if (!*r) {
  76. pr_err("clk %s.%s: trying to set invalid rate %ld\n",
  77. clk->cl.dev_id, clk->cl.con_id, rate);
  78. return -1;
  79. }
  80. }
  81. clk->rate = rate;
  82. return 0;
  83. }
  84. EXPORT_SYMBOL(clk_set_rate);
  85. long clk_round_rate(struct clk *clk, unsigned long rate)
  86. {
  87. if (unlikely(!clk_good(clk)))
  88. return 0;
  89. if (clk->rates && *clk->rates) {
  90. unsigned long *r = clk->rates;
  91. while (*r && (*r != rate))
  92. r++;
  93. if (!*r) {
  94. return clk->rate;
  95. }
  96. }
  97. return rate;
  98. }
  99. EXPORT_SYMBOL(clk_round_rate);
  100. int clk_enable(struct clk *clk)
  101. {
  102. if (unlikely(!clk_good(clk)))
  103. return -1;
  104. if (clk->enable)
  105. return clk->enable(clk);
  106. return -1;
  107. }
  108. EXPORT_SYMBOL(clk_enable);
  109. void clk_disable(struct clk *clk)
  110. {
  111. if (unlikely(!clk_good(clk)))
  112. return;
  113. if (clk->disable)
  114. clk->disable(clk);
  115. }
  116. EXPORT_SYMBOL(clk_disable);
  117. int clk_activate(struct clk *clk)
  118. {
  119. if (unlikely(!clk_good(clk)))
  120. return -1;
  121. if (clk->activate)
  122. return clk->activate(clk);
  123. return -1;
  124. }
  125. EXPORT_SYMBOL(clk_activate);
  126. void clk_deactivate(struct clk *clk)
  127. {
  128. if (unlikely(!clk_good(clk)))
  129. return;
  130. if (clk->deactivate)
  131. clk->deactivate(clk);
  132. }
  133. EXPORT_SYMBOL(clk_deactivate);
  134. struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
  135. {
  136. return NULL;
  137. }
  138. static inline u32 get_counter_resolution(void)
  139. {
  140. u32 res;
  141. __asm__ __volatile__(
  142. ".set push\n"
  143. ".set mips32r2\n"
  144. "rdhwr %0, $3\n"
  145. ".set pop\n"
  146. : "=&r" (res)
  147. : /* no input */
  148. : "memory");
  149. return res;
  150. }
  151. void __init plat_time_init(void)
  152. {
  153. struct clk *clk;
  154. ltq_soc_init();
  155. clk = clk_get_cpu();
  156. mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
  157. write_c0_compare(read_c0_count());
  158. pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
  159. clk_put(clk);
  160. }