clock.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/arch/arm/mach-sa1100/clock.c
  4. */
  5. #include <linux/module.h>
  6. #include <linux/kernel.h>
  7. #include <linux/device.h>
  8. #include <linux/list.h>
  9. #include <linux/errno.h>
  10. #include <linux/err.h>
  11. #include <linux/string.h>
  12. #include <linux/clk.h>
  13. #include <linux/spinlock.h>
  14. #include <linux/mutex.h>
  15. #include <linux/io.h>
  16. #include <linux/clkdev.h>
  17. #include <mach/hardware.h>
  18. #include <mach/generic.h>
  19. struct clkops {
  20. void (*enable)(struct clk *);
  21. void (*disable)(struct clk *);
  22. unsigned long (*get_rate)(struct clk *);
  23. };
  24. struct clk {
  25. const struct clkops *ops;
  26. unsigned int enabled;
  27. };
  28. #define DEFINE_CLK(_name, _ops) \
  29. struct clk clk_##_name = { \
  30. .ops = _ops, \
  31. }
  32. static DEFINE_SPINLOCK(clocks_lock);
  33. /* Dummy clk routine to build generic kernel parts that may be using them */
  34. long clk_round_rate(struct clk *clk, unsigned long rate)
  35. {
  36. return clk_get_rate(clk);
  37. }
  38. EXPORT_SYMBOL(clk_round_rate);
  39. int clk_set_rate(struct clk *clk, unsigned long rate)
  40. {
  41. return 0;
  42. }
  43. EXPORT_SYMBOL(clk_set_rate);
  44. int clk_set_parent(struct clk *clk, struct clk *parent)
  45. {
  46. return 0;
  47. }
  48. EXPORT_SYMBOL(clk_set_parent);
  49. struct clk *clk_get_parent(struct clk *clk)
  50. {
  51. return NULL;
  52. }
  53. EXPORT_SYMBOL(clk_get_parent);
  54. static void clk_gpio27_enable(struct clk *clk)
  55. {
  56. /*
  57. * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
  58. * (SA-1110 Developer's Manual, section 9.1.2.1)
  59. */
  60. GAFR |= GPIO_32_768kHz;
  61. GPDR |= GPIO_32_768kHz;
  62. TUCR = TUCR_3_6864MHz;
  63. }
  64. static void clk_gpio27_disable(struct clk *clk)
  65. {
  66. TUCR = 0;
  67. GPDR &= ~GPIO_32_768kHz;
  68. GAFR &= ~GPIO_32_768kHz;
  69. }
  70. static void clk_cpu_enable(struct clk *clk)
  71. {
  72. }
  73. static void clk_cpu_disable(struct clk *clk)
  74. {
  75. }
  76. static unsigned long clk_cpu_get_rate(struct clk *clk)
  77. {
  78. return sa11x0_getspeed(0) * 1000;
  79. }
  80. int clk_enable(struct clk *clk)
  81. {
  82. unsigned long flags;
  83. if (clk) {
  84. spin_lock_irqsave(&clocks_lock, flags);
  85. if (clk->enabled++ == 0)
  86. clk->ops->enable(clk);
  87. spin_unlock_irqrestore(&clocks_lock, flags);
  88. }
  89. return 0;
  90. }
  91. EXPORT_SYMBOL(clk_enable);
  92. void clk_disable(struct clk *clk)
  93. {
  94. unsigned long flags;
  95. if (clk) {
  96. WARN_ON(clk->enabled == 0);
  97. spin_lock_irqsave(&clocks_lock, flags);
  98. if (--clk->enabled == 0)
  99. clk->ops->disable(clk);
  100. spin_unlock_irqrestore(&clocks_lock, flags);
  101. }
  102. }
  103. EXPORT_SYMBOL(clk_disable);
  104. unsigned long clk_get_rate(struct clk *clk)
  105. {
  106. if (clk && clk->ops && clk->ops->get_rate)
  107. return clk->ops->get_rate(clk);
  108. return 0;
  109. }
  110. EXPORT_SYMBOL(clk_get_rate);
  111. const struct clkops clk_gpio27_ops = {
  112. .enable = clk_gpio27_enable,
  113. .disable = clk_gpio27_disable,
  114. };
  115. const struct clkops clk_cpu_ops = {
  116. .enable = clk_cpu_enable,
  117. .disable = clk_cpu_disable,
  118. .get_rate = clk_cpu_get_rate,
  119. };
  120. static DEFINE_CLK(gpio27, &clk_gpio27_ops);
  121. static DEFINE_CLK(cpu, &clk_cpu_ops);
  122. static unsigned long clk_36864_get_rate(struct clk *clk)
  123. {
  124. return 3686400;
  125. }
  126. static struct clkops clk_36864_ops = {
  127. .enable = clk_cpu_enable,
  128. .disable = clk_cpu_disable,
  129. .get_rate = clk_36864_get_rate,
  130. };
  131. static DEFINE_CLK(36864, &clk_36864_ops);
  132. static struct clk_lookup sa11xx_clkregs[] = {
  133. CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
  134. CLKDEV_INIT("sa1100-rtc", NULL, NULL),
  135. CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
  136. CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
  137. CLKDEV_INIT("sa11x0-pcmcia.0", NULL, &clk_cpu),
  138. CLKDEV_INIT("sa11x0-pcmcia.1", NULL, &clk_cpu),
  139. /* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
  140. CLKDEV_INIT("1800", NULL, &clk_cpu),
  141. CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
  142. };
  143. int __init sa11xx_clk_init(void)
  144. {
  145. clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
  146. return 0;
  147. }