orion.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Marvell Orion SoC clocks
  4. *
  5. * Copyright (C) 2014 Thomas Petazzoni
  6. *
  7. * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  8. *
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/clk-provider.h>
  12. #include <linux/io.h>
  13. #include <linux/of.h>
  14. #include "common.h"
  15. static const struct coreclk_ratio orion_coreclk_ratios[] __initconst = {
  16. { .id = 0, .name = "ddrclk", }
  17. };
  18. /*
  19. * Orion 5181
  20. */
  21. #define SAR_MV88F5181_TCLK_FREQ 8
  22. #define SAR_MV88F5181_TCLK_FREQ_MASK 0x3
  23. static u32 __init mv88f5181_get_tclk_freq(void __iomem *sar)
  24. {
  25. u32 opt = (readl(sar) >> SAR_MV88F5181_TCLK_FREQ) &
  26. SAR_MV88F5181_TCLK_FREQ_MASK;
  27. if (opt == 0)
  28. return 133333333;
  29. else if (opt == 1)
  30. return 150000000;
  31. else if (opt == 2)
  32. return 166666667;
  33. else
  34. return 0;
  35. }
  36. #define SAR_MV88F5181_CPU_FREQ 4
  37. #define SAR_MV88F5181_CPU_FREQ_MASK 0xf
  38. static u32 __init mv88f5181_get_cpu_freq(void __iomem *sar)
  39. {
  40. u32 opt = (readl(sar) >> SAR_MV88F5181_CPU_FREQ) &
  41. SAR_MV88F5181_CPU_FREQ_MASK;
  42. if (opt == 0)
  43. return 333333333;
  44. else if (opt == 1 || opt == 2)
  45. return 400000000;
  46. else if (opt == 3)
  47. return 500000000;
  48. else
  49. return 0;
  50. }
  51. static void __init mv88f5181_get_clk_ratio(void __iomem *sar, int id,
  52. int *mult, int *div)
  53. {
  54. u32 opt = (readl(sar) >> SAR_MV88F5181_CPU_FREQ) &
  55. SAR_MV88F5181_CPU_FREQ_MASK;
  56. if (opt == 0 || opt == 1) {
  57. *mult = 1;
  58. *div = 2;
  59. } else if (opt == 2 || opt == 3) {
  60. *mult = 1;
  61. *div = 3;
  62. } else {
  63. *mult = 0;
  64. *div = 1;
  65. }
  66. }
  67. static const struct coreclk_soc_desc mv88f5181_coreclks = {
  68. .get_tclk_freq = mv88f5181_get_tclk_freq,
  69. .get_cpu_freq = mv88f5181_get_cpu_freq,
  70. .get_clk_ratio = mv88f5181_get_clk_ratio,
  71. .ratios = orion_coreclk_ratios,
  72. .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
  73. };
  74. static void __init mv88f5181_clk_init(struct device_node *np)
  75. {
  76. return mvebu_coreclk_setup(np, &mv88f5181_coreclks);
  77. }
  78. CLK_OF_DECLARE(mv88f5181_clk, "marvell,mv88f5181-core-clock", mv88f5181_clk_init);
  79. /*
  80. * Orion 5182
  81. */
  82. #define SAR_MV88F5182_TCLK_FREQ 8
  83. #define SAR_MV88F5182_TCLK_FREQ_MASK 0x3
  84. static u32 __init mv88f5182_get_tclk_freq(void __iomem *sar)
  85. {
  86. u32 opt = (readl(sar) >> SAR_MV88F5182_TCLK_FREQ) &
  87. SAR_MV88F5182_TCLK_FREQ_MASK;
  88. if (opt == 1)
  89. return 150000000;
  90. else if (opt == 2)
  91. return 166666667;
  92. else
  93. return 0;
  94. }
  95. #define SAR_MV88F5182_CPU_FREQ 4
  96. #define SAR_MV88F5182_CPU_FREQ_MASK 0xf
  97. static u32 __init mv88f5182_get_cpu_freq(void __iomem *sar)
  98. {
  99. u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) &
  100. SAR_MV88F5182_CPU_FREQ_MASK;
  101. if (opt == 0)
  102. return 333333333;
  103. else if (opt == 1 || opt == 2)
  104. return 400000000;
  105. else if (opt == 3)
  106. return 500000000;
  107. else
  108. return 0;
  109. }
  110. static void __init mv88f5182_get_clk_ratio(void __iomem *sar, int id,
  111. int *mult, int *div)
  112. {
  113. u32 opt = (readl(sar) >> SAR_MV88F5182_CPU_FREQ) &
  114. SAR_MV88F5182_CPU_FREQ_MASK;
  115. if (opt == 0 || opt == 1) {
  116. *mult = 1;
  117. *div = 2;
  118. } else if (opt == 2 || opt == 3) {
  119. *mult = 1;
  120. *div = 3;
  121. } else {
  122. *mult = 0;
  123. *div = 1;
  124. }
  125. }
  126. static const struct coreclk_soc_desc mv88f5182_coreclks = {
  127. .get_tclk_freq = mv88f5182_get_tclk_freq,
  128. .get_cpu_freq = mv88f5182_get_cpu_freq,
  129. .get_clk_ratio = mv88f5182_get_clk_ratio,
  130. .ratios = orion_coreclk_ratios,
  131. .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
  132. };
  133. static void __init mv88f5182_clk_init(struct device_node *np)
  134. {
  135. return mvebu_coreclk_setup(np, &mv88f5182_coreclks);
  136. }
  137. CLK_OF_DECLARE(mv88f5182_clk, "marvell,mv88f5182-core-clock", mv88f5182_clk_init);
  138. /*
  139. * Orion 5281
  140. */
  141. static u32 __init mv88f5281_get_tclk_freq(void __iomem *sar)
  142. {
  143. /* On 5281, tclk is always 166 Mhz */
  144. return 166666667;
  145. }
  146. #define SAR_MV88F5281_CPU_FREQ 4
  147. #define SAR_MV88F5281_CPU_FREQ_MASK 0xf
  148. static u32 __init mv88f5281_get_cpu_freq(void __iomem *sar)
  149. {
  150. u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) &
  151. SAR_MV88F5281_CPU_FREQ_MASK;
  152. if (opt == 1 || opt == 2)
  153. return 400000000;
  154. else if (opt == 3)
  155. return 500000000;
  156. else
  157. return 0;
  158. }
  159. static void __init mv88f5281_get_clk_ratio(void __iomem *sar, int id,
  160. int *mult, int *div)
  161. {
  162. u32 opt = (readl(sar) >> SAR_MV88F5281_CPU_FREQ) &
  163. SAR_MV88F5281_CPU_FREQ_MASK;
  164. if (opt == 1) {
  165. *mult = 1;
  166. *div = 2;
  167. } else if (opt == 2 || opt == 3) {
  168. *mult = 1;
  169. *div = 3;
  170. } else {
  171. *mult = 0;
  172. *div = 1;
  173. }
  174. }
  175. static const struct coreclk_soc_desc mv88f5281_coreclks = {
  176. .get_tclk_freq = mv88f5281_get_tclk_freq,
  177. .get_cpu_freq = mv88f5281_get_cpu_freq,
  178. .get_clk_ratio = mv88f5281_get_clk_ratio,
  179. .ratios = orion_coreclk_ratios,
  180. .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
  181. };
  182. static void __init mv88f5281_clk_init(struct device_node *np)
  183. {
  184. return mvebu_coreclk_setup(np, &mv88f5281_coreclks);
  185. }
  186. CLK_OF_DECLARE(mv88f5281_clk, "marvell,mv88f5281-core-clock", mv88f5281_clk_init);
  187. /*
  188. * Orion 6183
  189. */
  190. #define SAR_MV88F6183_TCLK_FREQ 9
  191. #define SAR_MV88F6183_TCLK_FREQ_MASK 0x1
  192. static u32 __init mv88f6183_get_tclk_freq(void __iomem *sar)
  193. {
  194. u32 opt = (readl(sar) >> SAR_MV88F6183_TCLK_FREQ) &
  195. SAR_MV88F6183_TCLK_FREQ_MASK;
  196. if (opt == 0)
  197. return 133333333;
  198. else if (opt == 1)
  199. return 166666667;
  200. else
  201. return 0;
  202. }
  203. #define SAR_MV88F6183_CPU_FREQ 1
  204. #define SAR_MV88F6183_CPU_FREQ_MASK 0x3f
  205. static u32 __init mv88f6183_get_cpu_freq(void __iomem *sar)
  206. {
  207. u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) &
  208. SAR_MV88F6183_CPU_FREQ_MASK;
  209. if (opt == 9)
  210. return 333333333;
  211. else if (opt == 17)
  212. return 400000000;
  213. else
  214. return 0;
  215. }
  216. static void __init mv88f6183_get_clk_ratio(void __iomem *sar, int id,
  217. int *mult, int *div)
  218. {
  219. u32 opt = (readl(sar) >> SAR_MV88F6183_CPU_FREQ) &
  220. SAR_MV88F6183_CPU_FREQ_MASK;
  221. if (opt == 9 || opt == 17) {
  222. *mult = 1;
  223. *div = 2;
  224. } else {
  225. *mult = 0;
  226. *div = 1;
  227. }
  228. }
  229. static const struct coreclk_soc_desc mv88f6183_coreclks = {
  230. .get_tclk_freq = mv88f6183_get_tclk_freq,
  231. .get_cpu_freq = mv88f6183_get_cpu_freq,
  232. .get_clk_ratio = mv88f6183_get_clk_ratio,
  233. .ratios = orion_coreclk_ratios,
  234. .num_ratios = ARRAY_SIZE(orion_coreclk_ratios),
  235. };
  236. static void __init mv88f6183_clk_init(struct device_node *np)
  237. {
  238. return mvebu_coreclk_setup(np, &mv88f6183_coreclks);
  239. }
  240. CLK_OF_DECLARE(mv88f6183_clk, "marvell,mv88f6183-core-clock", mv88f6183_clk_init);