clk.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. static inline u32 get_counter_resolution(void)
  135. {
  136. u32 res;
  137. __asm__ __volatile__(
  138. ".set push\n"
  139. ".set mips32r2\n"
  140. "rdhwr %0, $3\n"
  141. ".set pop\n"
  142. : "=&r" (res)
  143. : /* no input */
  144. : "memory");
  145. return res;
  146. }
  147. void __init plat_time_init(void)
  148. {
  149. struct clk *clk;
  150. ltq_soc_init();
  151. clk = clk_get_cpu();
  152. mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
  153. write_c0_compare(read_c0_count());
  154. pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
  155. clk_put(clk);
  156. }