clock.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * Moschip MCS814x clock routines
  3. *
  4. * Copyright (C) 2012, Florian Fainelli <florian@openwrt.org>
  5. *
  6. * Licensed under GPLv2
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/init.h>
  10. #include <linux/export.h>
  11. #include <linux/spinlock.h>
  12. #include <linux/err.h>
  13. #include <linux/io.h>
  14. #include <linux/clkdev.h>
  15. #include <linux/clk.h>
  16. #include <mach/mcs814x.h>
  17. #include "common.h"
  18. #define KHZ 1000
  19. #define MHZ (KHZ * KHZ)
  20. struct clk_ops {
  21. unsigned long (*get_rate)(struct clk *clk);
  22. int (*set_rate)(struct clk *clk, unsigned long rate);
  23. struct clk *(*get_parent)(struct clk *clk);
  24. int (*enable)(struct clk *clk, int enable);
  25. };
  26. struct clk {
  27. struct clk *parent; /* parent clk */
  28. unsigned long rate; /* clock rate in Hz */
  29. unsigned long divider; /* clock divider */
  30. u32 usecount; /* reference count */
  31. struct clk_ops *ops; /* clock operation */
  32. u32 enable_reg; /* clock enable register */
  33. u32 enable_mask; /* clock enable mask */
  34. };
  35. static unsigned long clk_divide_parent(struct clk *clk)
  36. {
  37. if (clk->parent && clk->divider)
  38. return clk_get_rate(clk->parent) / clk->divider;
  39. else
  40. return 0;
  41. }
  42. static int clk_local_onoff_enable(struct clk *clk, int enable)
  43. {
  44. u32 tmp;
  45. /* no enable_reg means the clock is always enabled */
  46. if (!clk->enable_reg)
  47. return 0;
  48. tmp = readl_relaxed(mcs814x_sysdbg_base + clk->enable_reg);
  49. if (!enable)
  50. tmp &= ~clk->enable_mask;
  51. else
  52. tmp |= clk->enable_mask;
  53. writel_relaxed(tmp, mcs814x_sysdbg_base + clk->enable_reg);
  54. return 0;
  55. }
  56. static struct clk_ops default_clk_ops = {
  57. .get_rate = clk_divide_parent,
  58. .enable = clk_local_onoff_enable,
  59. };
  60. static DEFINE_SPINLOCK(clocks_lock);
  61. static const unsigned long cpu_freq_table[] = {
  62. 175000,
  63. 300000,
  64. 125000,
  65. 137500,
  66. 212500,
  67. 250000,
  68. 162500,
  69. 187500,
  70. 162500,
  71. 150000,
  72. 225000,
  73. 237500,
  74. 200000,
  75. 262500,
  76. 275000,
  77. 287500
  78. };
  79. static struct clk clk_cpu;
  80. /* System clock is fixed at 50Mhz */
  81. static struct clk clk_sys = {
  82. .rate = 50 * MHZ,
  83. };
  84. static struct clk clk_sdram;
  85. static struct clk clk_timer0 = {
  86. .parent = &clk_sdram,
  87. .divider = 2,
  88. .ops = &default_clk_ops,
  89. };
  90. static struct clk clk_timer1_2 = {
  91. .parent = &clk_sys,
  92. };
  93. /* Watchdog clock is system clock / 128 */
  94. static struct clk clk_wdt = {
  95. .parent = &clk_sys,
  96. .divider = 128,
  97. .ops = &default_clk_ops,
  98. };
  99. static struct clk clk_emac = {
  100. .ops = &default_clk_ops,
  101. .enable_reg = SYSDBG_SYSCTL,
  102. .enable_mask = SYSCTL_EMAC,
  103. };
  104. static struct clk clk_ephy = {
  105. .ops = &default_clk_ops,
  106. .enable_reg = SYSDBG_PLL_CTL,
  107. .enable_mask = ~SYSCTL_EPHY, /* active low */
  108. };
  109. static struct clk clk_cipher = {
  110. .ops = &default_clk_ops,
  111. .enable_reg = SYSDBG_SYSCTL,
  112. .enable_mask = SYSCTL_CIPHER,
  113. };
  114. #define CLK(_dev, _con, _clk) \
  115. { .dev_id = (_dev), .con_id = (_con), .clk = (_clk) },
  116. static struct clk_lookup mcs814x_chip_clks[] = {
  117. CLK("cpu", NULL, &clk_cpu)
  118. CLK("sys", NULL, &clk_sys)
  119. CLK("sdram", NULL, &clk_sdram)
  120. /* 32-bits timer0 */
  121. CLK("timer0", NULL, &clk_timer0)
  122. /* 16-bits timer1 */
  123. CLK("timer1", NULL, &clk_timer1_2)
  124. /* 64-bits timer2, same as timer 1 */
  125. CLK("timer2", NULL, &clk_timer1_2)
  126. CLK(NULL, "wdt", &clk_wdt)
  127. CLK(NULL, "emac", &clk_emac)
  128. CLK(NULL, "ephy", &clk_ephy)
  129. CLK(NULL, "cipher", &clk_cipher)
  130. };
  131. static void local_clk_disable(struct clk *clk)
  132. {
  133. WARN_ON(!clk->usecount);
  134. if (clk->usecount > 0) {
  135. clk->usecount--;
  136. if ((clk->usecount == 0) && (clk->ops->enable))
  137. clk->ops->enable(clk, 0);
  138. if (clk->parent)
  139. local_clk_disable(clk->parent);
  140. }
  141. }
  142. static int local_clk_enable(struct clk *clk)
  143. {
  144. int ret = 0;
  145. if (clk->parent)
  146. ret = local_clk_enable(clk->parent);
  147. if (ret)
  148. return ret;
  149. if ((clk->usecount == 0) && (clk->ops->enable))
  150. ret = clk->ops->enable(clk, 1);
  151. if (!ret)
  152. clk->usecount++;
  153. else if (clk->parent && clk->parent->ops->enable)
  154. local_clk_disable(clk->parent);
  155. return ret;
  156. }
  157. int clk_enable(struct clk *clk)
  158. {
  159. int ret;
  160. unsigned long flags;
  161. spin_lock_irqsave(&clocks_lock, flags);
  162. ret = local_clk_enable(clk);
  163. spin_unlock_irqrestore(&clocks_lock, flags);
  164. return ret;
  165. }
  166. EXPORT_SYMBOL(clk_enable);
  167. void clk_disable(struct clk *clk)
  168. {
  169. unsigned long flags;
  170. spin_lock_irqsave(&clocks_lock, flags);
  171. local_clk_disable(clk);
  172. spin_unlock_irqrestore(&clocks_lock, flags);
  173. }
  174. EXPORT_SYMBOL(clk_disable);
  175. unsigned long clk_get_rate(struct clk *clk)
  176. {
  177. if (unlikely(IS_ERR_OR_NULL(clk)))
  178. return 0;
  179. if (clk->rate)
  180. return clk->rate;
  181. if (clk->ops && clk->ops->get_rate)
  182. return clk->ops->get_rate(clk);
  183. return clk_get_rate(clk->parent);
  184. }
  185. EXPORT_SYMBOL(clk_get_rate);
  186. struct clk *clk_get_parent(struct clk *clk)
  187. {
  188. unsigned long flags;
  189. if (unlikely(IS_ERR_OR_NULL(clk)))
  190. return NULL;
  191. if (!clk->ops || !clk->ops->get_parent)
  192. return clk->parent;
  193. spin_lock_irqsave(&clocks_lock, flags);
  194. clk->parent = clk->ops->get_parent(clk);
  195. spin_unlock_irqrestore(&clocks_lock, flags);
  196. return clk->parent;
  197. }
  198. EXPORT_SYMBOL(clk_get_parent);
  199. void __init mcs814x_clk_init(void)
  200. {
  201. u32 bs1;
  202. u8 cpu_freq;
  203. clkdev_add_table(mcs814x_chip_clks, ARRAY_SIZE(mcs814x_chip_clks));
  204. /* read the bootstrap registers to know the exact clocking scheme */
  205. bs1 = readl_relaxed(mcs814x_sysdbg_base + SYSDBG_BS1);
  206. cpu_freq = (bs1 >> CPU_FREQ_SHIFT) & CPU_FREQ_MASK;
  207. pr_info("CPU frequency: %lu (kHz)\n", cpu_freq_table[cpu_freq]);
  208. clk_cpu.rate = cpu_freq * KHZ;
  209. /* read SDRAM frequency */
  210. if (bs1 & SDRAM_FREQ_BIT)
  211. clk_sdram.rate = 100 * MHZ;
  212. else
  213. clk_sdram.rate = 133 * MHZ;
  214. pr_info("SDRAM frequency: %lu (MHz)\n", clk_sdram.rate / MHZ);
  215. }